7
votes

I have an mp4 video file that I want to play it in iOS using avfoundation. Unfortunately, the file is not being played and unable to save into the default gallery(photos) even it has h264 video codec and aac audio codec. And it is only playable when I reencode it using ffmpeg. I want to know why the file only becomes playable after reencoding the video?

Not Playable(originalFile.mp4) vs Playable File(outputFile.mp4) Information Comparison

enter image description here

File is playable with avfoundation when these commands are being applied:

  1. 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

  2. ffmpeg -y -hide_banner -i originalFile.mp4 -f mp4 -vcodec h264 -acodec aac outputFile.mp4

File is not playable with avfoundation when this command is being applied:

  1. ffmpeg -y -hide_banner -i originalFile.mp4 -f mp4 -vcodec copy -acodec aac outputFile.mp4

originalFile.mp4 file link: https://drive.google.com/file/d/1-yZFL0EsLztMIfwU79Al6dv8gdwJyGAD/view?usp=sharing

ffprobe streams of both files are here https://www.diffchecker.com/VgZL66QB

1
How was originalFile.mp4 created? Looks like you made it with ffmpeg.llogan
@llogan Yes, the originalFile.mp4 has made by ffmpeg.Rabel Ahmed
@RabelAhmed Please show the FFmpeg commands used to create the originalFile.mp4.VC.One
@VC.One The command to create the originalFile.mp4 is unknown. We have an app where user uploaded this file for conversion. Thanks.Tahlil
@VC.One I've added more information about originalFile.mp4 and shared the file as well so that you can observe easily. Thanks.Rabel Ahmed

1 Answers

0
votes

I tried to dive into that, and I am blocked at this call stack:

#0  0x00007fff24e0d82e in PullParamSetSPS ()
#1  0x00007fff24e0f357 in FigH264Bridge_GetSPSIsInterlaced ()
#2  0x00007fff27fdc473 in mv_CheckIfVideoPresentable ()
...

These functions are from CoreMedia framework.

I guess there is something with SPS in this video (https://www.quora.com/What-are-SPS-and-PPS-in-video-codecs).

The framework calls mv_CheckIfVideoPresentable to check if the video is "valid".

This function copies a piece of data from a video and this pieces are:

outputFile.mp4

6764001F ACD940C0 126C0440 00000040 00000C83 C60C6580
originalFile.mp4

6764001F AC1B2940 C024D80B 50501064 00000004 000000CB 
898000B3 620001E8 48FC638C 4C00059B 10000F42 47E31C28

Then PullParamSetSPS uses this data to calculate something, and FigH264Bridge_GetSPSIsInterlaced returns 1 or 0 depending on that data.

So you need to figure out what SPS is, what these pieces of data are. And you could set breakpoints to these functions to see what is going on there.

I used this code to trigger the breakpoints:

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)

I hope this helps