This is an old revision of the document!
dvd_info
My own set of C programs that are small utilities for reading DVD info, and managing DVD drives.
Included:
dvd_info
- a successor in spirit to lsdvd, can output information about a DVD in human-readable or JSON outputdvd_drive_status
- poll the DVD drive to see the status of a drive: open, polling, closed with no disc, closed with discdvd_eject
- a small eject utility that does its best to make sure a drive is properly closed and ready to go before being able toa ccess it (very useful for shell scripts that access DVD drives)dvd_copy
- copies a VOB straight to harddrive or stdoutdvd_player
- a DVD player using libmpvdvd_trip
- a DVD ripper using libmpv
The code is open-source, licensed under GNU GPL v2. Source code is available at https://github.com/beandog/dvd_info.
Build requirements: libdvdread, libdvdcss, libmpv (optional)
Installation
Then you can do standard ./configure; make; make install
dvd_info
See –help
for all the fancy stuff it can do. A man page (man dvd_info) is also included.
dvd_info - display information about a DVD Usage: dvd_info [path] [options] Options: -t, --track <number> Limit to selected track (default: all tracks) -j, --json Display output in JSON format Detailed information: -v, --video Display video streams -a, --audio Display audio streams -s, --subtitles Display VobSub subtitles -c, --chapters Display chapters -d, --cells Display cells -x, --all Display all Narrow results: -l, --longest Track with the longest length -A, --has-audio Track has audio streams -S, --has-subtitles Track has VobSub subtitles -E, --seconds <secs> Track has minimum number of seconds -M, --minutes <mins> Track has minimum number of minutes -T, --vts <number> Track is in video title set number -L, --valid Track is marked as valid Other: -i, --id Display DVD ID only -u, --volume Display DVD UDF volume name only (for ISO or disc) -g, --xchap Display title's chapter format for mkvmerge -h, --help Display these help options --version Display version DVD path can be a device name, a single file, or a directory (default: /dev/sr0)
Human-friendly output
Here's what polling a Batman: The Animated Series DVD looks like:
$ dvd_info 1.005.0053.BATMAN_THE_ANIMATED_SERIES.iso Disc Title: BATMAN_ANIMATED_SERIES_DISC1 Title: 01, Length: 02:36:21.100 Chapters: 07, Cells: 07, Audio streams: 04, Subpictures: 03 Title: 02, Length: 00:00:12.000 Chapters: 01, Cells: 01, Audio streams: 04, Subpictures: 03 Title: 03, Length: 00:00:32.033 Chapters: 01, Cells: 01, Audio streams: 04, Subpictures: 03 Title: 04, Length: 00:01:06.800 Chapters: 01, Cells: 01, Audio streams: 04, Subpictures: 03 Title: 05, Length: 00:00:29.967 Chapters: 01, Cells: 01, Audio streams: 04, Subpictures: 03 Title: 06, Length: 00:22:20.100 Chapters: 01, Cells: 01, Audio streams: 04, Subpictures: 03 Title: 07, Length: 00:22:20.834 Chapters: 01, Cells: 01, Audio streams: 04, Subpictures: 03 Title: 08, Length: 00:22:24.433 Chapters: 01, Cells: 01, Audio streams: 04, Subpictures: 03 Title: 09, Length: 00:22:17.000 Chapters: 01, Cells: 01, Audio streams: 04, Subpictures: 03 Title: 10, Length: 00:22:18.734 Chapters: 01, Cells: 01, Audio streams: 04, Subpictures: 03 Title: 11, Length: 00:22:24.000 Chapters: 01, Cells: 01, Audio streams: 04, Subpictures: 03 Title: 12, Length: 00:22:16.000 Chapters: 01, Cells: 01, Audio streams: 04, Subpictures: 03 Title: 13, Length: 00:05:02.000 Chapters: 01, Cells: 01, Audio streams: 04, Subpictures: 03 Title: 14, Length: 00:22:20.100 Chapters: 01, Cells: 01, Audio streams: 04, Subpictures: 03 Longest track: 01
Specifing a track:
$ dvd_info -t 6 1.005.0053.BATMAN_THE_ANIMATED_SERIES.iso Disc Title: BATMAN_ANIMATED_SERIES_DISC1 Title: 06, Length: 00:22:20.100 Chapters: 01, Cells: 01, Audio streams: 04, Subpictures: 03
JSON output
The JSON output functionality will print *all* the information that dvd_info
polls about the DVD. This is far more than the human-friendly output.
$ dvd_info -j 1.005.0053.BATMAN_THE_ANIMATED_SERIES.iso { "dvd": { "title": "BATMAN_ANIMATED_SERIES_DISC1", "side": 1, "tracks": 14, "longest track": 1, "provider id": "WARNER HOME VIDEO", "vmg id": "DVDVIDEO-VMG", "video title sets": 1, "dvdread id": "b4e9000903e4ec04c275dd6f9abfb944" }, "tracks": [ { "track": 1, "length": "02:36:21.100", "msecs": 9381100, "vts": 1, "ttn": 1, "video": { "codec": "MPEG2", "format": "NTSC", "aspect ratio": "4:3", "width": 720, "height": 480, "angles": 1, "fps": "29.97" }, "audio": [ { "track": 1, "active": 1, "lang code": "en", "codec": "ac3", "channels": 2, "stream id": "0x80" }, { "track": 2, "active": 1, "lang code": "fr", "codec": "ac3", "channels": 2, "stream id": "0x81" }, { "track": 3, "active": 1, "lang code": "es", "codec": "ac3", "channels": 2, "stream id": "0x82" }, { "track": 4, "active": 0, "lang code": "en", "codec": "ac3", "channels": 2, "stream id": "0x83" } ], "subtitles": [ { "track": 1, "active": 1, "lang code": "en", "stream id": "0x20" }, { "track": 2, "active": 1, "lang code": "fr", "stream id": "0x21" }, { "track": 3, "active": 1, "lang code": "es", "stream id": "0x22" } ], "chapters": [ { "chapter": 1, "length": "00:22:20.100", "msecs": 1340100, "startcell": 1 }, { "chapter": 2, "length": "00:22:20.834", "msecs": 1340834, "startcell": 2 }, { "chapter": 3, "length": "00:22:24.433", "msecs": 1344433, "startcell": 3 }, { "chapter": 4, "length": "00:22:17.000", "msecs": 1337000, "startcell": 4 }, { "chapter": 5, "length": "00:22:18.734", "msecs": 1338734, "startcell": 5 }, { "chapter": 6, "length": "00:22:24.000", "msecs": 1344000, "startcell": 6 }, { "chapter": 7, "length": "00:22:16.000", "msecs": 1336000, "startcell": 7 } ], "cells": [ { "cell": 1, "length": "00:22:20.100", "msecs": 1340100 }, { "cell": 2, "length": "00:22:20.834", "msecs": 1340834 }, { "cell": 3, "length": "00:22:24.433", "msecs": 1344433 }, { "cell": 4, "length": "00:22:17.000", "msecs": 1337000 }, { "cell": 5, "length": "00:22:18.734", "msecs": 1338734 }, { "cell": 6, "length": "00:22:24.000", "msecs": 1344000 }, { "cell": 7, "length": "00:22:16.000", "msecs": 1336000 } ] }, { "track": 2, "length": "00:00:12.000", "msecs": 12000, "vts": 1, "ttn": 2, "video": { "codec": "MPEG2", "format": "NTSC", "aspect ratio": "4:3", "width": 720, "height": 480, "angles": 1, "fps": "29.97" }, "audio": [ { "track": 1, "active": 1, "lang code": "en", "codec": "ac3", "channels": 2, "stream id": "0x80" }, { "track": 2, "active": 1, "lang code": "fr", "codec": "ac3", "channels": 2, "stream id": "0x81" }, { "track": 3, "active": 1, "lang code": "es", "codec": "ac3", "channels": 2, "stream id": "0x82" }, { "track": 4, "active": 0, "lang code": "en", "codec": "ac3", "channels": 2, "stream id": "0x83" } ], "subtitles": [ { "track": 1, "active": 1, "lang code": "en", "stream id": "0x20" }, { "track": 2, "active": 1, "lang code": "fr", "stream id": "0x21" }, { "track": 3, "active": 1, "lang code": "es", "stream id": "0x22" } ], "chapters": [ { "chapter": 1, "length": "00:00:12.000", "msecs": 12000, "startcell": 1 } ], "cells": [ { "cell": 1, "length": "00:00:12.000", "msecs": 12000 } ] }, { "track": 3, "length": "00:00:32.033", "msecs": 32033, "vts": 1, "ttn": 3, "video": { "codec": "MPEG2", "format": "NTSC", "aspect ratio": "4:3", "width": 720, "height": 480, "angles": 1, "fps": "29.97" }, "audio": [ { "track": 1, "active": 1, "lang code": "en", "codec": "ac3", "channels": 2, "stream id": "0x80" }, { "track": 2, "active": 1, "lang code": "fr", "codec": "ac3", "channels": 2, "stream id": "0x81" }, { "track": 3, "active": 1, "lang code": "es", "codec": "ac3", "channels": 2, "stream id": "0x82" }, { "track": 4, "active": 0, "lang code": "en", "codec": "ac3", "channels": 2, "stream id": "0x83" } ], "subtitles": [ { "track": 1, "active": 1, "lang code": "en", "stream id": "0x20" }, { "track": 2, "active": 1, "lang code": "fr", "stream id": "0x21" }, { "track": 3, "active": 1, "lang code": "es", "stream id": "0x22" } ], "chapters": [ { "chapter": 1, "length": "00:00:32.033", "msecs": 32033, "startcell": 1 } ], "cells": [ { "cell": 1, "length": "00:00:32.033", "msecs": 32033 } ] }, { "track": 4, "length": "00:01:06.800", "msecs": 66800, "vts": 1, "ttn": 4, "video": { "codec": "MPEG2", "format": "NTSC", "aspect ratio": "4:3", "width": 720, "height": 480, "angles": 1, "fps": "29.97" }, "audio": [ { "track": 1, "active": 1, "lang code": "en", "codec": "ac3", "channels": 2, "stream id": "0x80" }, { "track": 2, "active": 1, "lang code": "fr", "codec": "ac3", "channels": 2, "stream id": "0x81" }, { "track": 3, "active": 1, "lang code": "es", "codec": "ac3", "channels": 2, "stream id": "0x82" }, { "track": 4, "active": 0, "lang code": "en", "codec": "ac3", "channels": 2, "stream id": "0x83" } ], "subtitles": [ { "track": 1, "active": 1, "lang code": "en", "stream id": "0x20" }, { "track": 2, "active": 1, "lang code": "fr", "stream id": "0x21" }, { "track": 3, "active": 1, "lang code": "es", "stream id": "0x22" } ], "chapters": [ { "chapter": 1, "length": "00:01:06.800", "msecs": 66800, "startcell": 1 } ], "cells": [ { "cell": 1, "length": "00:01:06.800", "msecs": 66800 } ] }, { "track": 5, "length": "00:00:29.967", "msecs": 29967, "vts": 1, "ttn": 5, "video": { "codec": "MPEG2", "format": "NTSC", "aspect ratio": "4:3", "width": 720, "height": 480, "angles": 1, "fps": "29.97" }, "audio": [ { "track": 1, "active": 1, "lang code": "en", "codec": "ac3", "channels": 2, "stream id": "0x80" }, { "track": 2, "active": 1, "lang code": "fr", "codec": "ac3", "channels": 2, "stream id": "0x81" }, { "track": 3, "active": 1, "lang code": "es", "codec": "ac3", "channels": 2, "stream id": "0x82" }, { "track": 4, "active": 0, "lang code": "en", "codec": "ac3", "channels": 2, "stream id": "0x83" } ], "subtitles": [ { "track": 1, "active": 1, "lang code": "en", "stream id": "0x20" }, { "track": 2, "active": 1, "lang code": "fr", "stream id": "0x21" }, { "track": 3, "active": 1, "lang code": "es", "stream id": "0x22" } ], "chapters": [ { "chapter": 1, "length": "00:00:29.967", "msecs": 29967, "startcell": 1 } ], "cells": [ { "cell": 1, "length": "00:00:29.967", "msecs": 29967 } ] }, { "track": 6, "length": "00:22:20.100", "msecs": 1340100, "vts": 1, "ttn": 6, "video": { "codec": "MPEG2", "format": "NTSC", "aspect ratio": "4:3", "width": 720, "height": 480, "angles": 1, "fps": "29.97" }, "audio": [ { "track": 1, "active": 1, "lang code": "en", "codec": "ac3", "channels": 2, "stream id": "0x80" }, { "track": 2, "active": 1, "lang code": "fr", "codec": "ac3", "channels": 2, "stream id": "0x81" }, { "track": 3, "active": 1, "lang code": "es", "codec": "ac3", "channels": 2, "stream id": "0x82" }, { "track": 4, "active": 0, "lang code": "en", "codec": "ac3", "channels": 2, "stream id": "0x83" } ], "subtitles": [ { "track": 1, "active": 1, "lang code": "en", "stream id": "0x20" }, { "track": 2, "active": 1, "lang code": "fr", "stream id": "0x21" }, { "track": 3, "active": 1, "lang code": "es", "stream id": "0x22" } ], "chapters": [ { "chapter": 1, "length": "00:22:20.100", "msecs": 1340100, "startcell": 1 } ], "cells": [ { "cell": 1, "length": "00:22:20.100", "msecs": 1340100 } ] }, { "track": 7, "length": "00:22:20.834", "msecs": 1340834, "vts": 1, "ttn": 7, "video": { "codec": "MPEG2", "format": "NTSC", "aspect ratio": "4:3", "width": 720, "height": 480, "angles": 1, "fps": "29.97" }, "audio": [ { "track": 1, "active": 1, "lang code": "en", "codec": "ac3", "channels": 2, "stream id": "0x80" }, { "track": 2, "active": 1, "lang code": "fr", "codec": "ac3", "channels": 2, "stream id": "0x81" }, { "track": 3, "active": 1, "lang code": "es", "codec": "ac3", "channels": 2, "stream id": "0x82" }, { "track": 4, "active": 0, "lang code": "en", "codec": "ac3", "channels": 2, "stream id": "0x83" } ], "subtitles": [ { "track": 1, "active": 1, "lang code": "en", "stream id": "0x20" }, { "track": 2, "active": 1, "lang code": "fr", "stream id": "0x21" }, { "track": 3, "active": 1, "lang code": "es", "stream id": "0x22" } ], "chapters": [ { "chapter": 1, "length": "00:22:20.834", "msecs": 1340834, "startcell": 1 } ], "cells": [ { "cell": 1, "length": "00:22:20.834", "msecs": 1340834 } ] }, { "track": 8, "length": "00:22:24.433", "msecs": 1344433, "vts": 1, "ttn": 8, "video": { "codec": "MPEG2", "format": "NTSC", "aspect ratio": "4:3", "width": 720, "height": 480, "angles": 1, "fps": "29.97" }, "audio": [ { "track": 1, "active": 1, "lang code": "en", "codec": "ac3", "channels": 2, "stream id": "0x80" }, { "track": 2, "active": 1, "lang code": "fr", "codec": "ac3", "channels": 2, "stream id": "0x81" }, { "track": 3, "active": 1, "lang code": "es", "codec": "ac3", "channels": 2, "stream id": "0x82" }, { "track": 4, "active": 0, "lang code": "en", "codec": "ac3", "channels": 2, "stream id": "0x83" } ], "subtitles": [ { "track": 1, "active": 1, "lang code": "en", "stream id": "0x20" }, { "track": 2, "active": 1, "lang code": "fr", "stream id": "0x21" }, { "track": 3, "active": 1, "lang code": "es", "stream id": "0x22" } ], "chapters": [ { "chapter": 1, "length": "00:22:24.433", "msecs": 1344433, "startcell": 1 } ], "cells": [ { "cell": 1, "length": "00:22:24.433", "msecs": 1344433 } ] }, { "track": 9, "length": "00:22:17.000", "msecs": 1337000, "vts": 1, "ttn": 9, "video": { "codec": "MPEG2", "format": "NTSC", "aspect ratio": "4:3", "width": 720, "height": 480, "angles": 1, "fps": "29.97" }, "audio": [ { "track": 1, "active": 1, "lang code": "en", "codec": "ac3", "channels": 2, "stream id": "0x80" }, { "track": 2, "active": 1, "lang code": "fr", "codec": "ac3", "channels": 2, "stream id": "0x81" }, { "track": 3, "active": 1, "lang code": "es", "codec": "ac3", "channels": 2, "stream id": "0x82" }, { "track": 4, "active": 0, "lang code": "en", "codec": "ac3", "channels": 2, "stream id": "0x83" } ], "subtitles": [ { "track": 1, "active": 1, "lang code": "en", "stream id": "0x20" }, { "track": 2, "active": 1, "lang code": "fr", "stream id": "0x21" }, { "track": 3, "active": 1, "lang code": "es", "stream id": "0x22" } ], "chapters": [ { "chapter": 1, "length": "00:22:17.000", "msecs": 1337000, "startcell": 1 } ], "cells": [ { "cell": 1, "length": "00:22:17.000", "msecs": 1337000 } ] }, { "track": 10, "length": "00:22:18.734", "msecs": 1338734, "vts": 1, "ttn": 10, "video": { "codec": "MPEG2", "format": "NTSC", "aspect ratio": "4:3", "width": 720, "height": 480, "angles": 1, "fps": "29.97" }, "audio": [ { "track": 1, "active": 1, "lang code": "en", "codec": "ac3", "channels": 2, "stream id": "0x80" }, { "track": 2, "active": 1, "lang code": "fr", "codec": "ac3", "channels": 2, "stream id": "0x81" }, { "track": 3, "active": 1, "lang code": "es", "codec": "ac3", "channels": 2, "stream id": "0x82" }, { "track": 4, "active": 0, "lang code": "en", "codec": "ac3", "channels": 2, "stream id": "0x83" } ], "subtitles": [ { "track": 1, "active": 1, "lang code": "en", "stream id": "0x20" }, { "track": 2, "active": 1, "lang code": "fr", "stream id": "0x21" }, { "track": 3, "active": 1, "lang code": "es", "stream id": "0x22" } ], "chapters": [ { "chapter": 1, "length": "00:22:18.734", "msecs": 1338734, "startcell": 1 } ], "cells": [ { "cell": 1, "length": "00:22:18.734", "msecs": 1338734 } ] }, { "track": 11, "length": "00:22:24.000", "msecs": 1344000, "vts": 1, "ttn": 11, "video": { "codec": "MPEG2", "format": "NTSC", "aspect ratio": "4:3", "width": 720, "height": 480, "angles": 1, "fps": "29.97" }, "audio": [ { "track": 1, "active": 1, "lang code": "en", "codec": "ac3", "channels": 2, "stream id": "0x80" }, { "track": 2, "active": 1, "lang code": "fr", "codec": "ac3", "channels": 2, "stream id": "0x81" }, { "track": 3, "active": 1, "lang code": "es", "codec": "ac3", "channels": 2, "stream id": "0x82" }, { "track": 4, "active": 0, "lang code": "en", "codec": "ac3", "channels": 2, "stream id": "0x83" } ], "subtitles": [ { "track": 1, "active": 1, "lang code": "en", "stream id": "0x20" }, { "track": 2, "active": 1, "lang code": "fr", "stream id": "0x21" }, { "track": 3, "active": 1, "lang code": "es", "stream id": "0x22" } ], "chapters": [ { "chapter": 1, "length": "00:22:24.000", "msecs": 1344000, "startcell": 1 } ], "cells": [ { "cell": 1, "length": "00:22:24.000", "msecs": 1344000 } ] }, { "track": 12, "length": "00:22:16.000", "msecs": 1336000, "vts": 1, "ttn": 12, "video": { "codec": "MPEG2", "format": "NTSC", "aspect ratio": "4:3", "width": 720, "height": 480, "angles": 1, "fps": "29.97" }, "audio": [ { "track": 1, "active": 1, "lang code": "en", "codec": "ac3", "channels": 2, "stream id": "0x80" }, { "track": 2, "active": 1, "lang code": "fr", "codec": "ac3", "channels": 2, "stream id": "0x81" }, { "track": 3, "active": 1, "lang code": "es", "codec": "ac3", "channels": 2, "stream id": "0x82" }, { "track": 4, "active": 0, "lang code": "en", "codec": "ac3", "channels": 2, "stream id": "0x83" } ], "subtitles": [ { "track": 1, "active": 1, "lang code": "en", "stream id": "0x20" }, { "track": 2, "active": 1, "lang code": "fr", "stream id": "0x21" }, { "track": 3, "active": 1, "lang code": "es", "stream id": "0x22" } ], "chapters": [ { "chapter": 1, "length": "00:22:16.000", "msecs": 1336000, "startcell": 1 } ], "cells": [ { "cell": 1, "length": "00:22:16.000", "msecs": 1336000 } ] }, { "track": 13, "length": "00:05:02.000", "msecs": 302000, "vts": 1, "ttn": 13, "video": { "codec": "MPEG2", "format": "NTSC", "aspect ratio": "4:3", "width": 720, "height": 480, "angles": 1, "fps": "29.97" }, "audio": [ { "track": 1, "active": 1, "lang code": "en", "codec": "ac3", "channels": 2, "stream id": "0x80" }, { "track": 2, "active": 1, "lang code": "fr", "codec": "ac3", "channels": 2, "stream id": "0x81" }, { "track": 3, "active": 1, "lang code": "es", "codec": "ac3", "channels": 2, "stream id": "0x82" }, { "track": 4, "active": 0, "lang code": "en", "codec": "ac3", "channels": 2, "stream id": "0x83" } ], "subtitles": [ { "track": 1, "active": 1, "lang code": "en", "stream id": "0x20" }, { "track": 2, "active": 1, "lang code": "fr", "stream id": "0x21" }, { "track": 3, "active": 1, "lang code": "es", "stream id": "0x22" } ], "chapters": [ { "chapter": 1, "length": "00:05:02.000", "msecs": 302000, "startcell": 1 } ], "cells": [ { "cell": 1, "length": "00:05:02.000", "msecs": 302000 } ] }, { "track": 14, "length": "00:22:20.100", "msecs": 1340100, "vts": 1, "ttn": 14, "video": { "codec": "MPEG2", "format": "NTSC", "aspect ratio": "4:3", "width": 720, "height": 480, "angles": 1, "fps": "29.97" }, "audio": [ { "track": 1, "active": 1, "lang code": "en", "codec": "ac3", "channels": 2, "stream id": "0x80" }, { "track": 2, "active": 1, "lang code": "fr", "codec": "ac3", "channels": 2, "stream id": "0x81" }, { "track": 3, "active": 1, "lang code": "es", "codec": "ac3", "channels": 2, "stream id": "0x82" }, { "track": 4, "active": 0, "lang code": "en", "codec": "ac3", "channels": 2, "stream id": "0x83" } ], "subtitles": [ { "track": 1, "active": 1, "lang code": "en", "stream id": "0x20" }, { "track": 2, "active": 1, "lang code": "fr", "stream id": "0x21" }, { "track": 3, "active": 1, "lang code": "es", "stream id": "0x22" } ], "chapters": [ { "chapter": 1, "length": "00:22:20.100", "msecs": 1340100, "startcell": 1 } ], "cells": [ { "cell": 1, "length": "00:22:20.100", "msecs": 1340100 } ] } ] }