How to convert .flv Flash video to .mp4 on the Mac

I have a bunch of photography tutorials in the Flash video .flv format which I want to watch on my iPad. As you may be aware, everything with the name Flash in it doesn’t play too well on Apple’s iOS devices. VLC Media Player for iOS is able to play the .flv format but Apple doesn’t allow 3rd party software devs to use the built-in H.264 hardware acceleration for video playback. As as result, .flv videos usually don’t play very well on iOS devices. Besides, I prefer to manage my video collection in iTunes instead of dragging every clip onto an app icon.

A software called MPEG StreamClip is a good starting point to convert all kinds of video files to something that plays on iOS devices like the iPad. The software needs Perian to be able to handle the Flash video format. Perian itself uses ffmpeg to play Flash videos and plugs in nicely into Mac OS X so you can play Flash videos with Quicktime Player as well.

The .flv Flash video format is a container for different video and audio formats. A while back, On2 VP6 was the standard video codec for Flash video. With hardware video accelerators becoming more popular in mobile devices, many .flv videos are encoded with H.264/MPEG-4 AVC today.

For some reason, quite a few of my Flash videos don’t play very well with Perian. There’s stutter, there are those typical compression artifacts and video/audio is off-sync at times. It may very well be that there’s something odd with my Flash videos but with VLC for Mac and on my Windows XP virtual machine, those videos play back with no visible or audible problems. Since MPEG StreamClip uses Perian, the converted .mp4 videos show the same problems. But wait a second. If both, .flv and .mp4 make use of the same video format (H.264/MPEG-4 AVC) shouldn’t it be dead simple to extract the H.264 video stream and the audio stream and remux them to an iTunes-compatible .mp4 container, without transcoding the entire video?

The good news is: yes, it actually is! And it’s free as well. The bad news is (well, for some): it’s only for the command line savvy. All you need is ffmpeg. You may want to build your own ffmpeg binary but if you’re too lazy, just download my ffmpeg binary. The source for this binary is taken straight from the latest SVN trunk so don’t expect it to work for anything other than explained in this post. I also had to apply a small fix in utils.c so ffmpeg doesn’t abort with “error, non monotone timestamps n >= n” while remuxing slightly out-of-sync Flash videos. I linked all dependent libraries (like x264) statically so it’s just one large binary.

FFmpeg version SVN-r25783, Copyright (c) 2000-2010 the FFmpeg developers
  built on Nov 22 2010 20:50:32 with gcc 4.2.1 (Apple Inc. build 5664)
  configuration: --enable-libfaac --enable-libx264 --enable-nonfree
                         --disable-shared --enable-libmp3lame --enable-gpl
                         --enable-postproc --arch=x86_64
  libavutil     50.33. 0 / 50.33. 0
  libavcore      0.13. 0 /  0.13. 0
  libavcodec    52.97. 0 / 52.97. 0
  libavformat   52.85. 0 / 52.85. 0
  libavdevice   52. 2. 2 / 52. 2. 2
  libavfilter    1.62. 0 /  1.62. 0
  libswscale     0.12. 0 /  0.12. 0
  libpostproc   51. 2. 0 / 51. 2. 0
Hyper fast Audio and Video encoder

Remuxing .flv to an .mp4 container

Let’s say you want to convert in.flv to out.mp4. Your in.flv has an embedded H.264 video stream and an AAC audio stream. Your target format is an iTunes-compatible .mp4 container with an embedded H.264 stream. Use this command to remux the .flv to .mp4:

ffmpeg -vcodec copy -acodec copy -i in.flv out.mp4

That’s it! Ain’t that simple? And because there’s no transcoding involved, this process is super fast!

Transcode .flv to an .mp4 container

Let’s say you want to convert a Flash video that contains an On2 VP6 video stream. You can’t simply remux the streams into an .mp4 container in this situation. The video stream needs to be transcoded from VP6 to MPEG-4 in order to be iTunes-compatible. Use this command to transcode .flv to .mp4:

ffmpeg -sameq -i in.flv out.mp4

Obviously, transcoding from one video format into another will take a whole lot more time than remuxing.

Using ffmpeg for remuxing or transcoding Flash videos seems to deliver better results compared to all other video converters I was able to find for the Mac (not that there are many).

Useful tricks

Let’s say you want to remux all .flv (containing a H.264 stream) video files in a directory to .mp4. Here’s a simple shell script to do this:

#!/bin/sh
find . -name '*.flv' -print0 | while read -d $'\0' file ;
do
	echo "remuxing: $file"
        ffmpeg -vcodec copy -acodec copy -i "$file" "$file.mp4" < /dev/null
done

Want to transcode older (VP6) .flv video files to .mp4? There’s a script for that:

#!/bin/sh
find . -name '*.flv' -print0 | while read -d $'\0' file ;
do
	echo "transcoding: $file"
        ffmpeg -sameq -i "$file" "$file.mp4" < /dev/null
done

Useful tools

MediaInfo Mac is an extremely useful tool if you want to have a look at the metadata of a video container. I use it a lot to decide whether I need to remux or transcode video files.

33 Responses to “How to convert .flv Flash video to .mp4 on the Mac”

  • Jan says:

    The exact line number probably differs in every ffmpeg version but if you cd to the root source directory you could type something like
    grep -nri monotone *
    and this will show you the file and area you have to edit. Comment the line that says return -1 just below the condition. It will still output the error but ffmpeg won’t terminate just because of it.

    Cheers,
    Jan

  • Eli says:

    The only place where I found it was in libavformat/utils.c and the line was:

    if(st->cur_dts && st->cur_dts != AV_NOPTS_VALUE && ((!(s->oformat->flags & AVFMT_TS_NONSTRICT) && st->cur_dts >= pkt->dts) || st->cur_dts > pkt->dts)){
    av_log(s, AV_LOG_ERROR,
    “Application provided invalid, non monotonically increasing dts to muxer in stream %d: %”PRId64″ >= %”PRId64″\n”,
    st->index, st->cur_dts, pkt->dts);
    return AVERROR(EINVAL);

    That sound right?

  • Jan says:

    If this is the exact error message you’re getting – yes. Remove the return line and you’re all set.

    Cheers,
    Jan

  • Eli says:

    Jan is there any way I can contact you via email? I have a few questions I’d like to ask.

  • Dirk says:

    can ANYONE upload a windows binary with this exact patch?? I am unable to compile it :(

    Help would be appreciated.

  • Multipazz says:

    ffmpeg SVN-r25783 is from 2010

    any chance of building v1.0 released September, 28, 2012 ?

  • Anon says:

    latest mac binary can be pwned here:-

    http://ffmpegmac.net/

  • Jeffrey says:

    There has been a change in ffmpeg – the priority of “-i” is very important in parameter order. What you need to do is this:

    ffmpeg -i input.flv -vcodec copy -acodec copy output.mp4

    … to avoid errors like “Unknown decoder ‘copy’ ffmpeg”

  • Leave a Reply