<p>A direct option to resume encoding is not available.</p>

<p>And as for manually restarting encoding, that's also not possible. Two reasons:</p>

<p>1) when transcoding to a typical container like MP4, the index is written after encoding is completed. There will be no such index in a partial file if the process died unexpectedly, and so the existing file cannot be parsed.</p>

<p>2) If you cannot accurately identify the last uncorrupted frame encoded in the partial file, your join will not be seamless.</p>

<hr>

<p>That said, there is a tedious way this can be done. The method hinges on using the <code>segment</code> muxer. You encode to MPEG-TS format but segment the output as it is being generated. Should the job fail, you examine a few attributes and resume encoding based on that data. Finally, you join all segments together.</p>

<p><strong>Step 1</strong>: Encode and segment</p>

<p>For best results, audio and video should be done separately. In fact the audio can be done without segmenting since it will encode much faster</p>

<pre><code>ffmpeg -i in.mp4 -c:a aac -vn job-audio.mp4
</code></pre>

<p>And for video</p>

<pre><code>ffmpeg -copyts -start_at_zero -ss 0 -i in.mp4 -c:v libx264 -an
       -f segment -segment_time 0.01 -segment_time_delta 1
       -muxpreload 0 -muxdelay 0 -mpegts_copyts 1
       -segment_start_number 0 -segment_list files.ffcat
job-video%d.ts
</code></pre>

<p>Each segment above will contain one GOP, so no frames in a segment rely on frames in other segments for playback.</p>

<p><strong>Step 2</strong> Identify resume point</p>

<p>Suppose the job fails while creating segment #5.</p>

<p>First, you run</p>

<pre><code>ffprobe "in.mp4" -show_entries stream=codec_type,start_time,duration -of compact
</code></pre>

<p>This will produce a readout like this</p>

<pre><code>stream|codec_type=audio|start_time=0.000000|duration=356.309333
stream|codec_type=video|start_time=0.040000|duration=356.360000
</code></pre>

<p>Note the start time for the video stream.</p>

<p>Now, run it for the first and the last (incomplete) segment</p>

<pre><code>ffprobe "job-video0.ts" -show_entries stream=codec_type,start_time,duration -of compact

stream|codec_type=video|start_time=0.080000|duration=10.000000
</code></pre>

<p>You see that there's a positive offset of 0.04 w.r.t the MP4 video stream. Let's call this the initial offset value</p>

<p>Now, for the last stream</p>

<pre><code>ffprobe "job-video5.ts" -show_entries stream=codec_type,start_time,duration -of compact

stream|codec_type=video|start_time=20.080000|duration=4.320000
</code></pre>

<p><strong>Step 3</strong> Resume encoding</p>

<p>So, now you run</p>

<pre><code>ffmpeg -copyts -start_at_zero -ss {start_time of last segment - initial offset} -i in.mp4 -c:v libx264 -an
       -f segment -segment_time 0.01 -segment_time_delta 1
       -muxpreload 0 -muxdelay 0 -mpegts_copyts 1 -initial_offset {initial offset}
       -segment_start_number {index number of last segment} -segment_list files-resume.ffcat
job-video%d.ts
</code></pre>

<p><strong>Step 4</strong> Join segments</p>

<p>You'll have multiple <code>.ffcat</code> files - from the first run and all resumed runs. Copy over the entries from all secondary runs and append them to the first file. Avoid duplication.</p>

<p>Run</p>

<pre><code>ffmpeg -f concat -i files.ffcat -i job-audio.mp4 -c copy full.mp4
</code></pre>

CC BY-SA 3.0
2016-11-04T17:40:44.697Z
to clarify, do you know there will be one GOP per segment because as it says in the docs when segment_time_delta "... is specified a key-frame will start a new segment if its PTS satisfies the relation..."?
tonyl7126
CC BY-SA 3.0
2016-11-04T17:52:04.430Z
Yes, the very low segment_time ensures that the delta rarely comes into play. I originally added that option because my initial commands included audio as well. And the format start_time in those cases isn't always the same as the video start_time. Now, it's moot.
Gyan
CC BY-SA 3.0
2016-11-04T07:54:08.280Z
2016-11-04T07:54:08.280Z
Gyan
<p>If you know the specific portion of the file that the encoding job chokes on, you can use <code>ffmpeg</code>'s <code>--ss</code> and <code>-t</code> options to pass over the choke point. You can read more about these options by looking at the tool's <a href="https://ffmpeg.org/ffmpeg.html" rel="nofollow noreferrer">documentation</a>.</p>

CC BY-SA 3.0
2016-11-04T03:50:36.317Z
let's assume failure is unpredictable i.e there is no known failure point.
tonyl7126
CC BY-SA 3.0
2016-11-04T02:11:20.900Z
2016-11-04T02:11:20.900Z
marshki
<p>Is there a common technique or some sort of strategy for restarting a failed transcoding job from where it had left off when it crashed (or stopped for whatever reason)?</p>

<p>For example, if I have a 2 hour transcoding job and it fails/crashes at 1 hour and 59 minutes, is there some way I can just do that last minutes worth of work and use the progress I already had assuming the partially transcoded file is still available?</p>

<ffmpeg><transcoding>
restart ffmpeg job from failure
tonyl7126
# restart ffmpeg job from failure

(Asked by: username_0 on 2016-11-03)

Is there a common technique or some sort of strategy for restarting a failed transcoding job from where it had left off when it crashed (or stopped for whatever reason)?

For example, if I have a 2 hour transcoding job and it fails/crashes at 1 hour and 59 minutes, is there some way I can just do that last minutes worth of work and use the progress I already had assuming the partially transcoded file is still available?

**Tags:** ffmpeg, transcoding


---

## 2 answers

### Answer by username_1 on 2016-11-04. Score: 7

A direct option to resume encoding is not available.
And as for manually restarting encoding, that's also not possible. Two reasons:
1) when transcoding to a typical container like MP4, the index is written after encoding is completed. There will be no such index in a partial file if the process died unexpectedly, and so the existing file cannot be parsed.
2) If you cannot accurately identify the last uncorrupted frame encoded in the partial file, your join will not be seamless.

That said, there is a tedious way this can be done. The method hinges on using the segment muxer. You encode to MPEG-TS format but segment the output as it is being generated. Should the job fail, you examine a few attributes and resume encoding based on that data. Finally, you join all segments together.
Step 1: Encode and segment
For best results, audio and video should be done separately. In fact the audio can be done without segmenting since it will encode much faster
ffmpeg -i in.mp4 -c:a aac -vn job-audio.mp4

And for video
ffmpeg -copyts -start_at_zero -ss 0 -i in.mp4 -c:v libx264 -an
       -f segment -segment_time 0.01 -segment_time_delta 1
       -muxpreload 0 -muxdelay 0 -mpegts_copyts 1
       -segment_start_number 0 -segment_list files.ffcat
job-video%d.ts

Each segment above will contain one GOP, so no frames in a segment rely on frames in other segments for playback.
Step 2 Identify resume point
Suppose the job fails while creating segment #5.
First, you run
ffprobe "in.mp4" -show_entries stream=codec_type,start_time,duration -of compact

This will produce a readout like this
stream|codec_type=audio|start_time=0.000000|duration=356.309333
stream|codec_type=video|start_time=0.040000|duration=356.360000

Note the start time for the video stream.
Now, run it for the first and the last (incomplete) segment
ffprobe "job-video0.ts" -show_entries stream=codec_type,start_time,duration -of compact

stream|codec_type=video|start_time=0.080000|duration=10.000000

You see that there's a positive offset of 0.04 w.r.t the MP4 video stream. Let's call this the initial offset value
Now, for the last stream
ffprobe "job-video5.ts" -show_entries stream=codec_type,start_time,duration -of compact

stream|codec_type=video|start_time=20.080000|duration=4.320000

Step 3 Resume encoding
So, now you run
ffmpeg -copyts -start_at_zero -ss {start_time of last segment - initial offset} -i in.mp4 -c:v libx264 -an
       -f segment -segment_time 0.01 -segment_time_delta 1
       -muxpreload 0 -muxdelay 0 -mpegts_copyts 1 -initial_offset {initial offset}
       -segment_start_number {index number of last segment} -segment_list files-resume.ffcat
job-video%d.ts

Step 4 Join segments
You'll have multiple .ffcat files - from the first run and all resumed runs. Copy over the entries from all secondary runs and append them to the first file. Avoid duplication.
Run
ffmpeg -f concat -i files.ffcat -i job-audio.mp4 -c copy full.mp4

> **Comments:**
> **username_0**: to clarify, do you know there will be one GOP per segment because as it says in the docs when segment_time_delta "... is specified a key-frame will start a new segment if its PTS satisfies the relation..."?  
> **username_1**: Yes, the very low segment_time ensures that the delta rarely comes into play. I originally added that option because my initial commands included audio as well. And the format start_time in those cases isn't always the same as the video start_time. Now, it's moot.  

---

### Answer by username_2 on 2016-11-04. Score: 1

If you know the specific portion of the file that the encoding job chokes on, you can use `ffmpeg`'s `--ss` and `-t` options to pass over the choke point. You can read more about these options by looking at the tool's [documentation](https://ffmpeg.org/ffmpeg.html).

> **Comments:**
> **username_0**: let's assume failure is unpredictable i.e there is no known failure point.  

---

