Monday, October 27, 2014

Gotcha of the Day: Adding an audio stream to a video which Handbrake refuses to process

I'm using handbrake to convert flv videos to various formats on the fly. It's been working exceedingly well, that is until I tried to process a video and hit this error:

$ /usr/local/bin/HandBrakeCLI -i special.flv  -o blank.m4v --preset 'iPhone & iPod Touch'
[11:12:31] hb_init: starting libhb thread
HandBrake svn4582 (2012040901) - Linux i686 - http://handbrake.fr
2 CPUs detected
Opening blank.flv...
[11:12:31] hb_scan: path=blank.flv, title_index=1
libbluray/bdnav/index_parse.c:157: indx_parse(): error opening blank.flv/BDMV/index.bdmv
libbluray/bluray.c:1471: nav_get_title_list(blank.flv) failed (0xb6300490)
[11:12:31] bd: not a bd - trying as a stream/file instead
libdvdnav: Using dvdnav version 4.1.3
libdvdread: Encrypted DVD support unavailable.
libdvdnav:DVDOpenFileUDF:UDFFindFile /VIDEO_TS/VIDEO_TS.IFO failed
libdvdnav:DVDOpenFileUDF:UDFFindFile /VIDEO_TS/VIDEO_TS.BUP failed
libdvdread: Can't open file VIDEO_TS.IFO.
libdvdnav: vm: failed to read VIDEO_TS.IFO
[11:12:31] dvd: not a dvd - trying as a stream/file instead
Input #0, flv, from 'blank.flv':
  Metadata:
    canSeekToEnd    : true
    creationdate    : Thu Oct 23 11:12:12 2014
    Encoded_By      : Sorenson Squeeze
    Encoded_With    : Sorenson Squeeze
  Duration: 00:00:04.03, start: 0.000000, bitrate: 839 kb/s
    Stream #0.0: Video: vp6f, yuv420p, 480x360, 839 kb/s, 29 tbr, 1k tbn, 1k tbc
[11:12:31] scan: decoding previews for title 1
[11:12:31] scan: 10 previews, 480x360, 29.000 fps, autocrop = 0/0/0/0, aspect 1.33:1, PAR 1:1
[11:12:31] scan: title (0) job->width:480, job->height:352
[11:12:31] libhb: scan thread found 1 valid title(s)
+ title 1:
  + stream: blank.flv
  + duration: 00:00:04
  + size: 480x360, pixel aspect: 1/1, display aspect: 1.33, 29.000 fps
  + autocrop: 0/0/0/0
  + chapters:
    + 1: cells 0->0, 0 blocks, duration 00:00:04
  + audio tracks:
  + subtitle tracks:
+ Using preset: iPhone & iPod Touch
<b>ERROR: Invalid audio input track '1', exiting.</b>

The error message is pretty clear - something is up with the audio track of the video. Running flvcheck -v showed that special.flv contained only video frames. Apparently that throws handbrake for a loop (Sorry, Charlie).

The solution turned out to be pretty straight forward. I just needed to turn to my friends stackoverflow and ffmpeg for the answer.

In the end, I used this recipe:

ffmpeg -ar 48000 -ac 2 -f s16le -i /dev/zero \
       -i special.flv -shortest -c:v copy    \
       -c:a aac -strict experimental \
       special_with_audio.flv

This ffmpeg command copies the video stream (without losing any quality) and injects an audio stream built from /dev/zero - which is a stream of null bytes.

This gives you in a glimpse into the power of ffmpeg. One can easily imagine dropping the video stream and keeping the audio; or merging the video of one file with the audio of another. Yeah, if you're going to touch video you need to learn ffmpeg.

No comments:

Post a Comment