untrunc icon indicating copy to clipboard operation
untrunc copied to clipboard

Adding keyframe to recovered video with FFmpeg truncates duration to reference duration

Open BaronKhan opened this issue 6 years ago • 7 comments

I've managed to successfully recover a corrupted MP4 file. Unfortunately the first 7 seconds for the video do not work. I found that this is due to the first keyframe missing. Any ideas how to fix this?

I've tried running the mp4 through ffmpeg with the -force_key_frames options. Unfortunately, this causes the output to have the same length as the reference video which was used in untrunc to recover the corrupted video (which is much shorter than the corrupted video). It seems you can't insert a keyframe without re-encoding the video but this causes issues with length.

BaronKhan avatar Dec 16 '18 19:12 BaronKhan

Hardly believable. Are you sure that the keyframe is present in the corrupted file and the header of the file is not damaged? More likely that the few frames were skipped during recording...

SuslikV avatar Dec 17 '18 18:12 SuslikV

I am unable to confirm whether the first frame is a keyframe (apologies, I jumped the gun with the title of the issue). I managed to fix this anyway by forcing saveKeyframes() to insert one at frame 0 (1) even if it didn't have one to begin with. This successfully fixed my issue.

The main issue here is: it should be possible to add a keyframe using FFmpeg anyway, but currently this has issues. Actually, a lot of processing on the recovered video using FFmpeg is not possible because the duration of the output from FFmpeg gets truncated to the length of the reference video used to recover it.

There must be some sort of atom that is not being updated (or is copied from the reference with a field set to the duration of the reference) that remains in the recovered video, and FFmpeg is using this for the duration of the output.

BaronKhan avatar Dec 17 '18 19:12 BaronKhan

You can try to extract raw streams from the recovered file to use them in your completely new file.

SuslikV avatar Dec 17 '18 19:12 SuslikV

I had a similar problem, where Codec::isKeyframe() always returned false. I was able to fix this for my files, does it work for yours too?

anthwlock avatar Dec 23 '18 08:12 anthwlock

Sorry for the necroposting, but I've had a similar problem, and if we're lucky you should be able to reproduce it as well. Unfortunately I have to tell you the whole story so it will be long. I use Gentoo Linux, so latest version of everything. I've been having this problem with downloading a youtube live video (one of those 24/7 music streams) with youtube-dl. youtube-dl endlessly downloads the live stream until you hit ^C. At this point, two things can happen:

  1. ffmpeg is interrupted before it can write the moov atom to the file - broken and useless video
  2. ffmpeg exits normally, you have a healthy/reference file. I tried fixing a 4-hours long 1) video with a 1-minute 2) video. The results are that mpv, my media player can actually play the whole fixed video like a charm. The problem, however, is that when stream-copying with ffmpeg (ffmpeg -i fixed.mp4 -c copy reallyfixed.mp4) it actually truncates the video at reference duration and refuses to go forward, even though no warnings are given. The only one is cur_dts is invalid st:0 (0) [init:1 i_done:0 finish:0] . I've actually discovered there's something called an "edit list" that tells ffmpeg the duration of the video. The magic option, that makes ffmpeg ignore them, is -ignore_editlist 1 . With this option, ffmpeg succesfully stream-copies the entire video. So maybe these edit lists are copied straight from the reference to the broken file which results in this behaviour.

ElDavoo avatar Feb 08 '20 23:02 ElDavoo

At the moment only for the codec avc1 I am able to detect a keyfame. For the other codec I will need to look up the documentation.

About the edit lists, in edts atom, I should probably just remove them. I will make a test, can you provide a sample?

ponchio avatar Feb 09 '20 13:02 ponchio

As I said, you can create new samples by pressing ^C at the right time with youtube-dl. I've done it for you anyway https://filebin.net/x4c1zjruhv7q7au4

ElDavoo avatar Feb 09 '20 16:02 ElDavoo