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 thoughts on “How to convert .flv Flash video to .mp4 on the Mac

  1. Actually, there’s a way to do this without having to use terminal. Automator was built for things like this.

    Open Automator and choose “Application” in the “Chose a Template for your workflow” pane.

    It’ll pop up a blank workflow.

    Add the run shell script action from Utilities making sure to change “Pass Input” to “as arguments.

    Then paste the following into the action:

    for f in “$@”
    do
    ffmpeg -vcodec copy -acodec copy -i “$f” “$f”.mp4
    done

    Save it in your applications folder and add it to your dock. Then you can just drop your video files onto it and it’ll convert it without any command line kung foo!

  2. As a code clutz I understood only a bit of that and tried the paste into an automator action window but only get an error message which asks me to check the automators properties…

    I did guess i need set the shell option to /bin/sh but even posting in the original posters code and trying to massage the above code into it gave me no better result although the time between starting and fail ranged to different time scales

  3. Thanks for the help by the way

    Ha it does not like code My current text box in the automator is between the : :
    :
    for f in “$@”
    do
    /usr/local/bin/ffmpeg -vcodec copy -acodec copy -i “$f” “$f”.mp4
    done
    :

    still gives error when i drag flv onto automator

  4. Hi. Sorry to dig up an old thread, but i am having problems. So i am running os x lion, and i am using this add-on in firefox which downloads tv shows off ABC iview (australia). https://addons.mozilla.org/en-US/firefox/addon/iviewfox/ . It says in the link that the downloaded file needs to be run through the ‘flvuncontainer’, but the one provided by him no lunger works in the new firefox update. So how can i uncontain(if that is to make it an itunes compatible mp4). I tried automator, i tried your app, Jan, but i am not sure what i have to change, if i have to change anything etc. I installed the perian thing, so i presume i have ffmpeg. This is my automator script:

    for f in “$@”
    do
    echo “$f”
    done

    for f in “$@”
    do
    ffmpeg -vcodec copy -acodec copy -i in.flv out.mp4
    done

    Is this right?What shell type should it be (bin/???)

    Cheers, thanks heaps in advance, a speedy reply would be appreciated, am going away soon and want to put the videos on ipad. Any solution/help would be great!

  5. @Elias:
    Perian won’t have provided you with a working copy of ffmpeg. You’ll need to download a copy for yourself and install it, then reference it in your Automator application. The only thing that might keep the Automator app from working is the issue raised in the original post of remixing vs. transcoding. But that’s for later. For now,…

    Go to http://go.to/osxffmpegcompiling. Click on the top-most link to download the ffmpeg 0.82 binary.

    Now, open a Finder window and drag the downloaded zip archive to the desktop. Double-click it to expand the archive. You now have an ffmpeg executable.

    Click on the Finder window to give it focus, then, from the Go menu choose the next-to-last item, “Go to Folder…”. In the text-entry sheet that drops down in your Finder window type:
    /usr/local/bin/
    and press Return. Drag the ffmpeg executable from your desktop into this directory. You now have a *working* ffmpeg executable. To get it to work in an Automator app, you’ll have to follow Jan’s suggestion above and enter the absolute path. So, here’s what’s next….

    Start clean. Open Automator and select an application template. In the Actions list on the left, click on the Utilities category in the Library. From the utilities, drag “Run Shell Script” action to the workflow area.

    In the Run Shell Script action, leave the shell type set to “/bin/bash”. Set “Pass input” to “as arguments”. Delete the line that says “echo “@f” ” and replace it with the command for remuxing with the absolute path to ffmpeg added:
    /usr/local/bin/ffmpeg -vcodec copy -acodec copy -i “$f” “$f”.mp4

    Save your application to the Application directory. Drag a copy to your Dock if you want. Finally, take it for a test-drive. If it doesn’t work, you may need to transcode the videos instead. Replace the above command with:
    /usr/local/bin/ffmpeg sameq -i “$f” “$f”.mp4
    and save your app.

    That should take care of your vids. Now all you need to do is enjoy your trip!

  6. @Jess:
    Thank you so much! You have been a great help. Thanks for the detailed and easy to understand advice. And thanks for responding so quickly. And now i can enjoy the trip, especially the flight. Thanks again!

  7. @Jared
    Thanks for that pointer to compiled binaries for ffmpeg!

    @Automator users
    You can use the steps I posted above to create an Automator application which will remux or transcode an entire folder of FLV videos by adding the “Get Folder Contents” action (from the “Files and Folders” Library group) above/before the “Run Shell Script” action in the workflow. Then you can just drag an entire folder onto the application icon.

  8. I have a new iMac with Lion. I tried to follow Jess”s advice, but when I entered /usr/local/bin/ into the gotofolder drop down I got a can’t find message.
    What should I do?

  9. @Susan
    Since your iMac is new, you may not have installed any software that would place command-line executables in the /usr/local/bin/ directory. So, in the “Go to Folder…” drop-down sheet, enter
    /usr/local/
    leaving off the “bin/”. Once there, if you don’t see a “bin” directory already there, create one. Now go ahead and copy ffmpeg into your newly created directory.

  10. @Susan
    Well, the use of the “code” tag seems to have done something funky to the line to which it was applied. (You know, that funky CSS stuff!) In that white-backed text above, it says:
    /usr/local/
    even if you can’t read it.

  11. Hi Jess
    It couldn’t find /usr/local/ so I tried /usr/ and I have one. Inside is a folder labeled bin that contains such files as 2to3 and afmtodit. So, should I follow your directions using /usr/bin/ instead of /usr/local/bin/?

    I am being very cautious since I don’t want to screw up all the good Apple-installed things inadvertently.

    Thanks for your help and your patience.

  12. @Susan
    You could do that, but rather than tamper with a directory used by the OS, go ahead and create a “local” directory within “usr”, then create a “bin” directory within “local”. That will give you a path that’s acceptable to the *nix world.

    To recap:
    – create a /local directory within /usr = /usr/local/
    – create a /bin directory within /usr/local/ = /usr/local/bin/

  13. Jared, Jess, Tom
    Thanks for the advice. I created the /usr/local/bin/ and put ffmeg inside. Then I downloaded the remux. Then I tested with an flv file from Youtube. Success!!
    You guys are great
    Susan

  14. Here is my automator folder action:
    1. First rename the movie to .flv
    2. Run command line:
    – – – – – – –
    for f in “$@”
    do
    $HOME/bin/ffmpeg -i “$f” -vcodec copy -acodec copy “${f%.*}.mp4″
    done
    – – – – – – -

  15. Hopefully you’ll see this Jan because I really need your help! What was the change you made to utils.c that prevented ffmpeg from crashing due to the monotone error? I’m trying to build my own binary of ffmpeg and all of them crash due to this. Please help!

    • Eli, if I recall correctly, I just removed the line that makes the program exit the loop within the monotone check condition.

      Cheers,
      Jan

  16. Jan,

    Thanks for the reply. Do you by chance now which line that was? If not, that’s ok. I’ve never messed around in code before so I wouldn’t know where to start!

  17. 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

  18. 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?

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

    Help would be appreciated.

  20. 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

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>