Konubinix' opinionated web of thoughts

Phasher Crashes With Some Videos

Fleeting

phasher crashes with some videos with ffmpeg, ffprobe

phasher $file 2>&1
generating sprite screenshot: decoding image: image: unknown format

Debugging, I realized that the command that caused this issue was ffmpeg -y -ss 3.6285800000000004 -i $file -frames:v 1 -vf scale=160:-2 -c:v bmp -f rawvideo -

Trying this command, I get

ffmpeg -y -ss 3.6285800000000004 -i $file -frames:v 1 -vf scale=160:-2 -c:v bmp -f rawvideo - | wc -c
0

While with another time, I get.

ffmpeg -y -ss 3.5 -i $file -frames:v 1 -vf scale=160:-2 -c:v bmp -f rawvideo - | wc -c
136374

That’s strange, let’s check the duration of the video

ffmpeg -i $file 2>&1| grep Duration
  Duration: 00:00:03.97, start: 0.000000, bitrate: 1580 kb/s

The video file is long enough.

When you don’t get an output file, ffmpeg probably cannot seek to that position, or there is no video information at that position.

This means that the file could be broken, or the duration is just incorrectly reported from the container.

Try to play the file and see if it really works until 900 seconds.

https://superuser.com/questions/746952/ffmpeg-fails-to-generate-screenshots

Let’s check the duration of the video stream. I could not find an elegant way of doing so.

ffprobe -v error -show_format -show_streams -of json $file|jq -r '.streams[]|"\(.codec_type): \(.duration)"'
ffprobe -v error -show_format -show_streams -of json $file|jq -r '.format|"format: \(.duration)"'
video: 3.533333
audio: 3.968000
format: 3.968000

Hmmmm, the video stream is shorter than the audio one. That explains why I could get a screenshot at the time 3.5s but not at time 3.55s.

I don’t want to keep the end of those videos, so I will trim them.

duration="$(ffprobe -v error -show_format -show_streams -of json $file|jq -r '.streams[]|select(.codec_type == "video").duration')"
newfile="/tmp/a.mp4"
ffmpeg -v error -y -i $file -c:a copy -c:v copy -to "${duration}" "${newfile}"

ffprobe -v error -show_format -show_streams -of json $newfile|jq -r '.streams[]|"\(.codec_type): \(.duration)"'
ffprobe -v error -show_format -show_streams -of json $newfile|jq -r '.format|"format: \(.duration)"'
video: 3.533333
audio: 3.541000
format: 3.542000
phasher --quiet /tmp/a.mp4
c88a7fc32aea6a26

Great !!