Use Mobile-FFmpeg with Unity
Introduction
It became necessary to process video files and audio files within the application being developed in Unity, so we decided to use Mobile-FFmpeg. A memo of what I did before I introduced it and became able to use it.
What is Mobile-FFmpeg?
FFmpeg’s Android / iOS open source library. The content consists of FFmpeg and FFprobe implementations and external libraries. Updates are also being actively carried out.
The feature is that it is a simple API that is called by specifying an optional command character string in exactly the same way as the command line version of FFmpeg.
https://github.com/tanersener/mobile-ffmpeg
Caution
Since MobileFFmpeg has more than 40 externally dependent libraries, it is a good idea to first determine where to use MobileFFmpeg in your app and clarify the required functions and required libraries.
This article is written for Mobile-FFmpeg Version 4.4, Unity 2018 and above.
Pre-built binaries
You can build it yourself, but we also have pre-built binaries, so I used this one this time.
Eight kinds of variations are prepared for the binary depending on the external library included.
Packages
min
: Minimal packagemin-gpl
: min with the GPL license library addedhttps
: TLS related libraries addedhttps-gpl
: https with the GPL license library added- ʻAudio`: Added audio-related libraries
video
: Added video-related librariesfull
: Full set (not including GPL license)full-gpl
: Full set (including GPL license)
Select the package from the above according to your purpose and download the file (https://github.com/tanersener/mobile-ffmpeg/releases)
Download aar file for library for Android
-(File name): mobile-ffmpeg-[Package]-[Version] .aar
Download the xcframework.zip file and unzip the library for iOS
-(File name): mobile-ffmpeg-[Package]-[Version]-ios-xcframework.zip
Check the following for details on each package.
2.1 Packages
Import to Unity
downloaded
.aar file
/Assets/Plugins/Android
Unzip the zip and open the framework files
/Assets/Plugins/iOS
set on.
Call from C # on the Unity side
Implement a wrapper for calling Plugin modules for Android and iOS respectively. Basically, it’s OK if you can call two APIs, Execute and Cancel.
I referred to the thread of Isshue # 258 on GitHub of MobileFFmpeg.
https://github.com/tanersener/mobile-ffmpeg/issues/258#issuecomment-663913978
code
There are three source files. Place the .mm file in ʻAssets / Plugins / iOS`.
FFmpegWrapper.cs
using UnityEngine;
public class FFmpegWrapper
{
private static int Execute(string command)
{
#if UNITY_ANDROID
using (AndroidJavaClass configClass = new AndroidJavaClass("com.arthenica.mobileffmpeg.Config"))
{
AndroidJavaObject paramVal = new AndroidJavaClass("com.arthenica.mobileffmpeg.Signal").GetStatic<AndroidJavaObject>("SIGXCPU");
configClass.CallStatic("ignoreSignal", new object[] { paramVal });
using (AndroidJavaClass ffmpeg = new AndroidJavaClass("com.arthenica.mobileffmpeg.FFmpeg"))
{
int code = ffmpeg.CallStatic<int>("execute", new object[] { command });
return code;
}
}
#elif UNITY_IOS
return MobileFFmpegIOS.Execute(command);
#else
return 0;
#endif
}
private static int Cancel()
{
#if UNITY_ANDROID
using (AndroidJavaClass configClass = new AndroidJavaClass("com.arthenica.mobileffmpeg.Config"))
{
using (AndroidJavaClass ffmpeg = new AndroidJavaClass("com.arthenica.mobileffmpeg.FFmpeg"))
{
int code = ffmpeg.CallStatic<int>("cancel");
return code;
}
}
#elif UNITY_IOS
return MobileFFmpegIOS.Cancel();
#else
return 0;
#endif
}
MobileFFmpegIOS.cs
using UnityEngine;
using System.Collections;
using System.Runtime.InteropServices;
public class MobileFFmpegIOS : MonoBehaviour
{
#if UNITY_IOS
[DllImport("__Internal")]
private static extern int _execute(string command);
[DllImport("__Internal")]
private static extern void _cancel();
#endif
/**
* Synchronously executes FFmpeg command provided. Space character is used to split command
* into arguments.
*
* @param command FFmpeg command
* @return zero on successful execution, 255 on user cancel and non-zero on error
*/
public static int Execute(string command)
{
int result = -1;
#if UNITY_IOS
if (Application.platform == RuntimePlatform.IPhonePlayer)
{
result = _execute(command);
}
#endif
return result;
}
/**
* Cancels an ongoing operation.
*
* This function does not wait for termination to complete and returns immediately.
*/
public static void Cancel()
{
#if UNITY_IOS
if (Application.platform == RuntimePlatform.IPhonePlayer)
{
_cancel();
}
#endif
}
}
The following is placed in ʻAssets / Plugins / iOS`
MobileFFmpeg.mm
//In unity, You'd place this file in your "Assets>plugins>ios" folder
//Objective-C Code
#import <mobileffmpeg/MobileFFmpeg.h>
extern "C"
{
/**
* Synchronously executes FFmpeg command provided. Space character is used to split command
* into arguments.
*
* @param command FFmpeg command
* @return zero on successful execution, 255 on user cancel and non-zero on error
*/
int _execute(const char* command)
{
return [MobileFFmpeg execute: @(command)];
}
/**
* Cancels an ongoing operation.
*
* This function does not wait for termination to complete and returns immediately.
*/
void _cancel()
{
[MobileFFmpeg cancel];
}
}
Call from Unity
Call the option command by passing it as a character string to the Execute parameter (note that “ffmpeg” is unnecessary). If successful, 0 is returned.
Example
private void Test()
{
var input = Application.persistentDataPath + "/input.mov";
var output = Application.persistentDataPath + "/output.mp4";
int rc = FFmpegWrapper.Execute(string.Format("-i {0} {1}", input, output));
Debug.Log("Return Code is " + rc);
}
There is also an asynchronously executed FFmpeg.executeAsync
function, but I haven’t tried it. I’m sorry. .. ..
Other
○ If you get a linker error in Xcode
** If the following libraries do not exist in [Link Binary with Libraries] **, add them.
bzip2, iconv, libuuid, zlib, AudioToolbox, VideoToolbox, AVFoundation
(libz.tbd, libbz2.tbd, libiconv.tbd)
It seems that it does not support Armv7, so ** Architectures ** was built exclusively for Arm64.
○ Run-time error
-Fails if a file with the same name as the Output file that does not have file write permission already exists
-The required library is determined according to the command, so it will fail if there is no module.
Reference article
Analyze and convert audio files using FFmpeg on Android
https://qiita.com/tarumzu/items/a4d15957a144f520f842
You can do it with FFmpeg!
https://qiita.com/cha84rakanal/items/e84fe4eb6fbe2ae13fd8
Convert video to GIF with FFmpeg
https://qiita.com/wMETAw/items/fdb754022aec1da88e6e