Long time no write!, I’ve been very busy last year hacking on some cool projects (most of them are hosted on my Github account) and (tele) working for some cool clients (Opendrive, Meneame among others) and the best, I have a brand new job. Now I finally found some little time and of course, something interesting to write about in this blog.
Last week I was quite busy building an online video player for one customer, it was a nice challenge, and I thought it was pretty easy task. In this post I will describe what I’ve done to get it working from the perspective of the backend (from the frontend is not a big deal though, you only need some jquery player for HTML5 player with fallback to flash)
The first thing that I had to do was a super simple queue to process video conversions (FIFO), I didn’t want to suck up all the CPU from the servers, right now it is converting 10 videos at a time. For this task I created a tiny webserver using NodeJS, which is pretty awesome btw to create child processes, and the best it’s a single process (no forks, no locks, no threads). Because the queue has its interface through webserver I can create task and check their status with a simple REST interface (which is pretty neat).
The skeleton was built, now I had to Google about ffmpeg and the right parameters to get a mp4 version of the current video, and this video should work for HTML5 (Chrome, and Safary I think) and Flash (JWPlayer — Firefox, IE, etc).
After hours of Googling and testing I ended up using these parameters:
ffmpeg -i <input> -vcodec libx264 -vpre -vpre “>-vpre “>hq -vpre ipod640 -b 250k -bt 50k -acodec libfaac -ab 56k -ac 2 -s 480×320 -g <output>
That command was perfect for our use case, fast and with good quality.
Nonetheless I found some issues, for instance the flash player wasn’t able to play the video until it was totally downloaded, which was pretty annoying for large videos and/or slow connections. For my surprise it was working perfectly fine on HTML5 (with last Chrome for OpenSuse), then watching Apache’s log I found out that Chrome was doing a couple of partial requests, the first one to get the meta-data of the video, and the other to get the video itself.
After tons of hours researching about how to move meta-data to the beginning of the file, and ideally it should be done only with ffmpeg, but I couldn’t find it. (if you know how to do it, ping me pls)
MP4Box -inter 0.5 <output>
After these unexpected issues, everything is working as a charm
PD: Fixed some typos (it is 5am here)