MP4 碎片无法在 ffplay/QuickTime/Safari 中播放,但在 VLC 中播放
Fragmented MP4 not playing in ffplay/QuickTime/Safari, but in VLC
我使用 VideoToolbox 和 CoreMedia 在 Swift 中编码了一个 fMP4 视频 (HEVC)。生成的MP4碎片只能在VLC中播放
我用来编写 fMP4 的库是这个 GitHub-Project 的 HEVC-adapted 版本:https://github.com/krad/morsel
编码写入过程:
- VideoToolbox:从相机编码
SampleBuffer
(VTCompressionSession
,如 WWDC 2014 Session 513 中所述)
- 使用
CoreMedia
-函数(例如 CMVideoFormatDescriptionGetHEVCParameterSetAtIndex
、CMVideoFormatDescriptionGetDimensions
)获取编码流元数据。我是直接把CMFormatDescriptionGetExtension(description, extensionKey: "SampleDescriptionExtensionAtoms" as CFString)["hvcC"]
的内容写到hvcC框里。这个框明显写对了,当我修改mp4的框的一位时,QuickTime报错。
- 我将示例缓冲区数据附加到 morsel-library,它管理碎片并创建 moof 和 mdat 原子。
结果文件可以在 VLC 中播放,当我只是让播放“运行”而不做任何事情时。当我在 VLC 中滚动时间时,VLC 崩溃并且播放停止。
它在 Safari 和 QuickTime 中也有点“可播放”(没有显示错误消息,播放 window 打开并显示正确的文件长度,我什至可以更改播放时间 / play/pause,但没有显示视频。window 仍然是空的。这就是我遇到的问题。我需要在 Safari 和 QuickTime 中获取 fMP4 运行ning。
文件在 ffplay 中根本无法播放(使用 ffmpeg 转换时出现同样的问题)。显示播放时间的行仍然是 nan M-V: nan fd= 0 aq= 0KB vq= 0KB sq= 0B f=0/0
,没有错误消息。播放只是没有开始。
使用 ffplay 播放文件时,这是输出:
ffplay version 4.3 Copyright (c) 2003-2020 the FFmpeg developers
built with Apple clang version 11.0.3 (clang-1103.0.32.62)
configuration: --prefix=/usr/local/Cellar/ffmpeg/4.3_2 --enable-shared --enable-pthreads --enable-version3 --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libdav1d --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librtmp --enable-libspeex --enable-libsoxr --enable-videotoolbox --disable-libjack --disable-indev=jack
libavutil 56. 51.100 / 56. 51.100
libavcodec 58. 91.100 / 58. 91.100
libavformat 58. 45.100 / 58. 45.100
libavdevice 58. 10.100 / 58. 10.100
libavfilter 7. 85.100 / 7. 85.100
libavresample 4. 0. 0 / 4. 0. 0
libswscale 5. 7.100 / 5. 7.100
libswresample 3. 7.100 / 3. 7.100
libpostproc 55. 7.100 / 55. 7.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'test.mp4':
Metadata:
major_brand : mp42
minor_version : 1
compatible_brands: mp41mp42isomhlsf
creation_time : 2020-08-03T20:41:08.000000Z
Duration: N/A, bitrate: N/A
Stream #0:0(und): Video: hevc (Main) (hvc1 / 0x31637668), yuv420p(tv), 1920x1080, SAR 1:1 DAR 16:9, 1000000000.00 tbr, 1000000000.00 tbn, 1000000000.00 tbc (default)
Metadata:
creation_time : 2020-08-03T20:41:08.000000Z
handler_name : video
nan M-V: nan fd= 0 aq= 0KB vq= 0KB sq= 0B f=0/0
我的文件有这样的结构:
ftyp
moov
mvhd
trak
tkhd
mdia
mdhd
hdlr
minf
vmhd
dinf
dref
stbl
stsd
stts
stsc
stsz
stco
mvex
trex
moof-(1)
mdat
moof-(2)
mdat
...
我要创建的结果文件应该类似于此 HLS 播放列表中提供的 fMP4:(示例:https://developer.apple.com/streaming/examples/advanced-stream-hevc.html, Playlist: https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_adv_example_hevc/master.m3u8)
该文件具有以下结构:
ftyp
moov
mvhd
trak
tkhd
mdia
mdhd
hdlr
minf
vmhd
dinf
dref
stbl
stsd
stts
stsc
stsz
stco
trak (same structure as above)
mvex
trex
moof-(1)
mdat
moof-(2)
mdat
...
这个来自 Apple 的文件在 ffmpeg 和 QuickTime/Safari 中完美播放。除了第二个 trak
原子外,它具有相同的结构。
“好”文件是:https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_adv_example_hevc/v14/main.mp4(它用于 HLS 播放列表,我用 curl 下载了它)
“坏”文件是:https://www.transfernow.net/ddl/fmp4_bad(link 应该可以,刚刚测试过:))。视频显示一张缓慢旋转的 sheet 纸。
有什么建议是我的文件有什么问题吗?
提前致谢!
moof->traf->trun->entries->duration中的duration错误
moof->traf->tfhd->default_sample_duration也是如此。
它看起来更像是一个时间戳,但它应该是帧持续时间。
每个片段只有一个样本,这是合法的但非常浪费。
我使用 VideoToolbox 和 CoreMedia 在 Swift 中编码了一个 fMP4 视频 (HEVC)。生成的MP4碎片只能在VLC中播放
我用来编写 fMP4 的库是这个 GitHub-Project 的 HEVC-adapted 版本:https://github.com/krad/morsel
编码写入过程:
- VideoToolbox:从相机编码
SampleBuffer
(VTCompressionSession
,如 WWDC 2014 Session 513 中所述) - 使用
CoreMedia
-函数(例如CMVideoFormatDescriptionGetHEVCParameterSetAtIndex
、CMVideoFormatDescriptionGetDimensions
)获取编码流元数据。我是直接把CMFormatDescriptionGetExtension(description, extensionKey: "SampleDescriptionExtensionAtoms" as CFString)["hvcC"]
的内容写到hvcC框里。这个框明显写对了,当我修改mp4的框的一位时,QuickTime报错。 - 我将示例缓冲区数据附加到 morsel-library,它管理碎片并创建 moof 和 mdat 原子。
结果文件可以在 VLC 中播放,当我只是让播放“运行”而不做任何事情时。当我在 VLC 中滚动时间时,VLC 崩溃并且播放停止。
它在 Safari 和 QuickTime 中也有点“可播放”(没有显示错误消息,播放 window 打开并显示正确的文件长度,我什至可以更改播放时间 / play/pause,但没有显示视频。window 仍然是空的。这就是我遇到的问题。我需要在 Safari 和 QuickTime 中获取 fMP4 运行ning。
文件在 ffplay 中根本无法播放(使用 ffmpeg 转换时出现同样的问题)。显示播放时间的行仍然是 nan M-V: nan fd= 0 aq= 0KB vq= 0KB sq= 0B f=0/0
,没有错误消息。播放只是没有开始。
使用 ffplay 播放文件时,这是输出:
ffplay version 4.3 Copyright (c) 2003-2020 the FFmpeg developers
built with Apple clang version 11.0.3 (clang-1103.0.32.62)
configuration: --prefix=/usr/local/Cellar/ffmpeg/4.3_2 --enable-shared --enable-pthreads --enable-version3 --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libdav1d --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librtmp --enable-libspeex --enable-libsoxr --enable-videotoolbox --disable-libjack --disable-indev=jack
libavutil 56. 51.100 / 56. 51.100
libavcodec 58. 91.100 / 58. 91.100
libavformat 58. 45.100 / 58. 45.100
libavdevice 58. 10.100 / 58. 10.100
libavfilter 7. 85.100 / 7. 85.100
libavresample 4. 0. 0 / 4. 0. 0
libswscale 5. 7.100 / 5. 7.100
libswresample 3. 7.100 / 3. 7.100
libpostproc 55. 7.100 / 55. 7.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'test.mp4':
Metadata:
major_brand : mp42
minor_version : 1
compatible_brands: mp41mp42isomhlsf
creation_time : 2020-08-03T20:41:08.000000Z
Duration: N/A, bitrate: N/A
Stream #0:0(und): Video: hevc (Main) (hvc1 / 0x31637668), yuv420p(tv), 1920x1080, SAR 1:1 DAR 16:9, 1000000000.00 tbr, 1000000000.00 tbn, 1000000000.00 tbc (default)
Metadata:
creation_time : 2020-08-03T20:41:08.000000Z
handler_name : video
nan M-V: nan fd= 0 aq= 0KB vq= 0KB sq= 0B f=0/0
我的文件有这样的结构:
ftyp
moov
mvhd
trak
tkhd
mdia
mdhd
hdlr
minf
vmhd
dinf
dref
stbl
stsd
stts
stsc
stsz
stco
mvex
trex
moof-(1)
mdat
moof-(2)
mdat
...
我要创建的结果文件应该类似于此 HLS 播放列表中提供的 fMP4:(示例:https://developer.apple.com/streaming/examples/advanced-stream-hevc.html, Playlist: https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_adv_example_hevc/master.m3u8) 该文件具有以下结构:
ftyp
moov
mvhd
trak
tkhd
mdia
mdhd
hdlr
minf
vmhd
dinf
dref
stbl
stsd
stts
stsc
stsz
stco
trak (same structure as above)
mvex
trex
moof-(1)
mdat
moof-(2)
mdat
...
这个来自 Apple 的文件在 ffmpeg 和 QuickTime/Safari 中完美播放。除了第二个 trak
原子外,它具有相同的结构。
“好”文件是:https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_adv_example_hevc/v14/main.mp4(它用于 HLS 播放列表,我用 curl 下载了它)
“坏”文件是:https://www.transfernow.net/ddl/fmp4_bad(link 应该可以,刚刚测试过:))。视频显示一张缓慢旋转的 sheet 纸。
有什么建议是我的文件有什么问题吗? 提前致谢!
moof->traf->trun->entries->duration中的duration错误
moof->traf->tfhd->default_sample_duration也是如此。
它看起来更像是一个时间戳,但它应该是帧持续时间。
每个片段只有一个样本,这是合法的但非常浪费。