Duration not reported as number for Matroska files

Started by staticfinal, December 04, 2024, 07:47:09 AM

Previous topic - Next topic

staticfinal

Hello everyone,

I use the following command line to automatically extract metadata from video files uploaded to our website:

exiftool -d '%s' -json -Duration# ...other metadata fields... file

Normally I get the duration in seconds as expected:

[{
  "SourceFile": "foo.m4v",
  "Duration": 232.432432432432
}]

But for Matroska files the duration is reported as timecode:

[{
  "SourceFile": "bar.mkv",
  "Duration": "01:54:40.448000000",
}]

My code expects the JSON duration field to be a number and fails.

I'm using the latest version:

exiftool -ver
13.04

Am I missing some command line option to always report the duration in seconds or is this a problem in exiftool?

Kind regards,

Thomas

staticfinal

Sorry, I forgot to include the OS version. exiftool is running in an alpine-linux docker container.

uname -a
Linux 0efacf4cfc0e 6.10.14-linuxkit #1 SMP PREEMPT_DYNAMIC Thu Oct 24 19:30:56 UTC 2024 x86_64 Linux


StarGeek

Run the command in FAQ #3 and check to see if there are more than one Duration tag. Odds are that you will find there are multiple Duration tags.

One of these tags, usually the first one I think, is the duration of the file saved (computed?) as a number. This is the one that will return as seconds with the -n (--printConv) option.

Most MKV "Tags" are actually two tags which exiftool combines and displays as one. These tags are saved as a KEY:VALUE pair and are not saved as simple numbers, but as a string. That's what the extra duration tags are.

Here's an example looking at a file with MKVToolNix-GUI. Notice the highlighted duration is under "Segment information". This is the actual duration of the file.

The other two durations are below in the "Tags" section. They are saved as "Name:String" pairs. Note that these tags can be saved as any value and do not necessarily have to be accurate. The only reason they would be accurate is because the program that saved them wrote them accurately. You could easily change the values using any MKV editing tool to whatever value you wanted, and it would not break the video.

mkvtoolnix-gui-2024-12-04_07.11.55.png

MKV files have very few "set" tags. They are almost all KEY:VALUE pairs and the ones that you might see only exists because the community that creates the files has settled on these de facto names. You could easily add tags such as "NumberOfMonkeysInVideo" or "HowManyMoreGooglyEyesAreNeeded". Exiftool versions 12.51 and earlier will display Matroska tags separately
[Matroska]      Duration                        : 1741.727
[Matroska]      TagName                         : ENCODER
[Matroska]      TagString                       : Lavf57.79.100
[Matroska]      TagName                         : DURATION
[Matroska]      TagString                       : 00:29:01.727000000
[Matroska]      TagName                         : DURATION
[Matroska]      TagString                       : 00:29:01.656000000
"It didn't work" isn't helpful. What was the exact command used and the output.
Read FAQ #3 and use that cmd
Please use the Code button for exiftool output

Please include your OS/Exiftool version/filetype

staticfinal

Sorry for the late reply. Yes there are multiple Duration tags in the file.

exiftool -a -G1 -s /data/foo.mkv
...
[Matroska]      EBMLVersion                     : 1
[Matroska]      EBMLReadVersion                 : 1
[Matroska]      DocType                         : matroska
[Matroska]      DocTypeVersion                  : 4
[Matroska]      DocTypeReadVersion              : 2
[Matroska]      TimecodeScale                   : 1 ms
[Matroska]      MuxingApp                       : Lavf61.1.100
[Matroska]      WritingApp                      : Lavf61.1.100
[Matroska]      Duration                        : 1:43:04
[Matroska]      Encoder                         : Lavf61.1.100
[Matroska]      TagTrackUID                     : 52b98638625b3e56
[Matroska]      Duration                        : 01:43:04.033000000
[Matroska]      TagTrackUID                     : 6d4966dbc5c892c4
[Matroska]      Duration                        : 01:43:03.914000000

Exiftool is returning the last of the tags.

exiftool -Duration# /data/foo.mkv
Duration                        : 01:43:03.914000000

But I'm not completely sure I fully understand the problem. Is exiftool returning the value of the Duration tag unmodified because the format of the string contained in the tag is not specified? But since I instruct exiftool to return the value in seconds wouldn't it be better to not return a result at all, if that is the case?

StarGeek

#4
Quote from: staticfinal on December 09, 2024, 10:58:58 AMBut I'm not completely sure I fully understand the problem. Is exiftool returning the value of the Duration tag unmodified because the format of the string contained in the tag is not specified?

The other tags are only called Duration and are written by some program that made the file. They are not necessarily accurate. These are simply strings written to the file. These types of tags can be given any name you want. For example, I created this tag with ffmpeg
C:\>exiftool -G1 -a -s -*Monkey* Y:/!temp/Test5-edited.mkv
[Matroska]      Howmanymonkeys                  : 50 monkeys are in this video

The first Duration is the actual duration of the file. This is an actual number that is the duration of the file and can be converted to a human-readable form.

QuoteBut since I instruct exiftool to return the value in seconds wouldn't it be better to not return a result at all, if that is the case?

No, you didn't instruct exiftool to return the value in seconds. You instructed it to provide the raw value of the tag without converting it to a human-readable form. See the -n (--printConv) option.

The raw value of the other Duration tags are exactly what is listed, a value of "01:43:03.914000000". The raw value of the real Duration is a number.

Using exiftool's -v3 (-verbose3) option, you can look at the hex values for the tags. For the real Duration in the file I'm looking at right now, it shows this
  | | Duration = 5271
  | | - Tag 0x0489 (8 bytes):
  | |     0161: 40 b4 97 00 00 00 00 00                         [@.......]
The tag has an ID of 0x0489. The value in the tag is 5271 milliseconds (5.271 seconds). Exiftool will return "5.27 s" normally and "5.271" with the -n option.

Looking at the other two durations in this file, they are saved this way.
  | | | | TagName = DURATION
  | | | | - Tag 0x05a3 (8 bytes):
  | | | |     03b6: 44 55 52 41 54 49 4f 4e                         [DURATION]
  | | | | TagString = 00:00:05.252000000
  | | | | - Tag 0x0487 (20 bytes):
  | | | |     03c1: 30 30 3a 30 30 3a 30 35 2e 32 35 32 30 30 30 30 [00:00:05.2520000]
  | | | |     03d1: 30 30 00 00                                     [00..]
  | | | | Duration = 00:00:05.252000000
and
| | | | TagName = DURATION
  | | | | - Tag 0x05a3 (8 bytes):
  | | | |     03fa: 44 55 52 41 54 49 4f 4e                         [DURATION]
  | | | | TagString = 00:00:05.271000000
  | | | | - Tag 0x0487 (20 bytes):
  | | | |     0405: 30 30 3a 30 30 3a 30 35 2e 32 37 31 30 30 30 30 [00:00:05.2710000]
  | | | |     0415: 30 30 00 00                                     [00..]
  | | | | Duration = 00:00:05.271000000

These both have the same ID of 0x05a3 for the tag name and 0x0487 for the tag value. That is because these are NAME:VALUE pairs. The first part contains the name and the second part contains a string of "00:00:05.271000000".

Also notice that one of these does not match the actual duration of the file, going back to what I was saying about accuracy.

I know I'm not explaining this well, but it's a messy complicated subject, and I'm not sure how to clarify it better.
"It didn't work" isn't helpful. What was the exact command used and the output.
Read FAQ #3 and use that cmd
Please use the Code button for exiftool output

Please include your OS/Exiftool version/filetype

StarGeek

I thought I had written this in my first post, but I guess I forgot.

You can get the real Duration by using this command
exiftool -ID-1161:Duration /path/to/files/

Example:
C:\>exiftool -G1 -a -s -ID-1161:Duration Y:/!temp/Test5.mkv
[Matroska]      Duration                        : 5.27 s

C:\>exiftool -G1 -a -s -n -ID-1161:Duration Y:/!temp/Test5.mkv
[Matroska]      Duration                        : 5.271
"It didn't work" isn't helpful. What was the exact command used and the output.
Read FAQ #3 and use that cmd
Please use the Code button for exiftool output

Please include your OS/Exiftool version/filetype

staticfinal

Aaah! Thanks for the clarification und your help!