FFmpeg is fast easy and powerful

ffmpeg fast versatile powerful

FFmpeg is a collection of different projects for handling multimedia files. It’s evolved into a tool kit that is fast, easy, and powerful. So while there are several GUI based applications available, sometimes you need something that can provide the ultimate performance. Enter FFmpeg.

Let’s start at the beginning

Hey there fellow Android Developers! Here is the scenario…

You’ve been asked to record some videos in your Android app and send those videos through an HTTP call. A pretty straight forward requirement, right? But here’s the catch, since we are trying to maximize the resources and we are trying to be as efficient as possible, the videos need to be compressed.

Now what?

So, the question here is: How do we accomplish that?

After some research, I ran into FFmpeg, which is a command-line tool. Because of that, Android can run it perfectly without a problem, but there’s another tricky part. We need to learn how to execute command lines from our code. As a result, we may spend more time trying to do so.

Another solution is an SDK. So, lucky for us, the guys from Writing Minds have created such SDK. This meant we don’t have to worry about executing commands for now.

Let’s code!

Imports

So, now we have what we need to fulfill our requirement, let’s see some code, shall we?

First of all, we need to import the SDK. By doing this, we’ll be able to use FFmpeg. So, for that, we just need to add these line in our app level build.gradle file:

implementation 'com.writingminds:FFmpegAndroid:0.3.2'
Initializing our library

The next thing we want to do is create an instance of our FFmpeg library and initialize it. For that, I recommend doing this in our Application extended class. As a result, this code will just execute once, and we’ll have just one instance, and we can call it from every part of our project.

class MyApplication : Application() {

    override fun onCreate() {
        super.onCreate()
        loadFFMpegBinary()
    }
    companion object{
        @JvmStatic
        lateinit var ffmpeg : FFmpeg
    }
    fun loadFFMpegBinary() {
        try {
            ffmpeg = FFmpeg.getInstance(this)
            ffmpeg.loadBinary( object:LoadBinaryResponseHandler() {
                override fun onFailure() {
                    Log.i("FFMPEG", "FAIL")
                }
                override fun onSuccess() {
                    Log.i("FFMPEG", "SUCCESS")
                }
            })
        } catch (e : FFmpegNotSupportedException) {
            Log.e("FFMPEG", e.message, e)
        } catch (e : Exception) {
            Log.e("FFMPEG", e.message, e)
        }
    }
}

By doing this, we are creating the instance and loading the binaries required for FFmpeg to work properly with our smartphone’s architecture.

Executing our commands

Now we are ready to start playing with our new tool.  To be able to call the compress function in my entire app, I added this method to my Utils class.

fun compressVideo(inputVideoPath: String, outputVideoPath: String) {

        try {
            val command = arrayOf("-y", "-i", inputVideoPath, "-s", "720x960", "-r", "24", "-b:v", "150k", "-b:a", "48000", "-strict", "-2", "-ac", "2", "-ar", "16000", outputVideoPath)

            MyApplication.ffmpeg.execute(command, object : ExecuteBinaryResponseHandler() {
                override fun onFailure(s: String?) {
                }
                override fun onSuccess(s: String?) {
                }
                override fun onProgress(s: String?) {
                }
                override fun onStart() {
                }
                override fun onFinish() {
                }

            })
        } catch (e: FFmpegCommandAlreadyRunningException) {
            Utils.error(TAG, e.message, e)
        }
    }

This method is receiving as parameters the base video and the new path where the compressed video will be. As you can see, the way to execute the commands is straightforward. We simply create an array with the parameters and execute it.

In this particular case, this is the list of parameters I used:

-yto overwrite output files without asking.
-ireads from input files specified by option -i
-svideo output size(video resolution)
-rset frame rate
-b:vsets the video bitrate
-b:asets the audio bitrate
-acsets the number of audio channels
-arsets the sampling rate of the audio streams if encoded.
Pretty simple, right?

The good news is, this is a very easy, yet powerful way to use FFmpeg. There are a lot of things you can do with this tool like compress a video, extract the audio from a video, extract images from a video, cut videos, and so on.

I hope this little tutorial encourages you to try all the benefits this powerful tool has to offer.

Talk with Business Mobility Experts

Discuss your ideas, questions, and concerns. Get answers specific to your needs.

Schedule Call
Write a comment