12

I found many question about creating DVD menu using ffmpeg but i did not find any one about programmically access to DVD structure information. When i using libav (or FFmpeg) library i can open DVD image (iso file) and access to video, audio and subtitle streams. But i could not find any API.

I can play video and found information using VLC player (and so libvlc library). But I need to do some processing on audio and subtitle stream programmically. I don't want to split VOBs using tools like SmartRipper, and only then do processing.

Does libav(ffmpeg) contain any API for dealing with DVD menus? If not can you recommend any other library which can be used to obtain information about title(chapter) start and end time with one frame(sample, AVPacket) accuracy?

I heard about libdvdnav library but i don't know if it right for me. I'm new to libav and DVD format internals.

4
  • Try using the ffmpeg command line utility on your iso file, and see the kinds of information it displays on the screen. The command is something like ffmpeg -i input.iso output.avi. If it displays the info you need, then it means that it is in principle accessible using libav.
    – sashoalm
    Commented Sep 3, 2012 at 9:57
  • I already tried to use ffprobe (avprobe) it displays only streams count and its type.
    – Tarhan
    Commented Sep 3, 2012 at 11:36
  • I'm not sure if ffprobe gives the same info as ffmpeg. I've never used ffprobe. Did you try using ffmpeg -i input.iso output.avi as well?
    – sashoalm
    Commented Sep 3, 2012 at 11:57
  • Yes, i tried to convert to avi. It also displays only information about streams count and type. By the way, both type of tools ffmpeg and ffprobe display length of first video. But when i encode iso image into avi format and ending of first video it continues to next without any message.
    – Tarhan
    Commented Sep 4, 2012 at 15:58

5 Answers 5

11

I'm not sure about what 1-frame accuracy means in this context. However, I've been using a tool called lsdvd, which is a basic CLI tool that takes as it's only parameter, the block device of your DVD drive. (Without that parameter, it will guess /dev/dvd, which is lacking on modern Linux, and is usually /dev/sr0.) It will then give you a nice listing of the chapters on the disc, like so:

$ lsdvd /dev/sr0
Disc Title: METAL_DISC_2
Title: 01, Length: 00:00:00.433 Chapters: 01, Cells: 01, Audio streams: 01, Subpictures: 01
Title: 02, Length: 00:00:11.500 Chapters: 01, Cells: 01, Audio streams: 01, Subpictures: 00
Title: 03, Length: 00:00:00.433 Chapters: 01, Cells: 01, Audio streams: 01, Subpictures: 01
Title: 04, Length: 00:00:00.433 Chapters: 01, Cells: 01, Audio streams: 01, Subpictures: 01
Title: 05, Length: 00:00:09.000 Chapters: 01, Cells: 01, Audio streams: 01, Subpictures: 00
Title: 06, Length: 00:00:10.000 Chapters: 01, Cells: 01, Audio streams: 01, Subpictures: 00
Title: 07, Length: 00:00:00.433 Chapters: 01, Cells: 01, Audio streams: 01, Subpictures: 01
Title: 08, Length: 00:25:02.333 Chapters: 06, Cells: 06, Audio streams: 01, Subpictures: 00
Title: 09, Length: 00:00:00.433 Chapters: 01, Cells: 01, Audio streams: 01, Subpictures: 00
Title: 10, Length: 00:07:48.700 Chapters: 16, Cells: 16, Audio streams: 01, Subpictures: 00
Title: 11, Length: 00:00:00.433 Chapters: 01, Cells: 01, Audio streams: 01, Subpictures: 00
Title: 12, Length: 00:16:43.066 Chapters: 08, Cells: 08, Audio streams: 01, Subpictures: 00
...snip...
Longest track: 20

If you wish to write your own code, I imagine looking at the source for lsdvd will be instructive. The only library it links against in Fedora 25 (other than standard stuff) is libdvdread.so.4, which is part of the dvdnav project.

HTH.

2
  • 1
    Also note that you can use lsdvd -c to show detailed information about chapters.
    – a3nm
    Commented Jan 22, 2019 at 17:13
  • It also accepts ISO files as input, nice tool.
    – Álex
    Commented Oct 22, 2022 at 9:20
4

Basically you can’t tell, but you can look for the longest title.

one option: use handbrakecli -scan e: (part of handbrake)

another: use mplayer -identify dvd:// -dvd-device e: (mplayer standard)

From: http://betterlogic.com/roger/2011/07/dvd-determine-main-title-from-command-line/

This helped me, as VLC lists the titles and chapters in it's GUI Menu's

Basically, install VLC Media Player, then play your DVD in it. Navigate through till it “is playing the real title”

then go to Playback [menu] -> title and see which one it is currently highlighting.

Now you know which title is the “main” title track.

Source: http://betterlogic.com/roger/2010/11/how-to-use-vlc-to-tell-how-many-titles-and-chapters-and-which-is-the-main/

3

Mplayer can do this. I am not familiar with their library, but this could get you started

mplayer dvd:// -identify

Result

CHAPTERS: 00:00:00.000,00:03:40.200,00:07:29.500,00:12:04.033,00:16:17.199,
00:27:36.499,00:34:26.166,00:43:37.199,00:49:29.533,00:59:46.500,01:12:47.667,
01:17:09.000,01:26:13.700,01:47:15.833,01:50:06.200,01:55:25.500,02:06:42.500,
02:13:03.666,02:20:37.499,02:28:20.832,02:33:26.832,02:37:47.532,02:43:58.665,
02:51:00.165,02:56:36.165,03:01:21.998,03:05:09.331,03:07:14.665,03:11:49.665,
03:16:35.165,
2
  • 3
    I added the -frames 0 option to prevent actually playing the video. Example: mplayer -identify -frames 0 '/path/to/VIDEO_TS.IFO 2>/dev/null | grep CHAPTERS:
    – mivk
    Commented Oct 17, 2013 at 17:32
  • alternatively you can filter with grep TITLE titles seem to come one per line
    – Falk
    Commented Aug 21, 2016 at 17:27
3

I use a combination of both of the above to create a DVD chapter file which I can later add with mkvmerge to an encoded mkv file:

#!/bin/bash
if [ $# -lt 1 ]; then
    echo "Usage: $0 filename title_no"
    exit 
fi

i=1
j2=01
filename=$1
echo "Using lsdvd to load chapter info:"
lsdvd -c ./
if [ -z "$2" ]; then
    echo -ne "What title number do you want to create chapter info for: "
    read title
else
    title=$2
fi
IFS=',' read -r -a CHAPTERS <<< `mplayer -identify -frames 0 "./VTS_0"$title"_0.IFO" 2>/dev/null | grep CHAPTERS: | sed 's/CHAPTERS: //'`

for chapter in "${CHAPTERS[@]}"
do
    echo "Chapter $i: $chapter"
    let i++
done

echo -ne "Creating chapter data file...."
sleep 3
for chapter in "${CHAPTERS[@]}"
do
    echo "CHAPTER$j2=$chapter" >> $filename.txt
    echo "CHAPTER"$j2"NAME=Chapter $j2" >> $filename.txt
    j2=$(printf %02d $((10#$j2 + 1 )))

done
echo "DONE."
echo "Chapter data file: $filename.txt"

Example output:

$ read_chapters.sh whiteglasses_chapters
Using lsdvd to load chapter info: 
libdvdread: Couldn't find device name.
Couldn't read enough bytes for title.
Disc Title: unknown
Title: 01, Length: 00:00:21.000 Chapters: 01, Cells: 01, Audio streams: 00, Subpictures: 00
    Chapter: 01, Length: 00:00:21.000, Start Cell: 01
Title: 02, Length: 01:52:32.166 Chapters: 11, Cells: 12, Audio streams: 02, Subpictures: 01
    Chapter: 01, Length: 00:10:23.200, Start Cell: 01
    Chapter: 02, Length: 00:11:53.200, Start Cell: 02
    Chapter: 03, Length: 00:08:02.367, Start Cell: 03
    Chapter: 04, Length: 00:11:28.533, Start Cell: 04
    Chapter: 05, Length: 00:12:55.834, Start Cell: 05
    Chapter: 06, Length: 00:12:26.600, Start Cell: 06
    Chapter: 07, Length: 00:16:20.766, Start Cell: 07
    Chapter: 08, Length: 00:10:31.934, Start Cell: 09
    Chapter: 09, Length: 00:09:24.033, Start Cell: 10
    Chapter: 10, Length: 00:09:04.767, Start Cell: 11
    Chapter: 11, Length: 00:00:00.800, Start Cell: 12
    Longest track: 02
    What title number do you want to create chapter info for: 2 
    Chapter 1: 00:00:00.000
    Chapter 2: 00:10:23.200
    Chapter 3: 00:22:16.400
    Chapter 4: 00:30:18.767
    Chapter 5: 00:41:47.300
    Chapter 6: 00:54:43.134
    Chapter 7: 01:07:09.734
    Chapter 8: 01:23:30.500
    Chapter 9: 01:34:02.434
    Chapter 10: 01:43:26.467
    Chapter 11: 01:52:31.234 
    Creating chapter data file....DONE.
    Chapter data file: whiteglasses_chapters.txt

Then I simply run:

mkvmerge --chapters chapters.txt -o output.mkv input-file.mkv
0

Linux and Windows

vgtmpeg can be used to create a metadata file with chapter data from DVDs and BDs. This metadata file can then be used as an input file to ffmpeg to mark chapters. vgtmpeg is a fork of ffmpeg but, because it is not updated very often, we'll use it as a separate tool here.

Single title in VOB

If working with VOBs containing a single title ("program" in ffmpeg terms), you can export the metadata as follows.

For just the main global data:

vgtmpeg -i dvd://VIDEO_TS -f ffmetadata meta.txt

For all the metadata, including stream data (-t 0 is just for shortcutting the copy operation):

vgtmpeg -t 0 -i dvd://VIDEO_TS -c copy -map 0 -map_metadata 0 -f ffmetadata meta.txt

You can then use your preferred version of ffmpeg to work with the VOBs while also bringing in the chapter data and other metadata.

Windows form:

ffmpeg -i concat:"VTS_01_1.VOB|VTS_01_2.VOB" -i meta.txt -c copy -map_metadata 1 foo.mkv

Linux form:

ffmpeg -i "concat:VTS_01_1.VOB\|VTS_01_2.VOB" -i meta.txt -c copy -map_metadata 1 foo.mkv

Add -fflags +genpts before the -i if ffmpeg complains about timestamps missing in your VOBs.

Irregularities

-map_metadata 0 is needed to get all the global metadata (like creation_time) for an unknown reason. Perhaps a bug. Perhaps this will change some day.

Similarly, it is not clear why -c copy is needed for stream metadata export... but it is likely related to needing -map 0 to select all the streams in input 0 for metadata export. From there -map_metadata 0 is needed to force including stream metadata with the global metadata (again, unknown as to why this is only needed when working with just the metadata).

If you want to limit the streams in the metadata file, map only the streams you want (e.g. -map 0:v -map 0:a). Use -map_metadata:?:? ?:?:? only for very unusual cases where needing to map data from one place to another.

Multiple titles in VOB

If working with VOBs containing multiple titles, you can still export to text files like above but, then, slicing later with ffmpeg becomes a challenge. Thus, we use vgtmpeg to create an intermediate transport file instead. Note: TS files do not support metadata, so use your destination format instead for the intermediate file (or use MKV since it complains the least about VOB streams and metadata).

vgtmpeg -i dvd://VIDEO_TS?title=1 -c copy -map 0 -map -0:d title1.mkv

Add -fflags +genpts before the -i if ffmpeg complains about timestamps missing in your VOBs. The dvd_nav_packet data stream will likely not be welcome in your output file, so we use -map -0:d to ignore all data streams.

You can then use your preferred version of ffmpeg to work with the intermediate file.

ffmpeg -i title1.mkv -c copy -map 0 done1.mkv

Whether or not -map_metadata 0 is needed here seems to depend on the file formats in use. MKV, by default, does well without i.

Adding chapter titles

Unfortunately, there is no built-in way to add chapter title generation with vgtmpeg/ffmpeg. One could maybe process meta.txt with a sed script (Super-Sed for Windows) to add title=Chapter 1 lines... but that is a task for another day. Alternatively, scripting out a long ffmpeg command with -metadata:c:0 title="Chapter 1" ... seems possible too.

Wish list

It would be nice if ffmpeg added IFO input support for program and chapter reading. Or, maybe, just absorb what vgtmpeg has done (but rename the title URL selector to "program" to help keep things straight.)

Windows only

Windows users can use Chapter-X-tractor with IFO files to generate a metadata file that ffmpeg can use to mark chapters. It's not a great solution for automation but, for one-off jobs, it works well enough. It also allows for very basic chapter title generation.

It doesn't come with a preset for ffmpeg (too old) so you need to add one with the following settings:

Header: ;FFMETADATA1\n

Format: \n[CHAPTER]\nTIMEBASE=1/1000\nSTART=%ams\nEND=%ams\ntitle=Chapter %c\n

Footer: [empty]

Like so:

Chapter-X-tractor screenshot of Format tab and settings

Save the data to a file such as ch.txt. Then, you can use ffmpeg to write the chapter data like so:

ffmpeg -i concat:"VTS_01_1.VOB|VTS_01_2.VOB" -i ch.txt -c copy -map_chapters 1 foo.mkv

Add -fflags +genpts before the -i if ffmpeg complains about timestamps missing in your VOBs.

Caveats

This creates a metadata file that is not 100% correct according to ffmpeg standards. For some unknown reason, ffmpeg wants a chapter end time and Chapter-X-tractor cannot fill this need elegantly. Thus, this sets START and END to the same value. This works fine in VLC and, likely, most other players.

If you're a purist, you can edit the output metadata file and copy chapter start times to the previous chapters' end times. Then, using the Total Film Length found on the RAW Data tab (shown in hh:mm:ss:cc format [cc is hundredths of a seconds]), calculate the last chapter's end time in milliseconds (one zero beyond the cc value).

Irregularities

If you leave out the END= line, ffmpeg will throw an error message but fills it in anyway with the next chapter's start time... which is good... except, on the last chapter where it sets start and end the same. This error also prevents reading the title= data. Thus, this is a poor solution overall.

This tool calculates chapter times that can be a few tenths of a second different from vgtmpeg.

Not the answer you're looking for? Browse other questions tagged or ask your own question.