Why ffmpeg for Android and The App
I was working on a project that requires transcoding of video files and then play these files on Android device. The definite tool to do this is ffmpeg. I can do it on Desktop and transfer the files to Android, but why not just transcode on Android itself?
Then I searched for ffmpeg and transcoding tools on Android, but cannot find any. And since I’ve built ffmpeg libraries for Android before, I believe it is also doable to port the ffmpeg command line utility to Android. So I started doing it.
Below is the screen capture of the Android app (I released it as ffmpeg for Android Beta),
Figure 1. Screenshots of ffmpeg for Android
Currently it only supports armv7 processor, the one that my Nexus One device uses.
How did I Port it?
The main design goal is to change as few lines of code as possible for ffmpeg.c file. To meet this goal, I decoupled the UI and ffmpeg processing into two processes.
Running ffmpeg on a separate processes has a few advantages,
- ffmpeg uses a lot of exit function, which will terminate the process. Use a separate process for ffmpeg will ensure the termination of ffmpeg won’t affect the front UI.
- ffmpeg is processing intensive, running it on a separate process will not affect the responsiveness of front UI.
There’s inter-process communication problem to solve (IPC) so the two processes can communicate with each other. The UI will be able to start and stop ffmpeg, and ffmpeg will send output message to UI.
From UI to ffmpeg is simple, I implement a service that will call ffmpeg. And we start the service using Intent. It’s the same for stop command.
From ffmpeg to UI, there’re a few choices. pipe, socket, etc. But since it requires only a very simple one way communication channel (ffmpeg write, UI read), I just use text files. ffmpeg dump all outputs to text files, and UI read it every second or two (you can also use file observer and update the UI only when the text files changes).
What are the Changes for ffmpeg.c
With the design above, the change for ffmpeg.c is simple.
- Change the main(int argc, char **argv) function prototype to a java JNI interface prototype that Android java code can call.
- Change the output to stdout to the text files we created.
- Comment out a few lines that cause the compilation error.
A little More Thoughts
I’m thinking this method can be used to port lots of other applications to Android too. Two processes, running the background processing utility as a service, change the main method to an native interface so Java code can call, use intents and text files for communication, etc.
If you would like to try out this app, go to https://market.android.com/developer?pub=roman10. Note that it’s for armv7 processor only.