Take the 2-minute tour ×
Video Production Stack Exchange is a question and answer site for engineers, producers, editors, and enthusiasts spanning the fields of video, and media creation. It's 100% free, no registration required.

I need an automatic solution to convert video clips for html5 (mp4/x264, webm/vp8) and flash (mp4/x264) video-on-demand streaming. For a site like Youtube, just much smaller.

The input files are mostly h264/x264 but sometimes others (like divx/xvid) and have different resolution and sometimes contain subtitles (.ass) that need to be hard-burned. The output resolution should be 720p and 480p for >=720p video, 480p for 480p-720p and the original resolution for everything else.

The server is running debian.

I couldn't find any open source project, just some cloud services (SaaS) that offer this kind of conversion. I tried working with ffmpeg but each video needs a different bitrate to be still in a good quality and have a file size that allows video-on-demand. If the input video is bad the output video shouldn't be larger. I have no idea how to set the x264/vp8 params right and obviously I can't do that manually.

Do you know of any (linux) tool for this? There are many video sites out there, how do they do this? I looked at video files from youtube and they all differ in bitrate and file size. Or do you know any website or tutorial that could help me? I've spend much time searching for tips but I just can't find anything, maybe I'm searching for the wrong terms..

share|improve this question

2 Answers 2

Video transcoding is very confusing and there is loads of different options.

If you dont want to use FFMpeg you could try VLC

Read more about transcoding with VLC here

Otherwise FFMpeg (or some kind of wrapper tool) is your best bet. By omitting the -vb option you let FFMpeg decide bitrate. There is also a few Presets you can use for encoding to specific devices and qualitys, like ipod640.

I've build a tiny java application that transcodes video from a que (using MySQL) but a cronjob and a shell-script is also a good solution

share|improve this answer

For a server, you definitely want ffmpeg. I would also strongly recommend compiling it yourself (those are Ubuntu instructions, but should work for Debian as well AFAIK) - the best AAC encoder available for ffmpeg (libfdk_aac) cannot be redistributed alongside x264 (because of the GPL), and the version of ffmpeg in the repositories is probably too old for some of the things I'm going to list here.

MP4

To convert an arbitrary video to an MP4 using libx264 and libfdk_aac:

ffmpeg -i input.avi -c:v libx264 -crf 24 -preset veryfast \
-ac 2 -c:a libfdk_aac -vbr 3 -movflags faststart output.mp4

Control the quality of the video with -crf: a lower number is better quality, but larger file. 18 is visually lossless under most circumstances, and 24 should be more than good enough for online streaming. Use a -preset to control the speed/size of the video: a slower preset means a smaller file (the presets are ultrafast, superfast, veryfast, faster, fast, medium, slow, and slower). See here for more detail.

Control the quality of the audio with -vbr: the scale is 1-5, where 5 is best quality. Actually, even a vbr of 1 should be good enough for your purposes. See here for more detail. -ac 2 means that ffmpeg will output 2 audio channels, mixing down if necessary; you only really need to use it if you think people will send in 5.1 surround sound audio or something.

-movflags faststart is required for internet MP4 video.

WEBM

.webm is a little more complicated. libvpx (the VP8 encoder) should have a crf mode that will work in a similar way to x264's, but it is currently broken. Unfortunately, you'll have to target a bit rate instead. For standard definition, 1000kb/s should give very good quality (in fact, that is probably overkill). For full 1080p HD, about 5000kb/s will give really good quality (again, you can probably go lower - try it out and see). About 2200kb/s should do it for 720p.

ffmpeg -i input.avi -c:v libvpx -b:v 1000k \
-c:a libvorbis -q:a 4 -ac 2 output.webm

NOTE - make sure you use libvorbis (the xiph.org encoder lib), NOT vorbis (the inferior internal ffmpeg encoder). Set the quality with -q:a: the range is -1-10, where 10 is best quality, and 5 is indistinguishable from an original CD. 3 or 4 should be adequate for online streaming purposes.

Subtitles & scale video

To hardcode subtitles, you have to first extract them from the original file, then use either the ass filter or the subtitles filter to encode them. Using the subtitles filter:

ffmpeg -i input.mkv -map 0:s:0 -c:s ass subtitle.ass
ffmpeg -i input.mkv -filter:v 'subtitles=subtitle.ass' \
-c:v libx264 -crf 24 -preset veryfast \
-c:a libfdk_aac -vbr 3 -movflags faststart output.mp4 \
-filter:v 'subtitles=subtitle.ass' \
-c:v libvpx -b:v 1000k \
-c:a libvorbid -q:a 4 output.webm

To scale videos, use the scale filter. -1:480 means 'for the width, keep the input aspect ratio, and scale the height to 480'.

ffmpeg -i input.avi -filter:v 'scale=-1:480' \
-c:v libx264 -crf 24 -preset veryfast \
-c:a libfdk_aac -vbr 3 -movflags faststart output.mp4 \
-filter:v 'scale:-1:480' \
-c:v libvpx -b:v 1000k \
-c:a libvorbid -q:a 4 output.webm

You can combine the scale and subtitle filters like so:

ffmpeg -i input.mkv -filter:v 'scale=-1:480,subtitles=subtitle.ass' \
-c:v libx264 -crf 24 -preset veryfast \
-c:a libfdk_aac -vbr 3 -movflags faststart output.mp4 \
-filter:v 'scale:-1:480,subtitles=subtitle.ass' \
-c:v libvpx -b:v 1000k \
-c:a libvorbid -q:a 4 output.webm

You'd probably want to use a bash script to detect the input height and test the existence of subtitles; I'd personally use mediainfo to find that information, it's pretty amenable to regex.

That should be enough to get you going.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.