Flutter 使用ffigen生成ffmpeg的dart接口

Flutter视频渲染系列

第一章 Android使用Texture渲染视频

第二章 Windows使用Texture渲染视频

第三章 Linux使用Texture渲染视频

第四章 全平台FFI+CustomPainter渲染视频

第五章 Windows使用Native窗口渲染视频

第六章 桌面端使用texture_rgba_renderer渲染视频

第七章 使用ffigen生成ffmpeg的dart接口(本章)


文章目录

  • Flutter视频渲染系列
  • 前言
  • 一、如何实现
    • 1、添加ffigen插件
    • 2、创建ffigen.yaml
    • 3、ffigen命令生成dart代码
    • 4、关联ffmpeg库
    • 二、制作成插件
    • 三、使用示例
      • 1、添加插件
      • 2、调用ffmpeg
      • 总结

        前言

        前面几章介绍了flutter各种视频渲染的方法,视频渲染前显然是需要先获取视频流并解码,这些操作就需要用到ffmpeg,前面的几章的解码都是通过c语言调用ffmpeg,再将数据传输到dart渲染的。本章将提供一种生成ffmpeg dart接口的方法,直接用dart就可以调用ffmpeg进行拉流并解码然后显示。


        一、如何实现

        1、添加ffigen插件

        插件的地址是https://pub-web.flutter-io.cn/packages/ffigen。我们直接在pubspec.yaml添加依赖即可。

        依赖。ffigen不是运行库,是一个开发工具,通过执行命令来生成dart代码,所以放在dev_dependencies即可。

        ffigen: ^12.0.0
        

        2、创建ffigen.yaml

        创建一个yaml文件用于指定需要生成的头文件以及生成的对象名称等信息。ffigen.yaml的用法查看插件官网:https://pub-web.flutter-io.cn/packages/ffigen

        编写生成信息,需要指定头文件、过滤规则、以及名称转换规则

        #usage:cmdline "dart run ffigen --config ffmpeg_ffigen.yaml"  see more:https://pub-web.flutter-io.cn/packages/ffigen
        name: FFmpegAutoGen#生成的dart类名
        output:
          bindings: "lib/ffmpeg/ffmpeg_auto_gen.dart"#生成的dart文件路径
        headers:
          entry-points:
            #需要生成dart代码的ffmpeg头文件
            - "ffi/sdk/include/libavcodec/avcodec.h"
            #其他ffmpeg头文件略
          include-directives:
            - "**.**"
        compiler-opts:
          - "-I ffi/sdk/include"
        #名称过滤规则略
        #名称转换规则略
        

        3、ffigen命令生成dart代码

        ffmpeg_ffigen.yaml所在目录,命令行在执行。需要安装lvvm,不同平台具体查看https://pub-web.flutter-io.cn/packages/ffigen

        dart run ffigen --config ffmpeg_ffigen.yaml
        

        生成的dart文件

        生成的dart代码

        4、关联ffmpeg库

        新建一个ff.dart文件,将上述步骤生成代码与ffmpeg库关联起来,下列是ffmpeg4.x的示例。

        import 'dart:ffi';
        import 'dart:io';
        import 'package:ffmpeg_interface/ffmpeg/ffmpeg_auto_gen.dart';
        import 'package:ffi/ffi.dart';
        List _libs4 = [
          DynamicLibrary.open(Platform.isWindows ? "avutil-56.dll" : "libavutil.so"),
          DynamicLibrary.open(
              Platform.isWindows ? "swresample-3.dll" : "libswresample.so"),
          DynamicLibrary.open(Platform.isWindows ? "avcodec-58.dll" : "libavcodec.so"),
          DynamicLibrary.open(
              Platform.isWindows ? "postproc-55.dll" : "libpostproc.so"),
          DynamicLibrary.open(Platform.isWindows ? "swscale-5.dll" : "libswscale.so"),
          DynamicLibrary.open(
              Platform.isWindows ? "avformat-58.dll" : "libavformat.so"),
          DynamicLibrary.open(Platform.isWindows ? "avfilter-7.dll" : "libavfilter.so"),
          DynamicLibrary.open(
              Platform.isWindows ? "avdevice-58.dll" : "libavdevice.so"),
        ];
        Pointer _looup(String symbolName) { for (final i in _libs4) { if (i.providesSymbol(symbolName)) { return i.lookup(symbolName);
            }
          }
          throw Exception("can not find the symbol $symbolName from library");
        }
        final ff = FFmpegAutoGen.fromLookup(_looup);
        

        调用方法是

        final frame=ff.av_frame_alloc();
        

        或者将自动生成的FFmpegAutoGen对象去掉,直接将ffmpeg的方法都变成全局方法,方便调用,此处略。


        二、制作成插件

        将上述生成好的代码放入插件中,方便使用。

        flutter create ffmpeg_interface -t plugin --platforms windows,linux,android
        

        制作好的插件

        https://download.csdn.net/download/u013113678/89410377

        注:插件名称为ffmpeg_interface,包含ffmpeg的所有dart接口,ffmpeg接口版本为4.x,插件中只有ffmpeg接口,ffmpeg动态库(4.x)需要自行提供(因为考虑到不同项目需求不同,有些需要全功能的ffmpeg库,有些需要最小体积的ffmpeg库等,所以插件中不提供库)。目前只支持windows、linux、android。不支持macos和ios(由于没有设备,且网上暂时未搜索到VideoToolBox.h相关头文件下载,因此无法生成苹果相关的ffmpeg dart代码)。


        三、使用示例

        ffmpeg_interface插件的使用示例

        1、添加插件

        因为是本地插件,指定插件路径即可。比如放在项目的plugins/ffmpeg_interface,则path: plugins/ffmpeg_interface

        2、调用ffmpeg

        需要确保运行目录中有ffmpeg(4.x)的动态库。

        引用

        import 'package:ffmpeg_interface/ffmpeg/ffmpeg.dart';
        

        显示ffmpeg版本

        Text('Running on: $_platformVersion\n ffmpeg version is ${av_version_info().cast().toDartString()}')
        

        运行效果


        总结

        以上就是今天要讲述的内容,生成ffmpeg的dart代码在有了ffigen的情况下,容易了很多,但是也有一些细节需要注意的,尤其是想要生成所的接口,就需要确保所有头文件都包含,以及过滤掉不相关的符号以及将一些公有符号的下划线前缀去掉避免在dart中无法使用。