flutter处理音频/视频,对于ffmpeg的使用

8,273 阅读2分钟

1.简介

  • flutter_ffmpeg是基于MobileFFmpeg 同时包含FFmpeg和FFprobe
  • flutter_ffmpeg文档: pub.dev/packages/fl…
  • 倒入flutter_ffmpeg库: flutter_ffmpeg: ^0.2.10

2.使用

  • 初始化:
    final FlutterFFmpegConfig _flutterFFmpegConfig = new FlutterFFmpegConfig();
    final FlutterFFmpeg _flutterFFmpeg = new FlutterFFmpeg();
    
  • 获取基本信息:
    void startupTests() {
      getFFmpegVersion().then((version) => print("FFmpeg version: $version"));
      getPlatform().then((platform) => print("Platform: $platform"));
      getLogLevel().then(
          (level) => print("Old log level: " + LogLevel.levelToString(level)));
      setLogLevel(LogLevel.AV_LOG_INFO);
      getLogLevel().then(
          (level) => print("New log level: " + LogLevel.levelToString(level)));
      getPackageName().then((packageName) => print("Package name: $packageName"));
      getExternalLibraries().then((packageList) {
        packageList.forEach((value) => print("External library: $value"));
      });
    }
    Future<String> getFFmpegVersion() async {
      return await _flutterFFmpegConfig.getFFmpegVersion();
    }
    
    Future<String> getPlatform() async {
      return await _flutterFFmpegConfig.getPlatform();
    }
    
    Future<int> executeFFmpegWithArguments(List arguments) async {
      return await _flutterFFmpeg.executeWithArguments(arguments);
    }
    
    Future<int> executeFFmpeg(String command) async {
      return await _flutterFFmpeg.execute(command);
    }
    
    Future<void> cancel() async {
      return await _flutterFFmpeg.cancel();
    }
    
    Future<void> disableRedirection() async {
      return await _flutterFFmpegConfig.disableRedirection();
    }
    
    Future<int> getLogLevel() async {
      return await _flutterFFmpegConfig.getLogLevel();
    }
    
    Future<void> setLogLevel(int logLevel) async {
      return await _flutterFFmpegConfig.setLogLevel(logLevel);
    }
    
    Future<void> enableLogs() async {
      return await _flutterFFmpegConfig.enableLogs();
    }
    
    Future<void> disableLogs() async {
      return await _flutterFFmpegConfig.disableLogs();
    }
    
    Future<void> enableStatistics() async {
      return await _flutterFFmpegConfig.enableStatistics();
    }
    
    Future<void> disableStatistics() async {
      return await _flutterFFmpegConfig.disableStatistics();
    }
    
    Future<Map<dynamic, dynamic>> getLastReceivedStatistics() async {
      return await _flutterFFmpegConfig.getLastReceivedStatistics();
    }
    
    Future<void> resetStatistics() async {
      return await _flutterFFmpegConfig.resetStatistics();
    }
    
    Future<void> setFontconfigConfigurationPath(String path) async {
      return await _flutterFFmpegConfig.setFontconfigConfigurationPath(path);
    }
    
    Future<void> setFontDirectory(
        String fontDirectory, Map<String, String> fontNameMap) async {
      return await _flutterFFmpegConfig.setFontDirectory(
          fontDirectory, fontNameMap);
    }
    
    Future<String> getPackageName() async {
      return await _flutterFFmpegConfig.getPackageName();
    }
    
    Future<List<dynamic>> getExternalLibraries() async {
      return await _flutterFFmpegConfig.getExternalLibraries();
    }
    
    Future<int> getLastReturnCode() async {
      return await _flutterFFmpegConfig.getLastReturnCode();
    }
    
    Future<String> getLastCommandOutput() async {
      return await _flutterFFmpegConfig.getLastCommandOutput();
    }
    
    Future<String> registerNewFFmpegPipe() async {
      return await _flutterFFmpegConfig.registerNewFFmpegPipe();
    }
    
  • 使用
    //将pcm转化为mp3格式
    static Future<String> pcmToMp3(String url) async {
     String mp3url;
     String value = await fileUtil.saveVoiceDirectory("flutter");
     mp3url = value + "/${DateTime.now().millisecondsSinceEpoch}.mp3";
     String str =
         "-y -f s16le -ac 2 -ar 8000 -acodec pcm_s16le -i $url $mp3url";
     await _flutterFFmpeg.execute(str);
     return mp3url;
    }
    
  • 上述ffmpeg指令是将pcm格式音频文件转换成mp3格式,如果要做其他操作只需要将命令换成你需要的ffmpeg指令就好,是不是很简单~~(创建文件fileUtil.saveVoiceDirectory)
  • 最后就是调用这个方法啦:
     ffmpegUtil.pcmToMp3(url).then((newurl) {
           print(newurl);
     });
    

3. 提示

  1. android部分
  • 编辑android/build.gradle文件并在ext.flutterFFmpegPackage变量中定义包名称。

    ext {
        flutterFFmpegPackage  = "<package name>"
    }
    

    根据所需要的功能导包,如全部需要: ext.flutterFFmpegPackage = 'full'

  • 一些flutter_ffmpeg软件包包括libc++_shared.so本地库。如果添加了另一个还包括libc++_shared.so作为依赖项的库,则gradle失败并显示More than one file was found with OS independent path 'lib/x86/libc++_shared.so'错误消息。 您可以通过将以下代码块添加到中来解决此错误build.gradle。

    android {
     packagingOptions {
         pickFirst 'lib/x86/libc++_shared.so'
         pickFirst 'lib/x86_64/libc++_shared.so'
         pickFirst 'lib/armeabi-v7a/libc++_shared.so'
         pickFirst 'lib/arm64-v8a/libc++_shared.so'
      }
    }
    
  1. ios部分
  • 编辑ios/Podfile文件并修改默认# Plugin Pods块,如下所示。不要忘记在部分中指定软件包名称。
     #Prepare symlinks folder. We use symlinks to avoid having Podfile.lock
     #referring to absolute paths on developers' machines.
     system('rm -rf .symlinks')
     system('mkdir -p .symlinks/plugins')
     plugin_pods = parse_KV_file('../.flutter-plugins')
     plugin_pods.each do |name, path|
     symlink = File.join('.symlinks', 'plugins', name)
     File.symlink(path, symlink)
      if name == 'flutter_ffmpeg'
         pod name+'/<package name>', :path => File.join(symlink, 'ios')
       else
         pod name, :path => File.join(symlink, 'ios')
       end
     end
    
    同理按照所需要的功能引入,如全部需要:pod name+'/full'
  • flutter_ffmpeg要求ios的部署目标至少为9.3, 通过platform :ios, '9.3'在ios/Podfile文件中添加定义来解决此问题。
    platform :ios, '9.3'