我有一个mkv文件没有有效的持续时间。我想手动更改此持续时间参数。我浏览了在http://www.matroska.org/technical/specs/index.html
看看matroska的规范,它只包含标识幻数,但没有指定数据的长度。
如何解析这个matroska头,以便获得持续时间字段并更改此字段?
"持续时间"字段的类型为浮动。根据文件,它可以是4个或8个八位字节。要知道它的大小,您必须查看字段的数据大小部分。数据大小部分使用类似UTF-8的系统。这里有解释。
您可以使用ffprobe来获取.mmv文件的持续时间:
$ ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 input.mkv
5012.640000
请参阅:https://trac.ffmpeg.org/wiki/FFprobeTips#Duration
Matroska使用EBML(https://en.wikipedia.org/wiki/Extensible_Binary_Meta_Language)作为基础。EBML元素使用大小可变的整数,因此只更改数字并非易事。您可以使用FFmpeg来重新复用MKV,这将以正确的持续时间重写标头。
很抱歉做了长时间的介绍,但您的案例在注释的末尾进行了描述
马特罗斯卡的EBML格式:
https://github.com/ietf-wg-cellar/ebml-specification/blob/master/specification.markdown
matroska规范:
https://www.matroska.org/technical/elements.html
- mkv文件由块组成
- 每个区块都有以下结构-由这3个部分组成-ID,DATA_LENGTH,数据
ID-字段识别部分
- 计数零位直到第一个1,以字节为单位估计该段的长度,直到该字节段结束的下一部分是matroska元素ID:
示例
1f 43 b6 75
0001 1111->第一个半字节为ID确定了一个4字节的块(二进制形式的第一个1在左起第四个位置),ID是0xF43b675,这意味着集群,可以在matroska规范中查找完整的ID 0x1f43b675
44 89
01000100->第一个半字节估计ID的2字节部分(二进制形式的第一个1在左起第二个位置),ID是0x489,它意味着持续时间,在matroska规范中与0x4489 匹配
数据长度-在ID部分遵循尺寸规范之后,也是BML
计数零位直到第一个1,以估计该段的字节长度,直到该(字节)段结束的下一部分是以字节为单位的数据长度
01 00 00 00 00 17 ff 0d
0000 0001-对于第一个字节,段长度为8个字节,相关数据长度为0x17ff0d
88
1000 1000-区段长度为1字节,相关数据长度为8字节
复杂样品
00000000 4d 80 a5 47 53 74 72 65 M.GStre
0000000 8 61 6d 65 72 20 6d 61 74 amer mat
00000010 72 6f 73 6b 61 6d 75 78 roskamux
00000018 20 76 65 72 73 69 6f 6e版本
00000020 20 31 2e 31 30 2e 34 00 1.10.4。
4d 80
0100 1100-定义2字节长的ID 0xD80-表示Muxing应用程序或库
a5
1010 0101-定义一个1字节长度的块,数据区有一个0x25字节的
DATA-数据块
00000000 47 53 74 72 65 M.GStre
0000000 8 61 6d 65 72 20 6d 61 74 amer mat
00000010 72 6f 73 6b 61 6d 75 78 roskamux
00000018 20 76 65 72 73 69 6f 6e版本
00000020 20 31 2e 31 30 2e 34 00 1.10.4。
注:
- 字符串以零结尾,大小中包含以零结尾
- 数字是大端的,不需要交换,所以1000000可以看作是0f4240
参见示例
时间戳刻度:00000000 2a d7 b1 83 0f 42 40
2a
0010 1010-ID为三个字节,ID为0xAD7B1
83
1000 0011-长度为一个字节,数据长度为3
0f 42 40-数据为BE整数-1000000
持续时间:
00000000 44 89 88 41 22 85 dd 26 D.A&
0000000 8 35 c5 b5 5.
44
0100 0100-ID部分的两个字节(1位于左起第二个位置),ID为0x489,在matroska规范中查找0x4489
88
1000 1000-长度段为一个字节(左起第一个位置为1),数据长度为8字节(剩余7位)
41 22 85 dd 26 35 c5 b5
8个字节的数据,这些数据是双重类型的,给出606958.57462900004-10分6.9585746629秒(VLC播放器显示了这一次)
在C++中:__int64 durationRaw=0x412285dd2635c5b5
double durationMiliSeconds=(double*)&durationRaw