Skip to content
This repository has been archived by the owner on Oct 7, 2021. It is now read-only.

Using Multiple FFmpeg Implementations In The Same iOS Application

Taner Şener edited this page Oct 23, 2020 · 4 revisions

On iOS / tvOS, FFmpeg inside MobileFFmpeg is packaged as a separate set of frameworks/libraries. This layout allows you to use FFmpeg alone without MobileFFmpeg.

Below you can see the contents of mobile-ffmpeg-min package published in Cocoapods. As you can see, there are 8 different frameworks inside the package. mobileffmpeg.framework belongs to MobileFFmpeg and the other 7 frameworks belong to FFmpeg.

You can use those 7 FFmpeg frameworks without MobileFFmpeg. But you can not use MobileFFmpeg framework alone because it depends on FFmpeg.

If you add another FFmpeg implementation into your application you may experience unexpected errors or crashes. It all depends on how the second FFmpeg implementation is packaged and in which order frameworks/libraries are loaded.

Remember that sometimes it may not be possible to resolve those errors.

1. Second FFmpeg as Single Framework/Library

Some libraries like MobileVLCKit does not use the same package layout as MobileFFmpeg and produce only a single framework/library. FFmpeg is included in that single library.

If you add one of those libraries into your application, you need to make sure that the second FFmpeg library is linked after MobileFFmpeg. If not, MobileFFmpeg will use the second FFmpeg implementation, not the one it is linked and packaged with and most probably will fail.

You need to edit OTHER_LDFLAGS flag in Pods-<Your App>.debug.xcconfig file of your project and move the second FFmpeg implementation after MobileFFmpeg.

For example, in order to use MobileVLCKit inside your application, edit OTHER_LDFLAGS and move -framework "MobileVLCKit" flag to the end. Or make sure that all MobileFFmpeg frameworks -framework "mobileffmpeg” -framework "libavcodec" -framework "libavdevice" -framework "libavfilter" -framework "libavformat" -framework "libavutil" -framework "libswresample" -framework "libswscale" are ahead of -framework "MobileVLCKit". If you do that, you will be able to use both libraries without any major issues.

1.1 Post Install Script for MobileVLCKit

Instead of manually editing OTHER_LDFLAGS, it is possible to define a post_install script in Podfile to make the necessary adjustments. Use the following one if you use MobileFFmpeg and MobileVLCKit in the same application. It will re-arrange OTHER_LDFLAGS and resolve the incompatibilities. Do not forget to replace MYPROJECT with your target name.

post_install do |installer|
    installer.pods_project.targets.each do |target|
        if target.name == "Pods-MYPROJECT"
            puts "Updating #{target.name} OTHER_LDFLAGS"
            target.build_configurations.each do |config|
                xcconfig_path = config.base_configuration_reference.real_path

                # read from xcconfig to build_settings dictionary
                build_settings = Hash[*File.read(xcconfig_path).lines.map{|x| x.split(/\s*=\s*/, 2)}.flatten]

                # modify OTHER_LDFLAGS
                vlc_flag = ' -framework "MobileVLCKit"'
                build_settings['OTHER_LDFLAGS'].gsub!(vlc_flag, "")
                build_settings['OTHER_LDFLAGS'].gsub!("\n", "")
                build_settings['OTHER_LDFLAGS'] += vlc_flag + "\n"

                # write build_settings dictionary to xcconfig
                File.open(xcconfig_path, "w") do |file|
                  build_settings.each do |key,value|
                    file.write(key + " = " + value)
                  end
                end
            end
        end
    end
end

2. Second FFmpeg as Multiple Frameworks/Libraries

If you add another FFmpeg implementation into your application where FFmpeg is packaged as a separate set of libraries like MobileFFmpeg, then it may not be possible to use that library with MobileFFmpeg. Technically, applications can not load multiple versions of the same library and one of the versions needs to be ignored/excluded.

In this particular case, there are two sets of FFmpeg libraries inside your application and only one of them can be used. You need to edit OTHER_LDFLAGS flag in Pods-<Your App>.debug.xcconfig file of your project and change the order in which libraries are loaded. You need to test and see if MobileFFmpeg can use the second FFmpeg implementation or the second FFmpeg library can use MobileFFmpeg's FFmpeg implementation. If either of them works then you can ignore/exclude the other FFmpeg implementation and use both libraries in the same application. If not, then you will not be able to use MobileFFmpeg with that library in the same application.

MobileFFmpeg uses -framework "libavcodec" -framework "libavdevice" -framework "libavfilter" -framework "libavformat" -framework "libavutil" -framework "libswresample" -framework "libswscale" flags in OTHER_LDFLAGS to link FFmpeg. You may need to move or delete that section in your tests.

Clone this wiki locally