Flutter 使用ffigen生成ffmpeg的dart接口

Flutter视频渲染系列

第一章 Android使用Texture渲染视频
第二章 Windows使用Texture渲染视频
第三章 Linux使用Texture渲染视频
第四章 全平台FFI+CustomPainter渲染视频
第五章 Windows使用Native窗口渲染视频
第六章 桌面端使用texture_rgba_renderer渲染视频
第七章 使用ffigen生成ffmpeg的dart接口(本章)



前言

前面几章介绍了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<DynamicLibrary> _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<T> _looup<T extends NativeType>(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<Utf8>().toDartString()}')

运行效果
在这里插入图片描述


总结

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

  • 12
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
你可以尝试使用`dart:io`库来实现TCP客户端,而使用Flutter来构建用户界面。 以下是一个简单的示例代码,它连接到目标服务器的IP地址和端口号,并发送一条消息。你可以将其作为起点来构建你自己的应用程序。 ```dart import 'dart:async'; import 'dart:io'; void main() async { // 连接到服务器 final socket = await Socket.connect('192.168.0.100', 8080); // 发送一条消息 socket.writeln('Hello, server!'); // 接收来自服务器的响应 socket.listen((data) { print('Received: $data'); }); } ``` 在Flutter中,你可以使用`TextEditingController`来获取用户在输入框中输入的文本,并使用`RaisedButton`来处理用户点击事件。例如: ```dart import 'dart:async'; import 'dart:io'; import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'TCP Client', home: MyHomePage(), ); } } class MyHomePage extends StatefulWidget { @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { final TextEditingController _controller = TextEditingController(); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('TCP Client'), ), body: Column( children: <Widget>[ TextField( controller: _controller, decoration: InputDecoration( hintText: 'Enter message', ), ), RaisedButton( child: Text('Send'), onPressed: () async { // 连接到服务器 final socket = await Socket.connect('192.168.0.100', 8080); // 发送用户输入的消息 final message = _controller.text; socket.writeln(message); // 接收来自服务器的响应 socket.listen((data) { print('Received: $data'); }); // 关闭连接 await socket.close(); }, ), ], ), ); } } ``` 请注意,这只是一个简单的示例,可能需要进行修改才能满足你的实际需求。例如,你可能需要添加错误处理、连接超时、重试逻辑等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CodeOfCC

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值