close

This ticket was migrated to our GitLab and can now be found here: #7485

Opened 9 years ago

Last modified 5 months ago

#7485 reopened enhancement

Display chapters stored in MP3 files (id3-tags)

Reported by: fsp Owned by: Francois Cartegnie
Priority: normal Milestone: 4.0.0
Component: Demuxers Version: 2.0.3
Severity: normal Keywords: chapter mp3 id3 tags
Cc: Difficulty: easy
Platform(s): all Work status: Not started

Description

Windows 7 x64 VLC 2.0.3

MP3 is capable of saving chapter information in ID3-Tags.

Here is an example file: http://meta.metaebene.me/media/cre/cre197-ipv6.mp3

00:00:00   Einführung
00:05:28   Persönlicher Hintergrund
00:12:11   IP History
00:18:55   Adressklassifizierung
00:25:02   Routing im Internet
01:05:09   Das schwer benutzbare Netz
01:08:39   Adressvergabe und Name Resolution
01:15:19   Änderung der Paketstruktur in IPv6
01:23:59   Fragmentierung und MTU Discovery
01:30:56   Lokale Adressvergabe unter IPv6
01:44:47   Paketversandarten und Scope
01:52:48   Globale Adressvergabe unter IPv6
02:05:22   Hierarchische Adress-Struktuierung und Präfixe
02:14:07   IPv6 Privacy Extensions
02:26:13   Mehrere Router gleichzeitig nutzen
02:36:16   IPv4 und IPv6 im Parallelbetrieb
02:39:30   Multicast, Broadcast und die Neighbor Discovery im Ethernet
02:52:10   IPv6 Provider
02:56:38   IPv6 Tunnel & Transition Strategies
03:23:11   Leben ohne IPv4
03:30:52   IPv6-Unterstützung von Anwendungen
03:37:29   DHCPv6
03:40:27   Ankommen in der IPv6 Welt
03:42:34   Vorteile von IPv6 für den Anwender
03:48:01   Epilog

Those are the chapters stored, not sure if the timestamps are ok, they were taken from the site. http://cre.fm/cre197

Some additional info:

http://www.id3.org/id3v2-chapters-1.0 http://id3v2-chap-tool.sourceforge.net/ (http://sourceforge.net/projects/id3v2-chap-tool/)

In this specific file the chapter starts at offset 0x00000150, maybe a little bit earlier, but here you can see the strings stored.

It would be awesome to display these chapters within VLC, as it is possible with a huge number of other formats.

Attachments (1)

0001-tablib-chapters-stash.patch (7.7 KB) - added by Francois Cartegnie 8 years ago.
Stash to restart from when taglib will be fixed

Download all attachments as: .zip

Change History (25)

comment:1 Changed 9 years ago by Jean-Baptiste Kempf

Milestone: 2.0.5Features paradize

comment:2 Changed 9 years ago by Jean-Baptiste Kempf

Difficulty: unknowneasy

comment:3 Changed 8 years ago by dckface

Hello, I would like to contribute to VLC development and this enhancement seems to be interesting.

Can I help with this enhancement as a part of my seminar project?

comment:4 Changed 8 years ago by TypX

Owner: changed from fenrir to dckface

comment:5 Changed 8 years ago by Jean-Baptiste Kempf

Owner: changed from dckface to Francois Cartegnie

Changed 8 years ago by Francois Cartegnie

Stash to restart from when taglib will be fixed

comment:7 Changed 7 years ago by auphonic

ffmpeg can now also read chapters out of MP3 files. Would it be possible to use ffmpeg for that?

Example with a smaller file: https://auphonic.com/media/blog/auphonic_chapters_demo.mp3

ffmpeg command:

ffprobe -show_chapters auphonic_chapters_demo.mp3

comment:8 Changed 7 years ago by auphonic

BTW: it seems that now also taglibe implemented chapter support for CHAP and CTOC id3 tags: https://github.com/taglib/taglib/pull/173

comment:9 Changed 7 years ago by Francois Cartegnie

still not in 1.9.1

comment:10 Changed 5 years ago by IAPark

I'd love to take a crack at this if people would be interested. TagLib? indeed now supports reading chapter information and I've implemented something to write chapter information for my own use. But I've been fiddling with the VLC's source and I'm not quite sure of the best way of making this happen.

Right now taglib is only being used inside taglib.cpp. I could implement some sort of chapter parsing there, but I'm not sure how to get the information from there to the demux module where it actually will get used. I could also just directly use TagLib? inside of the of the mpeg demux module, but then a whole lot of compatibility code which seems to exist in the taglib.cpp file to handle various build environments would have to be recoded and as I don't really understand why half of it is there.

The other problem with using TagLib? for this in general is that it only seems to work when a file path is available which it isn't when streaming.

I think for now I'm going to work on getting a simple proof of concept working, but I was curious if anyone had any suggestions for a better way of doing this.

comment:11 Changed 5 years ago by Jean-Baptiste Kempf

Unfortunately, you cannot do that in the taglib module. You must do it in the mpeg demuxer module.

comment:12 Changed 5 years ago by Jean-Baptiste Kempf

modules/demux/mpeg/es.c

comment:13 Changed 5 years ago by IAPark

Thanks I appreciate it. I've played around a bit and managed to get very non-robust parsing working properly for some test files I created, but something odd's going on with the example file given here. I'm going to keep experimenting/reading the spec and hopefully I can figure out what I'm doing wrong. It hits an APIC frame which is apparently used to store cover art and the like being bigger than any other frame I've encountered it doesn't get skipped over properly leaving the rest of the parsing offset from frame headers.

If I end up disappearing here's a link to the Github repo where I'm working on this so people can get some pointers towards what needs done. https://github.com/IAPark/vlc

comment:14 Changed 5 years ago by Jean-Baptiste Kempf

Don't disappear!

comment:15 Changed 5 years ago by IAPark

Don't plan on it, but I don't know, things come up and there's not guarantee that I'll finish this.

For people's information the problem seems to be that some things encode id3v2 frame header with the size specified as a normal big-endian 4 byte number. Others (aka taglib) encode it according to the spec for the size of the id3v2 header which calls for the size to be encoded as 4 bytes where the first bit of every byte is always 0 leaving 4 7 bit bytes to encode the size of each frame. The spec doesn't make it very clear at least at a quick reading but from doing some digging it appears that the TagLib? has the right implementation. The example given above, however, doesn't. I think it's a pretty common problem though, because ffmpeg at a minimum appears to somehow try to stay compatible with either encoding so it's definitely something I need to handle.

The good ish news is that if I manually change my code for that particular example it mostly reads the chapters ok, though I don't properly deal with the Unicode text at the moment somehow.

comment:16 Changed 5 years ago by IAPark

I've made progress, not quite sure if this is progress that people will actually want to use, but it is progress so I'll describe it.

The biggest problem I've had is understanding VLC's build system. Probably I just need to take a deep dive into autoconf, but I haven't at least not yet. The biggest problem there is that it seems to be impossible to mix any C++ code into the demux module. I'm assuming there is a way to do this, but it would invite it's own set of problems as some sort of hacky way off getting a VLC stream to work with Taglib would be required. Instead I wrote some basic functionality to handle parsing id3v2 tags directly. They aren't that complicated of a format. The biggest problem I had was differentiating between id3v2.3 and id3v2.4 where the format for the header is slightly different. I'm still not properly decoding tags that use unsynchronization. I have code that should handle this, but I can't seem to generate tags that get unsynchronized with any of the tools I've found. The specification does specify that it isn't necessary if the tag is only targeting players that were designed with i3v2 tags in mind so maybe all modern tools just assume that.

My question is if this is a reasonable way of achieving the goals of this ticket. It's a lot of code for what is a relatively minor feature request though it could be extended to allow for most of the information in i3v2 tags to be parsed even when the mp3 file is being streamed which is something that's impossible using the current TagLib? based implementation.

I have two branches (besides master) in my GitHub? repository currently.

First my parsing where any tags marked with unsynchronization can't be parsed. This is actually the second version of this. In this version there is a fairly generally purpose function used with function pointers allowing for different parses to be slotted in to handle and extract information from different types of frames.

My second extends this to hopefully strip unsynchronization where that is used. I can't properly test this as already mentioned but it should give an idea of what's required.

Secondary question. Any idea what the .gitignore doesn't include a lot of things that shouldn't be committed?

comment:17 Changed 4 years ago by Francois Cartegnie

I already reimplemented demuxers ID3 parsing

comment:18 Changed 4 years ago by Jean-Baptiste Kempf

So now, we just need chapter parsing?

comment:19 Changed 4 years ago by IAPark

OK. Well after 7 months I finally took a look at this again. It isn't perfect, but I have something that at least somewhat works. It does bring up some questions though.

First and maybe most important is that id3 chapters are actually more complicated than vlc can support. It involves potentially a hierarchy of chapters where VLC only allows for a flat structure.

To make the hierarchy work there is an additional tag that I am currently ignoring. it defines what order the chapters should go in and what the structure of the hierarchy should look like.

For an actual usable version I see two options. We either either look at just the first layer of the hierarchy and ignore any sub layers. Or we just take all the chapters and order them exactly as they appear chronographically.

To do to make this actually work then is

  • Either order chronographically or by index, but don't order by position in file as it currently does
  • Supporting subtitles
  • Testing, lots of testing
  • Ensure meeting code conventions

Also actually submitting the change. I'm not quite clear on what I need to do for that.

My changes for reference are at https://github.com/videolan/vlc/compare/master...IAPark:master now

comment:20 Changed 4 years ago by auphonic

I would just ignore the hierarchy (both of your suggestions should work), I have never seen any file which uses that. IMHO this is a very unfortunate design, as the complexity of it just discourages developers to integrate MP3 chapters ...

comment:21 Changed 4 years ago by Jean-Baptiste Kempf

Technically, VLC supports 2 level or hierarchy: title and chapters. But for an MP3, I would juste use chapters (and not title) and take the first level and ignore the rest.

comment:22 Changed 2 years ago by Jean-Baptiste Kempf

Milestone: Features paradize4.0.0
Resolution: fixed
Status: newclosed

comment:23 Changed 19 months ago by andekande

Tried it with another sample where no chapters are listed in latest VLC 4.0.0-dev on Windows 10 x64.

https://auphonic.com/media/blog/auphonic_chapters_demo.mp3

from https://auphonic.com/blog/2013/07/03/chapter-marks-and-enhanced-podcasts/

As auphonic itself commented 2 years ago maybe they can elaborate as well.

comment:24 Changed 5 months ago by Gary Wang

Resolution: fixed
Status: closedreopened

Tried with auphonic_chapters_demo.mp3 mentioned by @andekande at #comment:23, and also tried with cre197-ipv6.mp3 in the bug description, both of them will not show a chapter list from the most recent stable version of VLC (3.0.11 jenkins@ee165b7cae4d Jun 4 2020 15:48:20 vlc-3.0.11-win64.exe) for Windows x64.

Also tried with a nightly version(4.0.0-dev videolan@runner-yykwduqh-project-435-concurrent-1 Dec 10 2020 04:08:15, vlc-4.0.0-dev-win64-2dacb394.msi), the cre197-ipv6.mp3 works from the Chapter menu, but auphonic_chapters_demo.mp3 still doesn't work.

I'm not sure if I should submit another bug or reopen this one. I reopened this bug, please let me know if I should create another bug report.

Note: See TracTickets for help on using tickets.