我有一个 mp4 视频文件,我想使用 avfoundation 在 iOS 中播放它。不幸的是,该文件没有被播放并且无法保存到默认图库(照片)中,即使它有 h264 视频编解码器和 瑞声 音频编解码器。它只有在我使用 ffmpeg 重新编码时才能播放。我想知道为什么文件只有在重新编码视频后才能播放?
Not Playable(originalFile.mp4) vs Playable File(outputFile.mp4)信息对比
应用这些命令时,文件可通过 avfoundation 播放:
ffmpeg -y -hide_banner -i originalFile.mp4 -f mp4 -vcodec h264 -vf scale=out_color_matrix=bt709 -color_primaries bt709 -color_trc bt709 -colorspace bt709 -b:v 5703k -acodec aac -b:a 249k outputFile.mp4
ffmpeg -y -hide_banner -i originalFile.mp4 -f mp4 -vcodec h264 -acodec aac outputFile.mp4
应用此命令时,无法使用 avfoundation 播放文件:
ffmpeg -y -hide_banner -i originalFile.mp4 -f mp4 -vcodec copy -acodec aac outputFile.mp4
originalFile.mp4 文件链接: https://drive.google.com/file/d/1-yZFL0EsLztMIfwU79Al6dv8gdwJyGAD/view?usp=sharing
两个文件的 ffprobe 流都在这里
https://www.diffchecker.com/VgZL66QB
最佳答案
我试图深入研究,但我被这个调用堆栈阻塞了:
#0 0x00007fff24e0d82e in PullParamSetSPS ()
#1 0x00007fff24e0f357 in FigH264Bridge_GetSPSIsInterlaced ()
#2 0x00007fff27fdc473 in mv_CheckIfVideoPresentable ()
...
这些函数来自CoreMedia
框架。我猜这个视频(https://www.quora.com/What-are-SPS-and-PPS-in-video-codecs)中有一些关于 SPS 的内容。
框架调用
mv_CheckIfVideoPresentable
检查视频是否“有效”。此函数从视频中复制一段数据,这些数据是:
outputFile.mp4
6764001F ACD940C0 126C0440 00000040 00000C83 C60C6580
originalFile.mp4
6764001F AC1B2940 C024D80B 50501064 00000004 000000CB
898000B3 620001E8 48FC638C 4C00059B 10000F42 47E31C28
然后PullParamSetSPS
使用这些数据来计算,FigH264Bridge_GetSPSIsInterlaced
根据该数据返回 1 或 0。所以你需要弄清楚SPS是什么,这些数据是什么。您可以为这些函数设置断点以查看那里发生了什么。
我使用这段代码来触发断点:
let good = AVURLAsset(url: Bundle.main.url(forResource: "outputFile", withExtension: "mp4")!)
print(good.isPlayable)
let bad = AVURLAsset(url: Bundle.main.url(forResource: "originalFile", withExtension: "mp4")!)
print(bad.isPlayable)
我希望这有帮助
关于ios - 在 iOS 中无法使用 avfoundation 播放特定的 MP4 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62508983/