Flutter视频渲染系列

第一章 Android使用Texture渲染视频
第二章 Windows使用Texture渲染视频(本章)
第三章 Linux使用Texture渲染视频
第四章 全平台FFI+CustomPainter渲染视频


文章目录

  • Flutter视频渲染系列
  • 前言
  • 一、如何实现?
    • 1、定义Texture控件
    • 2、创建Texture对象
    • 3、关联TextureId
    • 4、写入rgba
  • 二、示例
    • 1.使用ffmpeg解码播放
  • 三、完整代码
  • 总结

前言

flutter渲染视频的方法有多种,比如texture、platformview、ffi,其中texture是通过flutter自己提供的一个texture对象与dart界面关联后进行渲染,很容易搜索到android和ios的相关资料,但是windows却几乎找不到。通过查看一些开源库的代码,找出了再windows使用texture渲染的方法,在这里做一个简单的介绍。


一、如何实现?

1、定义Texture控件

在界面中定义一个Texture

Container(width: 640,height: 360,child: Texture(textureId: textureId,
))

2、创建Texture对象

在Windows本地代码中创建一个Texture对象。

int64_t texture_id;
FlutterDesktopPixelBuffer flutter_pixel_buffer;
memset(&flutter_pixel_buffer, 0, sizeof(flutter_pixel_buffer));
flutter::TextureVariant* texture = new flutter::TextureVariant(flutter::PixelBufferTexture([&](size_t width, size_t height) {//回调返回视频数据return &flutter_pixel_buffer;}));
//此texture_id 关联到界面上的Texture即可。
texture_id = texture_registrar_->RegisterTexture(texture);

3、关联TextureId

dart

  int textureId = -1;if (textureId < 0) {//调用本地方法获取textureId methodChannel.invokeMethod('startPreview',<String,dynamic>{'path':'test.mov'}).then((value) {textureId = value;setState(() {print('textureId ==== $textureId');});});}

c++

//此texture_id 关联到界面上的Texture即可。
texture_id = texture_registrar_->RegisterTexture(texture);
//本地方法返回texture_id
result->Success(flutter::EncodableValue(texture_id));

4、写入rgba

flutter_pixel_buffer.width = width;
flutter_pixel_buffer.height = height;
//data[0]为一帧rgba数据
flutter_pixel_buffer.buffer = data[0];
//调用此方法后,会出发texture的回调
texture_registrar->MarkTextureFrameAvailable(texture_id);

注:texture_registrar的获取方法为:

//定义TextureRegistrar对象
static flutter::TextureRegistrar* texture_registrar_;
//插件注册代码,这里的插件名为ffplayplugin,此处为官方生成代码
void FfplayPlugin::RegisterWithRegistrar(flutter::PluginRegistrarWindows* registrar) {// 略 此处为官方生成代码//获取TextureRegistrar对象texture_registrar_ = registrar->texture_registrar();
}

二、示例

1.使用ffmpeg解码播放

main.dart

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
MethodChannel methodChannel = MethodChannel('ffplay_plugin');
void main() {runApp(MyApp());
}
class MyApp extends StatelessWidget {// This widget is the root of your application.@overrideWidget build(BuildContext context) {return MaterialApp(title: 'Flutter Demo',theme: ThemeData(primarySwatch: Colors.blue,),home: MyHomePage(title: 'Flutter Demo Home Page'),);}
}class MyHomePage extends StatefulWidget {MyHomePage({Key? key, required this.title}) : super(key: key);final String title;@override_MyHomePageState createState() => _MyHomePageState();
}class _MyHomePageState extends State<MyHomePage> {int _counter = 0;int textureId = -1;Future<void> _createTexture() async {print('textureId = $textureId');//调用本地方法播放视频if (textureId < 0) {methodChannel.invokeMethod('startPreview',<String,dynamic>{'path':'https://sf1-hscdn-tos.pstatp.com/obj/media-fe/xgplayer_doc_video/flv/xgplayer-demo-360p.flv'}).then((value) {textureId = value;setState(() {print('textureId ==== $textureId');});});}}@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text(widget.title),),//控件布局body: Center(child: Row(mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[if (textureId > -1)ClipRect (child: Container(width: 640,height: 360,child: Texture(textureId: textureId,)),),],),),floatingActionButton: FloatingActionButton(onPressed: _createTexture,tooltip: 'createTexture',child: Icon(Icons.add),),);}
}

定义一个插件我这里是fflay_plugin。
fflay_plugin.cpp
相关对象的定义

static flutter::TextureRegistrar* texture_registrar_;
class PlayData
{public://Play中封装的ffmepg的操作Play* play;FlutterDesktopPixelBuffer flutter_pixel_buffer;int64_t texture_id;
};
static std::map<int64_t, PlayData*> playMap;

插件注册代码

//插件注册代码,这里的插件名为ffplayplugin,此处为官方生成代码
void FfplayPlugin::RegisterWithRegistrar(flutter::PluginRegistrarWindows* registrar)
{// 略 此处为官方生成代码//获取TextureRegistrar对象texture_registrar_ = registrar->texture_registrar();
}

methodChannel部分

if (method_call.method_name().compare("startPreview") == 0)
{PlayData* pd = new PlayData;memset(&pd->flutter_pixel_buffer, 0, sizeof(pd->flutter_pixel_buffer));//创建播放器pd->play = new Play;//创建textureflutter::TextureVariant* texture_ = new flutter::TextureVariant(flutter::PixelBufferTexture([=](size_t width, size_t height) -> const FlutterDesktopPixelBuffer* {return &pd->flutter_pixel_buffer;}));//注册texture pd->texture_id = texture_registrar_->RegisterTexture(texture_);playMap[pd->texture_id] = pd;//播放视频回调pd->play->Display = [=](unsigned char* data[8], int linesize[8], int width, int height, AVPixelFormat format) {//设置视频数据pd->flutter_pixel_buffer.width = width;pd->flutter_pixel_buffer.height = height;pd->flutter_pixel_buffer.buffer = data[0];//通知渲染texture_registrar_->MarkTextureFrameAvailable(pd->texture_id);};//获取参数flutter::EncodableMap arguments = std::get<flutter::EncodableMap>(*method_call.arguments());auto path = std::get<std::string>(arguments[flutter::EncodableValue("path")]);//开始播放pd->play->Start(path.c_str(), AV_PIX_FMT_RGBA);//设置返回值result->Success(flutter::EncodableValue(pd->texture_id));
}

效果预览


三、完整代码

https://download.csdn.net/download/u013113678/87075729
包含完整代码的flutter项目,版本3.0.4、3.3.8都成功运行,目录说明如下。


总结

以上就是今天要讲的内容,flutter在Windows上渲染视频,熟悉c++的话代码不算难,但是主要问题是没有资料,几乎唯一的方法就是阅读源码,这就对开发效率造成了阻碍。总的来说,使用texture渲染跟界面兼容性好,但是性能一般,毕竟使用rgba渲染限制了硬解的优化可能,不过对于一般使用场景还是适用的。

Flutter 使用Texture实现Windows渲染视频相关推荐

  1. Flutter 使用Texture实现Linux渲染视频

    Flutter视频渲染系列 第一章 Android使用Texture渲染视频 第二章 Windows使用Texture渲染视频 第三章 Linux使用Texture渲染视频(本章) 第四章 全平台FF ...

  2. Flutter 使用Texture实现Android渲染视频

    Flutter视频渲染系列 第一章 Android使用Texture渲染视频(本章) 第二章 Windows使用Texture渲染视频 第三章 Linux使用Texture渲染视频 第四章 全平台FF ...

  3. D3D Surface/Texture SDL DDraw渲染视频的区别和疑问

    1  D3D  Surface用起来比较简单,窗口改变时视频模糊,貌似是初始化窗口过小.全屏时有锯齿. StretchRect的Rect是显示区域宽高,这个值固定是初始值.改成随窗口变化,失败. 2  ...

  4. Flutter 用Texture控件在Windows平台实现视频渲染

    提示:阅读此文章之前需要有C++开发经验,知道如何利用channel在C++和Dart之间做通信. 前言 一.PlatformView与Texture是什么? 二.使用步骤 1.在Flutter需要显 ...

  5. Windows平台OpenGL渲染视频

    我之前写过一个简单的RTSP播放器(https://github.com/greenjim301/rtsp),当时的视频渲染是用D3D实现的.一直想尝试一下用OpenGL来渲染视频,但却不得空,最近有 ...

  6. windows 仍在设置此设备的类配置。 (代码 56)_谷歌发布Flutter Alpha:支持Windows

    老孟导读:Windows来了,Mac.Linux.Web还远吗? 本文翻译自https://medium.com/flutter/announcing-flutter-windows-alpha-33 ...

  7. github windows系统监控_谷歌发布Flutter Alpha:支持Windows

    老孟导读:Windows来了,Mac.Linux.Web还远吗? 本文翻译自https://medium.com/flutter/announcing-flutter-windows-alpha-33 ...

  8. 谷歌发布Flutter Alpha:支持Windows

    老孟导读:Windows来了,Mac.Linux.Web还远吗? 本文翻译自https://medium.com/flutter/announcing-flutter-windows-alpha-33 ...

  9. OpenGL渲染视频(二)

    目录 一.前言 二.openGL渲染介绍 1.OpenGl渲染管线的流程 2.顶点着色器的介绍 3.片元着色器的介绍 三.openGL着色器语言GLSL介绍 1.数据类型 2.限定符 3.二维图像渲染 ...

最新文章

  1. 基于rman 全备+归档在线搭建DG
  2. LeetCode--055--跳跃游戏(java)
  3. 十九、“文捷笔妙活如水,气定神闲稳若山。”(2021.6.7)
  4. LeetCode【1--两数之和】 LeetCode【2--两数相加】
  5. 乔布斯不在了,世界一大步,苹果一小步。
  6. Linux下安装配置Redis
  7. Mysql(集群)业务水平切割 垂直切割(Amoeba)
  8. Luogu1169 [ZJOI2007]棋盘制作
  9. 基于springboot网上订餐系统设计与实现
  10. 《Java语言程序设计与数据结构》编程练习答案(第十九章)(一)
  11. 【干货】32个EMC标准电路分享!
  12. Unity 创建fnt字体
  13. 小满 前端埋点SDK 带你 从0 开发 并且发布npm
  14. 治愈系英语笔记-1-特殊疑问句
  15. 思科WLC与AP无法正常Join
  16. python3 教程 下载图片资源
  17. (PADA)Partial Adversarial Domain Adaptation笔记
  18. beats 耳机 android,Beats app安卓,Beats app安卓耳机管理预约 v2.3.5 - 游戏盒子下载站...
  19. 决战面试(二)智力题考察
  20. reactos操作系统实现(39)

热门文章

  1. 【人工智能在图像识别技术上应用】
  2. 独孤思维:长期稳妥的赚钱方法
  3. VS2019 配色_NBA球员上脚:基德穿AJ13湖人配色,莫兰特的保罗乔治4代
  4. 发明计算机作文300字,发明作文300字
  5. 【图像处理】基于matlab边缘检测 Sobel、Roberts、Prewitt
  6. 安防百科-单了解ONVIF 协议
  7. 文字校验的工具类--中文,电话号码,邮箱,身份证等信息的校验
  8. “模型驱动”还不够!企业级低代码开发平台系统架构解密
  9. 华为防火墙查看日志命令_华为路由器防火墙配置命令总结(上)
  10. 机器学习——【2】史上最全“特征工程“介绍