我在上一个帖子『Golang 的 http.DetectContentType 有更好的替代实现吗?』求问了 Golang 下面对于不同文件头识别的开源库,有 V 友回复了filetype这个库,但是我最后使用了mimetype这个库的解决方案。
mimetype能够正确把视频的 mimetype 识别成 video/mp4,但是filetype这个库却识别出来的是 video/quicktime 。
然后我在上面的帖子也 append 了一下让我困惑的问题,就是我接着用 ffprobe 查看视频的编码信息,输出的是 H.264 ,封装格式如下:
format_name=mov,mp4,m4a,3gp,3g2,mj2
format_long_name=QuickTime / MOV
最后我用 Mac 的 Finder 查看,显示的又是 MPEG-4 影片,完全糊涂了,这意味着这个视频是先用用 mov 封装,再用 mp4 进行封装的吗?
本人对视频编解码相关知识的了解非常基础,基本处于懵懵懂懂的状态,Google 了好久都没有找到对于 format_name 这个字段的多个值的具体解释。
求 V 友解惑。
1
wy315700 2021-09-13 11:49:09 +08:00 1
H.264 是视频编码,类似的还有 h265 。
mov 和 mp4 是视频文件格式,类似的还有 mkv,flv 。 一个视频文件里可以包含多个 H.264 视频和多个音频数据。。 mov 和 mp4 其实是一种东西,格式都一样的。。 |
2
ysc3839 2021-09-13 11:50:21 +08:00 1
> The MP4 container is derived from Apple QuickTime (MOV).
https://www.quora.com/What-is-the-main-difference-between-MOV-and-MP4-files |
3
seki 2021-09-13 11:52:12 +08:00 1
|
4
JerryCha 2021-09-13 11:56:34 +08:00
你去看 flv 的也是 H.264
ts 和 m2ts 里面也有 H.264 惊不惊喜 意不意外? |
5
xlsepiphone OP |
6
xlsepiphone OP mediainfo 输出如下
``` General Complete name : /Users/言叶之庭.mp4 Format : MPEG-4 Format profile : Base Media Codec ID : isom (isom) File size : 1.01 GiB Duration : 46 min 3 s Overall bit rate mode : Variable Overall bit rate : 3 130 kb/s Encoded date : UTC 2018-11-17 15:06:54 Tagged date : UTC 2018-11-17 15:06:54 Video ID : 1 Format : AVC Format/Info : Advanced Video Codec Format profile : High@L4 Format settings : CABAC / 4 Ref Frames Format settings, CABAC : Yes Format settings, Reference frames : 4 frames Codec ID : avc1 Codec ID/Info : Advanced Video Coding Duration : 46 min 3 s Bit rate : 3 000 kb/s Maximum bit rate : 20.6 Mb/s Width : 1 920 pixels Height : 1 080 pixels Display aspect ratio : 16:9 Frame rate mode : Variable Frame rate : 23.976 FPS Minimum frame rate : 23.810 FPS Maximum frame rate : 24.390 FPS Color space : YUV Chroma subsampling : 4:2:0 Bit depth : 8 bits Scan type : Progressive Bits/(Pixel*Frame) : 0.060 Stream size : 989 MiB (96%) Writing library : x264 core 148 r2597+52 4ed4a81 xiaowan [8-bit@all X86_64] Encoding settings : cabac=1 / ref=4 / deblock=1:1:1 / analyse=0x3:0x133 / me=umh / subme=10 / psy=1 / fade_compensate=0.00 / psy_rd=0.30:0.00 / mixed_ref=1 / me_range=24 / chroma_me=1 / trellis=2 / 8x8dct=1 / cqm=0 / deadzone=21,11 / fast_pskip=1 / chroma_qp_offset=-2 / threads=12 / lookahead_threads=1 / sliced_threads=0 / nr=0 / decimate=1 / interlaced=0 / bluray_compat=0 / constrained_intra=0 / fgo=0 / bframes=3 / b_pyramid=2 / b_adapt=2 / b_bias=0 / direct=3 / weightb=1 / open_gop=0 / weightp=2 / keyint=240 / keyint_min=1 / scenecut=60 / intra_refresh=0 / rc_lookahead=60 / rc=2pass / mbtree=1 / bitrate=3000 / ratetol=1.0 / qcomp=0.50 / qpmin=0:0:0 / qpmax=69:69:69 / qpstep=4 / cplxblur=20.0 / qblur=0.5 / ip_ratio=1.40 / aq=2:0.80 / aq-sensitivity=10.00 / aq-factor=1.00:1.00:1.00 / aq2=0 / aq3=0 Encoded date : UTC 2018-11-17 14:02:01 Tagged date : UTC 2018-11-17 15:07:04 Color range : Limited Matrix coefficients : BT.709 Codec configuration box : avcC Audio ID : 2 Format : AAC LC Format/Info : Advanced Audio Codec Low Complexity Codec ID : mp4a-40-2 Duration : 46 min 3 s Bit rate mode : Variable Bit rate : 125 kb/s Maximum bit rate : 262 kb/s Channel(s) : 6 channels Channel layout : C L R Ls Rs LFE Sampling rate : 48.0 kHz Frame rate : 46.875 FPS (1024 SPF) Compression mode : Lossy Stream size : 41.0 MiB (4%) Encoded date : UTC 2018-11-17 13:37:54 Tagged date : UTC 2018-11-17 15:07:04 ``` |
7
xylophone21 2021-09-13 12:05:31 +08:00
ffmpeg
|
8
siguretto 2021-09-13 12:07:13 +08:00
最简单的方法是判断头部字节 ftyp,mov 是 ftypqt,mp4 是 ftypmp4 。
|
9
xlsepiphone OP @siguretto #8
xxd /Users/言叶之庭.mp4 | head 00000000: 0000 0014 6674 7970 6973 6f6d 0000 0001 ....ftypisom.... 00000010: 6973 6f6d 001b 04be 6d6f 6f76 0000 006c isom....moov...l 00000020: 6d76 6864 0000 0000 d815 df0e d815 df0e mvhd............ 00000030: 0000 0258 0019 4dc0 0001 0000 0100 0000 ...X..M......... 00000040: 0000 0000 0000 0000 0001 0000 0000 0000 ................ 00000050: 0000 0000 0000 0000 0001 0000 0000 0000 ................ 00000060: 0000 0000 0000 0000 4000 0000 0000 0000 ........@....... 00000070: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000080: 0000 0000 0000 0003 0000 0015 696f 6473 ............iods 00000090: 0000 0000 1007 004f ffff 2a15 ff00 11d3 .......O..*..... |
10
xlsepiphone OP @siguretto #8 fty pisom 是什么鬼。。。
|
11
siguretto 2021-09-13 12:09:20 +08:00
在我理解,mov 是兼容 mp4 的,所里两个库得到的 mimetype 不一样也很正常。video/mp4 是从兼容性考虑,video/quicktime 则是更加准确。
|
12
siguretto 2021-09-13 12:14:44 +08:00 1
关于 iso,可以看看 wiki: https://en.wikipedia.org/wiki/ISO/IEC_base_media_file_format
可以这么想,iso 把 mov 标准化了,mp4 又采纳了 iso 标准,所以就是 mov -> iso -> mp4 |
13
mikewang 2021-09-13 12:17:44 +08:00 via iPhone 1
mov 是 Apple 的定标准,mp4 来自于 mov,用是 ISO 的标准。它们的格式类似。就像 webm 来自于 mkv,格式类似但有着不同的标准。
大多数情况播放器 mov 和 mp4 可以互相兼容,视频编码一样的话。mimetype 不一致关系也不大。 使用 ffprobe 来看,mov 格式的 major_brand 是 qt ( QuickTime ) |
14
lostvincent 2021-09-13 14:01:41 +08:00 4
首先,你要区分视频流和封装
h.264 是视频流的格式 mp4 是封装格式 这两个是可以同时存在的,简单来说就是一个是外包装,一个是内容 其次,你要明确下你需要的是视频流还是封装的格式。 看帖子内容,我假设你需要的是:封装格式 在没有具体文件的情况下,你描述的情况是可能存在的 类比现实情况,就是你拿到了一个水果礼物盒( mp4 ),里面装着一个柑橘( h.264 ) mimetype 检测之后,告诉你这是一个水果礼物盒( video/mp4 ) filetype 检测后,告诉你这是一个橘子礼物盒( video/quicktime ) ffprobe 告诉你这是一个柑橘( h.264 ) 一些关于 isom 的东西 Some references: https://forum.doom9.org/showthread.php?p=1664561#post1664561 https://forum.doom9.org/showthread.php?p=1827483#post1827483 相关行业标准文档: Document: ISO/IEC 14496-12 太长不看版: 都说的没错,只不过对象和详细程度不同 |
15
expy 2021-09-13 14:15:47 +08:00
容器跟编码的区别,H264/MPEG4/AVC 是同一个编码。
MP4 是容器,可以封装各种编码的视频流和音频流(H.264/H.265/AV1/AAC/FLAC/MP3/Opus)。 |
16
tsanie 2021-09-13 14:50:41 +08:00
抛开标题,我觉得这个文件比较奇怪。'ftypisom'为什么会被 ffprobe 和 filetype 库识别成 QuickTime File,果子的 QuickTime 格式规范上写的 major_brand 不是一定要'qt '么……
|
17
huangmingyou 2021-09-13 14:55:17 +08:00
封装和内容编码是两个独立概念。 内容编码可以比喻成英语书或者中文书,封装可以理解成顺风或者邮政快递。可以随便组合啊。
|
18
CEBBCAT 2021-09-13 16:00:50 +08:00 via Android 1
|
19
mikewang 2021-09-13 16:59:24 +08:00 1
#14 @lostvincent
水果礼物盒和橘子礼物盒的比喻可能不太准确,mov 和 mp4 应该是平级的,他们之间还存在一些微小的差别。 例如: video/quicktime 支持封装 ALAC 无损音频,video/mp4 不能。 video/mp4 支持封装 AV1 编码的视频,video/quicktime 不能。 上面都在讨论视频编码的问题,我觉得这个问题重点不在这里。 macOS 文件简介显示的「 MPEG-4 影片」指的是「 MPEG-4 Part 14 」定义的容器格式,不是指「 MPEG-4 Part 2 」定义的 MPEG-4 编码。 可以查看一个封装 HEVC 的 mp4 文件,简介依然为「 MPEG-4 影片」。 严格意义上讲,只有 major_brand 为 qt 时,文件才是 video/quicktime 。 filetype 库,将 #9 的文件识别为 video/quicktime 是有问题的,这显然是个 video/mp4 文件。 这个问题已经有人提过了,同一个文件多次执行,得到结果不一样 XD https://github.com/h2non/filetype/issues/64 ![]( https://ae01.alicdn.com/kf/Hdd619c78118648b1a0d5550c16c80aa3x.png) |
20
xlsepiphone OP @mikewang #19
``` Metadata: major_brand : isom minor_version : 1 compatible_brands: isom creation_time : 2018-11-17T15:06:54.000000Z ``` major_brand 是 isom,看完你们的回复,懵了,感觉视频编码与封装这块,太不直白了,这么多历史渊源。 |
21
lostvincent 2021-09-13 17:28:39 +08:00
@mikewang 多谢指正,quicktime 这部分不是了解太多,对表达失误带来的误解,表示抱歉
关于 ISO/IEC 14496-12 是因为我手边之前研究的是这份,也只看过这份,所以想了下,没删掉-12 @xlsepiphone 你要了解的话,看下 mp4 的 ftyp 这个东西就够了 |
22
litesoar 2021-09-13 17:48:36 +08:00
应该可以吧。
h.264 是视频编码格式 mp4 和 mov 是视频封装格式,都能采用 h264 编码。 |
23
xylophone21 2021-09-13 18:20:57 +08:00
score 越大,可能性越高
```c static int mov_probe(const AVProbeData *p) { int64_t offset; uint32_t tag; int score = 0; int moov_offset = -1; /* check file header */ offset = 0; for (;;) { int64_t size; int minsize = 8; /* ignore invalid offset */ if ((offset + 8ULL) > (unsigned int)p->buf_size) break; size = AV_RB32(p->buf + offset); if (size == 1 && offset + 16 <= (unsigned int)p->buf_size) { size = AV_RB64(p->buf+offset + 8); minsize = 16; } else if (size == 0) { size = p->buf_size - offset; } if (size < minsize) { offset += 4; continue; } tag = AV_RL32(p->buf + offset + 4); switch(tag) { /* check for obvious tags */ case MKTAG('m','o','o','v'): moov_offset = offset + 4; case MKTAG('m','d','a','t'): case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */ case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */ case MKTAG('f','t','y','p'): if (tag == MKTAG('f','t','y','p') && ( AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ') || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ') )) { score = FFMAX(score, 5); } else { score = AVPROBE_SCORE_MAX; } break; /* those are more common words, so rate then a bit less */ case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */ case MKTAG('w','i','d','e'): case MKTAG('f','r','e','e'): case MKTAG('j','u','n','k'): case MKTAG('p','i','c','t'): score = FFMAX(score, AVPROBE_SCORE_MAX - 5); break; case MKTAG(0x82,0x82,0x7f,0x7d): case MKTAG('s','k','i','p'): case MKTAG('u','u','i','d'): case MKTAG('p','r','f','l'): /* if we only find those cause probedata is too small at least rate them */ score = FFMAX(score, AVPROBE_SCORE_EXTENSION); break; } if (size > INT64_MAX - offset) break; offset += size; } if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) { /* moov atom in the header - we should make sure that this is not a * MOV-packed MPEG-PS */ offset = moov_offset; while (offset < (p->buf_size - 16)) { /* Sufficient space */ /* We found an actual hdlr atom */ if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') && AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') && AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) { av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n"); /* We found a media handler reference atom describing an * MPEG-PS-in-MOV, return a * low score to force expanding the probe window until * mpegps_probe finds what it needs */ return 5; } else { /* Keep looking */ offset += 2; } } } return score; } ``` |
24
msg7086 2021-09-13 18:50:06 +08:00 via Android 1
Mp4 isom mov 本来就是一家人。
顺便提一个有趣的小知识,avi 和 wav 也是一家人,都是基于 riff 。 视频音频方面的水本来就很深,一大堆公司在搞,各种组织在定自己的标准,然后各种标准又在借鉴别的标准。 然后甚至有时候还会出现软件输出的文件不那么标准的情况,然后软件也要一步步迭代完善。 很多格式还在不停发展变化,比如说 opus 或 flac in MP4 还没完全搞明白,各家软件还没支持,标准也还在草案阶段一点点推进,等哪天定稿了再逐步给各大工具平台推,再一点点开始普及,等等。 本来已经成熟的格式也在不停变化,比如前段时间 NHK 搞了 24 声道的 AAC,一直无人支持,后来有一天我去问了,然后给了个音轨样本以后他们才一点点开始实现功能。 这方面的浑水要趟的话得要有一些心理准备的。 |
25
thunderw 2021-09-14 08:58:58 +08:00
https://blog.csdn.net/pirateleo/article/details/7583321
这里面说的好像比较清楚。可以指定一种主格式,另外声明还兼容哪些格式。 所以你这个具体的文件就是 isom 兼容 moov 。约等于既是 mp4 又是 mov 。 参阅: http://www.ftyps.com |