背景

flutter项目用到了ffmpeg-kit,但是2025年年初因为版权问题,官方放弃维护并且删除了部分二进制文件,导致现在项目编译不过,升级到最新版本6.0可以暂时规避这个问题,但是很快也会被删除。

代码仓库地址:github.com/arthenica/f…

分析

依赖

ffmpeg_kit_flutter: 5.1.0

iOS

错误信息

执行pod install时报错(如果不报错,可能是因为本地有缓存,先执行:pod cache clear --all)

[!] Error installing ffmpeg-kit-ios-https
[!] /usr/bin/curl -f -L -o /var/folders/mk/9gycp1yd0w9dz33s9tf0mm4w0000gn/T/d20250318-13472-ix6xgk/file.zip https://github.com/arthenica/ffmpeg-kit/releases/download/v5.1/ffmpeg-kit-https-5.1-ios-xcframework.zip --create-dirs --netrc-optional --retry 2 -A 'CocoaPods/1.15.2 cocoapods-downloader/2.1'


解决办法

fork原仓库,但是部分依赖是动态下载的,即使是fork了仓库代码,仍然会找不到这个文件

代码分析

Pod::Spec.new do |s|
  s.name             = 'ffmpeg_kit_flutter'
  s.version          = '6.0.3'
  s.summary          = 'FFmpeg Kit for Flutter'
  s.description      = 'A Flutter plugin for running FFmpeg and FFprobe commands.'
  s.homepage         = 'https://github.com/arthenica/ffmpeg-kit'
  s.license          = { :file => '../LICENSE' }
  s.author           = { 'ARTHENICA' => 'open-source@arthenica.com' }

  s.platform            = :ios
  s.requires_arc        = true
  s.static_framework    = true

  s.source              = { :path => '.' }
  s.source_files        = 'Classes/**/*'
  s.public_header_files = 'Classes/**/*.h'

  s.default_subspec     = 'https'

  s.dependency          'Flutter'
  s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' }

  s.subspec 'min' do |ss|
    ss.source_files         = 'Classes/**/*'
    ss.public_header_files  = 'Classes/**/*.h'
    ss.dependency 'ffmpeg-kit-ios-min', "6.0"
    ss.ios.deployment_target = '12.1'
  end

  s.subspec 'min-lts' do |ss|
    ss.source_files         = 'Classes/**/*'
    ss.public_header_files  = 'Classes/**/*.h'
    ss.dependency 'ffmpeg-kit-ios-min', "6.0.LTS"
    ss.ios.deployment_target = '10'
  end

  s.subspec 'min-gpl' do |ss|
    ss.source_files         = 'Classes/**/*'
    ss.public_header_files  = 'Classes/**/*.h'
    ss.dependency 'ffmpeg-kit-ios-min-gpl', "6.0"
    ss.ios.deployment_target = '12.1'
  end

  s.subspec 'min-gpl-lts' do |ss|
    ss.source_files         = 'Classes/**/*'
    ss.public_header_files  = 'Classes/**/*.h'
    ss.dependency 'ffmpeg-kit-ios-min-gpl', "6.0.LTS"
    ss.ios.deployment_target = '10'
  end

  s.subspec 'https' do |ss|
    ss.source_files         = 'Classes/**/*'
    ss.public_header_files  = 'Classes/**/*.h'
    ss.dependency 'ffmpeg-kit-ios-https', "6.0"
    ss.ios.deployment_target = '12.1'
  end

  s.subspec 'https-lts' do |ss|
    ss.source_files         = 'Classes/**/*'
    ss.public_header_files  = 'Classes/**/*.h'
    ss.dependency 'ffmpeg-kit-ios-https', "6.0.LTS"
    ss.ios.deployment_target = '10'
  end

  s.subspec 'https-gpl' do |ss|
    ss.source_files         = 'Classes/**/*'
    ss.public_header_files  = 'Classes/**/*.h'
    ss.dependency 'ffmpeg-kit-ios-https-gpl', "6.0"
    ss.ios.deployment_target = '12.1'
  end

  s.subspec 'https-gpl-lts' do |ss|
    ss.source_files         = 'Classes/**/*'
    ss.public_header_files  = 'Classes/**/*.h'
    ss.dependency 'ffmpeg-kit-ios-https-gpl', "6.0.LTS"
    ss.ios.deployment_target = '10'
  end

  s.subspec 'audio' do |ss|
    ss.source_files         = 'Classes/**/*'
    ss.public_header_files  = 'Classes/**/*.h'
    ss.dependency 'ffmpeg-kit-ios-audio', "6.0"
    ss.ios.deployment_target = '12.1'
  end

  s.subspec 'audio-lts' do |ss|
    ss.source_files         = 'Classes/**/*'
    ss.public_header_files  = 'Classes/**/*.h'
    ss.dependency 'ffmpeg-kit-ios-audio', "6.0.LTS"
    ss.ios.deployment_target = '10'
  end

  s.subspec 'video' do |ss|
    ss.source_files         = 'Classes/**/*'
    ss.public_header_files  = 'Classes/**/*.h'
    ss.dependency 'ffmpeg-kit-ios-video', "6.0"
    ss.ios.deployment_target = '12.1'
  end

  s.subspec 'video-lts' do |ss|
    ss.source_files         = 'Classes/**/*'
    ss.public_header_files  = 'Classes/**/*.h'
    ss.dependency 'ffmpeg-kit-ios-video', "6.0.LTS"
    ss.ios.deployment_target = '10'
  end

  s.subspec 'full' do |ss|
    ss.source_files         = 'Classes/**/*'
    ss.public_header_files  = 'Classes/**/*.h'
    ss.dependency 'ffmpeg-kit-ios-full', "6.0"
    ss.ios.deployment_target = '12.1'
  end

  s.subspec 'full-lts' do |ss|
    ss.source_files         = 'Classes/**/*'
    ss.public_header_files  = 'Classes/**/*.h'
    ss.dependency 'ffmpeg-kit-ios-full', "6.0.LTS"
    ss.ios.deployment_target = '10'
  end

  s.subspec 'full-gpl' do |ss|
    ss.source_files         = 'Classes/**/*'
    ss.public_header_files  = 'Classes/**/*.h'
    ss.dependency 'ffmpeg-kit-ios-full-gpl', "6.0"
    ss.ios.deployment_target = '12.1'
  end

  s.subspec 'full-gpl-lts' do |ss|
    ss.source_files         = 'Classes/**/*'
    ss.public_header_files  = 'Classes/**/*.h'
    ss.dependency 'ffmpeg-kit-ios-full-gpl', "6.0.LTS"
    ss.ios.deployment_target = '10'
  end

end


iOS中, ffmpeg_kit_flutter.podspec 文件可以看出来,ffmpeg_kit_flutter 依赖了 ffmpeg-kit-ios-xxx,

其中xxx可以是min,https等,默认是https,正好对应了下载报错的ffmpeg-kit-https-5.1-ios-xcframework.zip 文件,所以只需要把这个依赖改成本地,就可以解决报错问题

代码修改

  1. 修改依赖

    1.    #   s.default_subspec     = 'https'
        # FFmpegKit has been officially retired.Place iOS dependent libraries locally to solve compilation problems
         s.default_subspec = 'ffmpeg_kit_ios_local'
      
         s.subspec 'ffmpeg_kit_ios_local' do |ss|
           ss.vendored_frameworks = 'Frameworks/ffmpeg-kit-ios-https/ffmpegkit.xcframework', 'Frameworks/ffmpeg-kit-ios-https/libavdevice.xcframework', 'Frameworks/ffmpeg-kit-ios-https/libavcodec.xcframework', 'Frameworks/ffmpeg-kit-ios-https/libavfilter.xcframework', 'Frameworks/ffmpeg-kit-ios-https/libavformat.xcframework', 'Frameworks/ffmpeg-kit-ios-https/libavutil.xcframework', 'Frameworks/ffmpeg-kit-ios-https/libswresample.xcframework', 'Frameworks/ffmpeg-kit-ios-https/libswscale.xcframework'
         end


  2. 增加本地依赖

      安卓处理

      分析

      解决办法

    1. 把未失效的aar下载下来,放到libs目录

    2. 如果已经失效了,之前有用过,可以在缓存里面拿到,例如:/home-dir/.gradle/caches/modules-2/files-2.1/com.arthenica/ffmpeg-kit-https/5.1/e3aed1e3121a8d12b83ea62ea749b183e02c1803/ffmpeg-kit-https-5.1.aar

    3. 已经失效的版本(5.1),有缓存,没有pom文件,可以在android依赖内看到二级依赖的版本

    4. 修改 ffmpeg-kit/flutter/flutter/android/build.gradle 文件


    5.   安卓端暂时未报错,maven显示有版本,但是实际链接无法下载:

    6.   mvnrepository.com/artifact/co…

    7.   mvnrepository.com/artifact/co…

    8.   Loading ffmpeg-kit.
        Loaded ffmpeg-kit-https-arm64-5.1-20220929.
        flutter: Loaded ffmpeg-kit-flutter-ios-https-arm64-5.1.0.


    9. 获取版本依赖包,如果是未删除的,可以从pod install --verbose 的安装信息中拿到下载地址,如果已经被删除了,并且本地之前有安装过,可以从本地缓存获取

    10. 把缓存文件放到代码目录:/code-path/ffmpeg-kit/flutter/flutter/ios/Frameworks/ffmpeg-kit-ios-https

    11. 此时目录下包含ffmpeg-kit及ffmpeg的依赖

    12. 编译运行,控制台输入信息,成功

    13. 定制分支,不同分支对应不同版本,方便业务使用

//start:ffmpeg-kit-https  
// implementation 'com.arthenica:ffmpeg-kit-https:5.1'  
// FFmpegKit has been officially retired.Place dependent libraries locally  
// The Maven configuration is immutable and currently not required; it’s retained solely as a precaution.  
implementation files('./libs/ffmpeg-kit-https-5.1.aar')  
   
// end:ffmpeg-kit-https


  1. 运行失败,查看pom文件:repo1.maven.org/maven2/com/…


<dependencies>
            <dependency>
            <groupId>com.arthenica</groupId>
            <artifactId>smart-exception-java</artifactId>
            <version>0.2.1</version>
            <scope>compile</scope>
            </dependency>
            </dependencies>


  1. 把二级依赖smart-exception-java也加入进来,仍然运行失败,因为还有间接依赖:repo1.maven.org/maven2/com/…


<dependencies>
            <dependency>
            <groupId>com.arthenica</groupId>
            <artifactId>smart-exception-common</artifactId>
            <version>0.2.1</version>
            <scope>compile</scope>
            </dependency>
            </dependencies>


  1. 加入 smart-exception-common 依赖

  代码修改

dependencies {
            implementation 'androidx.annotation:annotation:1.5.0'
                //start:ffmpeg-kit-https
            //    implementation 'com.arthenica:ffmpeg-kit-https:6.0-2'
            //    FFmpegKit has been officially retired.Place dependent libraries locally
            //    The Maven configuration is immutable and currently not required; it’s retained solely as a precaution.
                implementation files('./libs/ffmpeg-kit-https-6.0-2.aar')

            //start:    smart-exception-java
                implementation files('./libs/smart-exception-java-0.2.1.jar')
                implementation files('./libs/smart-exception-common-0.2.1.jar')
            //    or
            //    implementation 'com.arthenica:smart-exception-java:0.2.1'
            //end:    smart-exception-java
            //    end:ffmpeg-kit-https
            }


使用

以上修改已经放到fork的仓库中:github.com/carl-design…

使用方式:

之前的使用代码:

ffmpeg_kit_flutter: 5.1.0
or
ffmpeg_kit_flutter: 6.0.3


新的使用代码:

ffmpeg_kit_flutter:
  git:
  url: git@github.com:carl-designlibro/ffmpeg-kit.git
  path: flutter/flutter
  ref: flutter_fix_retired_v6.0.3  # For version 6.0.3  
  # ref: flutter_fix_retired_v5.1.0  # For version 5.1.0


TODO

只处理了5.1.0和6.0.3的https版本