Labels to id3v2 mp3 chapters spec

When I export to MP3, I would like labels to generate id3v2 chapters. Podcast listening applications like Overcast use these for listeners to skip to topics within a podcast they wish to listen to.

http://id3.org/id3v2-chapters-1.0 is the link to the spec.

There are apps which allow the import of a cue sheet and convert them to id3v2 mp3 chapters, such as https://chaptersapp.com/index.html - but it would be much more useful to be able to create the labels in Audacity while editing and have the chapters created as a part of the export to MP3.

Are there any players that support ID3v2 chapters?

Yes, there are.

MP3 chapter markers are supported by most podcast clients, including Apple Podcasts on iOS (provided you’re on iOS 12)

Under iOS and OS X, chapter marks in MP4 files (with URLs and images) are generally well supported by most podcast players, for example in Apple’s Podcast app. MP3 chapters can be displayed with Instacast, Overcast, Castro, Downcast, Podcat, Pocket Casts and iCatcher!.

On Android you can use Podcast Addict, which supports chapters in all file formats (MP3, M4A/MP4, Opus, Ogg, etc.), uPod to display chapter marks with URLs and images in MP3 and MP4 files, the open source AntennaPod supports chapter titles with URLs in MP3, Opus and Ogg Vorbis files and Pocket Casts supports MP3 chapters.

I don’t have a smartphone. Any PC apps support ID3v2 chapters?

Chapter image and title in Ubuntu’s media player

QuickTime player supports previous and next chapter based on these markers. It used to give a list of the chapters with their names, but Apple removed that interface at some point.

Chapter overview in iTunes

VLC is reported to, although I haven’t tried.

https://github.com/podlove/podlove-publisher has a web interface which also supports id3v2 mp3 chapters.

It also works in https://www.podigee.com/en/podcast-player/ Podigee’s web player (there’s a chapter marker button that reveals them in their interface, the button to the left of the cloud icon)

I downloaded the MP3 from there, but I don’t see any chapters in the downloaded version. I’ve checked with MediaInfo and VLC. Do you see chapters in the downloaded MP3?

While it’s encouraging to see that some apps are taking up id3v2 chapter tags, it still seems a long way from being “mainstream”, especially on Windows (our main user base by a long way). If we did add support for writing chapters, we run the risk of being flooded by users complaining that it doesn’t work (on their media player).

I can certainly log your “vote” for adding this feature, but I also have concerns about how useful/frustrating it will be to the majority of our users.

Is a screen grab of mp3 chapters in VLC on Windows, taken from the Internet. I’m still working out how to view them in VLC on Mac OS.

I’m led to believe that VLC, Windows Media Player (supports chapter images) and also Ubuntu’s default video player (supports chapter images and titles) all should work. I’m trying to confirm that.

But I wonder: the Windows user base of Audacity creates files for -their- audience, and focusing only on what Windows support exists may be in error. What are their users using, and who are they producing for? It’s probably more diverse, consisting of mobile (iOS, Android) if they’re producing podcasts.

It’s been a part of the spec since 2005. Enough clients support it, especially on mobile, that I’m getting asked regularly by the listeners of the podcast that I produce to adopt chapters. They allow listeners to find specific parts in a media file they are interested in and make my podcasts more likely to be discovered by new listeners. Some tell me that they don’t want to listen to podcasts that don’t adopt chapters, having experienced them.

I can’t speak to the podigree file, but I produced this one last night which does work in Overcast, and should work in other players that implement the spec. http://www.podtrac.com/pts/redirect.mp3/feeds.soundcloud.com/stream/618421383-appleinsider-com-blondie-steve-jobs-jimmy-iovine-jimmy-destri.mp3 - I edited the file in Audacity, created the labels in Audacity, exported the labels as txt, and then paid for credits to Auphonic.com to use their tool to take the txt file and add the labels as chapters to the mp3 file. (Auphonic does a lot of other things, like level gain, noise reduce, and so on - but all I needed it for in this case was embedding the labels as chapters, because Audacity doesn’t.

ffmpeg -i FILENAME should confirm the file has added chapters. I downloaded MediaInfo to see what you’re seeing - MediaInfo does not appear to display the chapters, but I have verified that I can see them using FFmpeg.

In the file linked above, the FFmpeg -i output is:


Input #0, mp3, from '/Users/vmarks/Downloads/ai pod/05092019 ai podcast.mp3':
  Metadata:
    title           : Blondie, Steve Jobs, Jimmy Iovine & Jimmy Destri
    encoded_by      : auphonic.com
    artist          : AppleInsider Podcast
    date            : 2019
  Duration: 00:32:35.71, start: 0.025056, bitrate: 112 kb/s
    Chapter #0:0: start 6.919000, end 63.220000
    Metadata:
      title           : Opener
    Chapter #0:1: start 63.220000, end 642.801000
    Metadata:
      title           : Introduction: Jimmy Destri
    Chapter #0:2: start 642.801000, end 725.750000
    Metadata:
      title           : I know music, and I know addiction
    Chapter #0:3: start 725.750000, end 839.764000
    Metadata:
      title           : Analog synths to digital and laptops
    Chapter #0:4: start 839.764000, end 896.441000
    Metadata:
      title           : Garageband
    Chapter #0:5: start 896.441000, end 963.603000
    Metadata:
      title           : Today, anybody can make a record
    Chapter #0:6: start 963.603000, end 1057.966000
    Metadata:
      title           : iTunes really covered our asses
    Chapter #0:7: start 1057.966000, end 1128.453000
    Metadata:
      title           : Spotify
    Chapter #0:8: start 1128.453000, end 1149.962000
    Metadata:
      title           : You trust Apple...
    Chapter #0:9: start 1149.962000, end 1333.264000
    Metadata:
      title           : What is Facebook's responsibility to their users
    Chapter #0:10: start 1333.264000, end 1498.773000
    Metadata:
      title           : Apple News
    Chapter #0:11: start 1498.773000, end 1700.850000
    Metadata:
      title           : Who's going to be Apple's competitor in the future?
    Chapter #0:12: start 1700.850000, end 1744.183000
    Metadata:
      title           : Steve Jobs parked anywhere he wants
    Chapter #0:13: start 1744.183000, end 1955.677000
    Metadata:
      title           : Jimmy Iovine told me some Steve Jobs stories
    Stream #0:0: Audio: mp3, 44100 Hz, stereo, fltp, 112 kb/s
    Metadata:
      encoder         : LAME3.99r
    Side data:
      replaygain: track gain - -6.100000, track peak - unknown, album gain - unknown, album peak - unknown, 
    Stream #0:1: Video: mjpeg (Baseline), yuvj420p(pc, bt470bg/unknown/unknown), 900x900 [SAR 1:1 DAR 1:1], 90k tbr, 90k tbn, 90k tbc
    Metadata:
      comment         : Cover (front)

This matches up well with my label track.txt file (Auphonic appears to round the numbers):

6.919116	6.919116	Opener
63.220385	63.220385	Introduction: Jimmy Destri
642.801768	642.801768	I know music, and I know addiction
725.750799	725.750799	Analog synths to digital and laptops
839.764525	839.764525	Garageband
896.441869	896.441869	Today, anybody can make a record
963.603922	963.603922	iTunes really covered our asses
1057.966303	1057.966303	Spotify
1128.453512	1128.453512	You trust Apple...
1149.962145	1149.962145	What is Facebook's responsibility to their users
1333.264823	1333.264823	Apple News
1498.773451	1498.773451	Who's going to be Apple's competitor in the future?
1700.850295	1700.850295	Steve Jobs drove himself
1744.183697	1744.183697	Jimmy Iovine told me some Steve Jobs stories

I wonder if something that works like https://github.com/jcs/mp3chap could be used here to make it easier to integrate it into Audacity- the output of the labels txt file piped to it as a part of exporting the file to mp3?

Thanks for logging my vote and having read this far. I’m trying to figure out how to satisfy my listener’s requests for this feature, and being able to do it all within Audacity is very desirable for me.

According to the Auphonic website where that image comes from, the image is showing Mp4 chapter marks, rather than MP3. MP3 Chapters are not supported in VLC on Windows based on my own testing using the files supplied by you, as well as the mp4 file supplied by Auphonic.

You’re correct, I made a mistake, that image of VLC is showing MP4 chapters. I apologize. This explains why I was unable to verify it with my file on Mac, but had been reassured that it was there.

MP3 chapters are going to be supported by VLC:

shows that MP3 chapters support is fixed for 4.0 of VLC as of 3 months ago, and Auphonic was one of the commenters there.

By default, Audacity uses LAME for writing MP3s, but it appears that LAME does not support id3v2 chapter frames.

Audacity is able to use FFmpeg for exporting, but I’ve not yet found any documentation to confirm that FFmpeg supports writing MP3 Chapter frames (I’ve only found documentation about reading MP3 chapters).
This page appears to imply that it doesn’t support writing chapter tags: https://wiki.multimedia.cx/index.php/FFmpeg_Metadata#MP3

This page says that FFmpeg does support writing MP3 chapter tags: https://auphonic.com/blog/2013/07/03/chapter-marks-and-enhanced-podcasts/
Has anyone been able to find FFmpeg documentation to confirm this?

http://jonhall.info/create_id3_tags_using_ffmpeg/ discusses using an external FFMETADATA file to write out the tags to an mp3.

;FFMETADATA1
title=Blondie, Steve Jobs, Jimmy Iovine & Jimmy Destri
encoded_by=auphonic.com
artist=AppleInsider Podcast
date=2019
encoder=Lavf58.27.103
[CHAPTER]
TIMEBASE=1/1000
START=6894
END=63195
title=Opener
[CHAPTER]
TIMEBASE=1/1000
START=63195
END=642776
title=Introduction: Jimmy Destri
[CHAPTER]
TIMEBASE=1/1000
START=642776
END=725725
title=I know music, and I know addiction
[CHAPTER]
TIMEBASE=1/1000
START=725725
END=839739
title=Analog synths to digital and laptops
[CHAPTER]
TIMEBASE=1/1000
START=839739
END=896416
title=Garageband
[CHAPTER]
TIMEBASE=1/1000
START=896416
END=963578
title=Today, anybody can make a record
[CHAPTER]
TIMEBASE=1/1000
START=963578
END=1057941
title=iTunes really covered our asses
[CHAPTER]
TIMEBASE=1/1000
START=1057941
END=1128428
title=Spotify
[CHAPTER]
TIMEBASE=1/1000
START=1128428
END=1149937
title=You trust Apple...
[CHAPTER]
TIMEBASE=1/1000
START=1149937
END=1333239
title=What is Facebook's responsibility to their users
[CHAPTER]
TIMEBASE=1/1000
START=1333239
END=1498748
title=Apple News
[CHAPTER]
TIMEBASE=1/1000
START=1498748
END=1700825
title=Who's going to be Apple's competitor in the future?
[CHAPTER]
TIMEBASE=1/1000
START=1700825
END=1744158
title=Steve Jobs parked anywhere he wants
[CHAPTER]
TIMEBASE=1/1000
START=1744158
END=1946689
title=Jimmy Iovine told me some Steve Jobs stories

Is what FFMPEG sees as the metadata when I read from the file created with Auphonic, which matches the format on the page linked above. It seems possible to write .mp3 with chapters using FFmpeg if that page is accurate.

Testing this, I saved the metadata above as metadata.txt. Then in my terminal, I issued the command:

./ffmpeg -i /Users/vmarks/Downloads/ai\ pod/ai\ pod\ destri.mp3 -i /Users/vmarks/Downloads/ai\ pod/metadata.txt -map_metadata 1 -c:a copy -id3v2_version 3 -write_id3v1 1 /Users/vmarks/Downloads/ai\ pod/out.mp3

which took a file that had no chapters (ai pod destri.mp3) and read in the metadata.txt file, creating the out.mp3 with chapters. It had one error in the process, “[mp3 @ 0x7fb0e1803800] Audio packet of size 523 (starting with 00FFFBA0…) is invalid, writing it anyway.”

FFmpeg saved a new file (out.mp3) with tags that look like mp3 id3 chapters. If I use FFmpeg -I on that out.mp3 file, it reports the chapters are there, with exactly what was in the metadata.txt for it. I don’t know how to address that error, and something’s not perfect: when I open it in an application that supports chapters, they aren’t present. Also, I can see that the times have shifted slightly for start and stop from my file that has chapters created properly. I need to figure out why that is, and figure out why it looks like they’re present, but not in applications that do support them.

But this seems promising. Things I could improve on: I don’t really understand FFmpeg. I’m just using syntax that was mentioned on the link at the top of this post, without knowing exactly what to expect. The metadata.txt? I used FFworks, a gui frontend to FFmpeg, to read the chapters from the previously created known-working mp3 file, and clicked on “edit metadata” and copied and pasted that into a text editor. I admit I’m stumbling a bit here, but it feels… close.

That’s a shame - so close and yet so far :frowning:

You might like to try experimenting with Audacity’s command line export: Exporting using an external encoder program - Audacity Manual
If you could get this to work with chapter tags, then we could be well on the way to a usable workaround. It would probably be relatively easy to create a plug-in to read labels and return the appropriate text to copy and paste into the “External Program” command text box.


I found some information about creating “iPod-compatible” chapter tags, but this is using MP4 tags rather than MP3:
https://wiki.archlinux.org/index.php/Audiobook

Success.

./ffmpeg -i /Users/vmarks/Downloads/ai\ pod/ai\ pod\ destri.mp3 -i /Users/vmarks/Downloads/ai\ pod/metadata.txt -map_metadata 1 -codec copy -id3v2_version 3 -write_id3v1 1 /Users/vmarks/Downloads/ai\ pod/out.mp3

created an out.mp3 file, which does have chapters when I check in applications that support it like Marco Arment’s Forecast.app Forecast: Podcast MP3 Chapter Encoder — Overcast

Now that this checks out, how do we get to

It would probably be relatively easy to create a plug-in to read labels and return the appropriate text to copy and paste into the “External Program” command text box.

I do not know how to create this plug-in to form a metadata.txt formatted file out of labels.

What is your “metadata.txt” file?

the contents of metadata.txt is:

;FFMETADATA1
title=Blondie, Steve Jobs, Jimmy Iovine & Jimmy Destri
encoded_by=auphonic.com
artist=AppleInsider Podcast
date=2019
encoder=Lavf58.27.103
[CHAPTER]
TIMEBASE=1/1000
START=6894
END=63195
title=Opener
[CHAPTER]
TIMEBASE=1/1000
START=63195
END=642776
title=Introduction: Jimmy Destri
[CHAPTER]
TIMEBASE=1/1000
START=642776
END=725725
title=I know music, and I know addiction
[CHAPTER]
TIMEBASE=1/1000
START=725725
END=839739
title=Analog synths to digital and laptops
[CHAPTER]
TIMEBASE=1/1000
START=839739
END=896416
title=Garageband
[CHAPTER]
TIMEBASE=1/1000
START=896416
END=963578
title=Today, anybody can make a record
[CHAPTER]
TIMEBASE=1/1000
START=963578
END=1057941
title=iTunes really covered our asses
[CHAPTER]
TIMEBASE=1/1000
START=1057941
END=1128428
title=Spotify
[CHAPTER]
TIMEBASE=1/1000
START=1128428
END=1149937
title=You trust Apple...
[CHAPTER]
TIMEBASE=1/1000
START=1149937
END=1333239
title=What is Facebook's responsibility to their users
[CHAPTER]
TIMEBASE=1/1000
START=1333239
END=1498748
title=Apple News
[CHAPTER]
TIMEBASE=1/1000
START=1498748
END=1700825
title=Who's going to be Apple's competitor in the future?
[CHAPTER]
TIMEBASE=1/1000
START=1700825
END=1744158
title=Steve Jobs parked anywhere he wants
[CHAPTER]
TIMEBASE=1/1000
START=1744158
END=1946689
title=Jimmy Iovine told me some Steve Jobs stories

Presume the start and end numbers are the same as labels exported to .txt, but multiplied by 1000, moving the decimal place.

Tell me if I’ve got any of this wrong:

I assume that this part is standard to all metadata.txt files:

;FFMETADATA1
title=
encoded_by=
artist=
date=

If so, we can make a GUI with text fields for title, encoded by, artist and date.
The command for creating a text (string) input widget is:

;control variable "Text left" string "text right" "default text"



[CHAPTER]
TIMEBASE=1/1000
START=1700825
END=1744158
title=Steve Jobs parked anywhere he wants

>

So the format for each chapter  is:

```text
[CHAPTER]
TIMEBASE=<fraction> (multiplier for each of the time values, default = milliseconds)
START=<integer> (time in milliseconds when timebase=1/1000)
END=<integer> (time in milliseconds when timebase=1/1000)
title=<text> (chapter title / description)

I’m guessing that the timebase is usually 1/1000, and usually the same for each chapter.

We will also want a file browser button to set the location of the output file. This is probably the most complex of all of Nyquist’s GUI widgets, and is described here: Missing features - Audacity Support

So if I’m correct about the above, our interface could be something like this (you can run this in the Nyquist Prompt to see what it looks like.)

;version 4
;type tool
;codetype lisp
;name "Labels to Chapters"

;control timebase "Time base" int "" 1000 100 2000
;control title "Title" string "" ""
;control encodedby "Encoded by" string "" ""
;control artist "Artist" string "" ""
;control date "Date" string "" "2019"
;control filename "Save file as" file "" "*default*/metadata.txt" "Text file|*.txt;*.TXT|All files|*.*;*" "save,overwrite"

The “START”, “END” and “title” we can read from the labels, so we don’t need to do anything for those in the GUI.

Does that all look good so far?

Assuming that I got all that right in my previous post, this should create a correctly formatted “metadata.txt” file (Requires Audacity 2.3.2 or later).

;version 4
;type tool
;codetype lisp
;name "Labels to Chapters"
;author "Steve Daulton"
;release 2.3.2
;copyright "Released under terms of the GNU General Public License version 2"

;control timebase "Time base" int "" 1000 100 2000
;control title "Title" string "" ""
;control encodedby "Encoded by" string "" ""
;control artist "Artist" string "" ""
;control date "Date" string "" "2019"
;control filename "Save file as" file "" "*default*/metadata.txt" "Text file|*.txt;*.TXT|All files|*.*;*" "save,overwrite"


(setf metadata
  (format nil ";FFMETADATA1~%~
              title=~a~%~
              encoded_by=~a~%~
              artist=~a~%~
              date=~a~%~
              encoder=Lavf58.27.103~%"
              title
              encodedby
              artist
              date))

;;  Get label data from first label track
(setf labels (second (first (aud-get-info "Labels"))))


(dolist (label labels)
  (setf chapter
    (format nil "[CHAPTER]~%~
                TIMEBASE=1/~a~%~
                START=~a~%~
                END=~a~%~
                title=~a~%"
                timebase
                (round (* timebase (first label)))
                (round (* timebase (second label)))
                (third label)))
  (string-append metadata chapter))


(setf fp (open filename :direction :output))
(format fp metadata)
(close fp)
(format nil "File written to~%~a" filename)

This code assumes that your chapters are marked using region labels in the first (or only) label track.

You can run the above code in the Nyquist Prompt for testing.

For more convenient use, save the code as a file and name it “labels-to-chapters.ny”. Note that the “.ny” at the end is important. You can then install and enable the plug-in as described here (instructions for macOS): https://manual.audacityteam.org/man/installing_effect_generator_and_analyzer_plug_ins_on_mac_os_x.html#nyquist_install
When installed, the plug-in will appear in the “Tools” menu.

I don’t commonly use region labels, but instead just press command B to insert a marker, name it, and move on - it ends when the next one begins.

I can run the code from the Nyquist command prompt, but it will not install it as a plugin. I do not know why.

I’m not convinced I’m doing this right yet.