Adding media assets in mobile applications is an awesome way to create a unique universe to immerse your users in.
I recently found myself in this situation where I need to embed more than 20 video files in an application, each of these files takes up nearly 100MB. That is a lot for 30 seconds of video. The particular use case of the application requires that the files be embedded directly into the application.
Without optimising these videos, it would drastically increase the app size, making each deployment and downloading so much longer and complicated, not to mention the performance issues it might entail. Luckily, that’s when FFmpeg comes to the rescue.
Open source, free, command line based
FFmpeg is a large suite of libraries and programs for handling video, audio, and other multimedia files and streams. At its core is the FFmpeg program itself, designed for command-line-based processing of video and audio files.
The simplest way to install FFmpeg is to use a package manager.
brew install ffmpeg
sudo apt update && sudo apt install ffmpeg
You can always download it directly from here: FFmpeg download page
Once installed, you can make use of this powerful tool by running the following command:
ffmpeg -i $pathToInputFile [-param1 value1 -param2 value2 etc] $pathToOutputFile
Most video formats are accepted as input: .mp4, .mov, .wmv, .avi, .webm, .mkv. You can find the full list of supported formats here
The parameters that I used were the following:
- The video encoding:
H265, or High Efficient Video Coding, is the new standard video compression that provides even more improvement over H264, also known as Advanced Video Coding.
⚠️ By default, when converting to H265 codec, ffmpeg tags the video as
hev1 format, which is not supported by iOS and MacOS. You will need to add the following parameter to the command:
- The constant rate factor:
The constant rate factor adjusts the file data rate. The lower the CRF number, the higher the quality of video.
For H264, the default CRF value is 23 for H264 and 28 for H265. You can adjust this rate to accommodate to your needs.
In my case, by combining the two parameters above, I was able to bring the average file size from 75MB to merely 4MB without significant quality loss in videos.
Here is the same frame before and after optimisation:
The delivered app, containing twenty of those video files, takes up less than 300MB as opposed to 1.5GB . This was clearly a big win for the team.
Obviously FFmpeg offers plenty of other possibilities to optimise your video files. The common parameters to play with are frame related.
If the destination device or display window is smaller than the original video, we can reduce the video size by applying the video filter:
-vf scale=width:height .
ffmpeg -i <input> -vf scale=480:320 <output>
To keep the original aspect ratio, set simply either the desired width or height and let the other parameter take the value -1.
ffmpeg -i <input> -vf scale=1024:-1 <output>
To optimise the video for devices that do not yet support high FPS, you can reduce the fps like so:
ffmpeg -i <input> -vf fps=30 <output>
You could also regulate the video’s bitrate which serves as an indicator of overall quality, as well as file size.
`ffmpeg -i <input> -b 800k <output>
In this article, we managed to optimise video files using FFmpeg by tweaking a couple of parameters. These should be enough for reducing file size without significant quality loss. To achieve more advanced and specific requirements, you can refer to the official documentation on https://ffmpeg.org .