Flutter 使用Texture实现Windows渲染视频
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渲染视频相关推荐
- Flutter 使用Texture实现Linux渲染视频
Flutter视频渲染系列 第一章 Android使用Texture渲染视频 第二章 Windows使用Texture渲染视频 第三章 Linux使用Texture渲染视频(本章) 第四章 全平台FF ...
- Flutter 使用Texture实现Android渲染视频
Flutter视频渲染系列 第一章 Android使用Texture渲染视频(本章) 第二章 Windows使用Texture渲染视频 第三章 Linux使用Texture渲染视频 第四章 全平台FF ...
- D3D Surface/Texture SDL DDraw渲染视频的区别和疑问
1 D3D Surface用起来比较简单,窗口改变时视频模糊,貌似是初始化窗口过小.全屏时有锯齿. StretchRect的Rect是显示区域宽高,这个值固定是初始值.改成随窗口变化,失败. 2 ...
- Flutter 用Texture控件在Windows平台实现视频渲染
提示:阅读此文章之前需要有C++开发经验,知道如何利用channel在C++和Dart之间做通信. 前言 一.PlatformView与Texture是什么? 二.使用步骤 1.在Flutter需要显 ...
- Windows平台OpenGL渲染视频
我之前写过一个简单的RTSP播放器(https://github.com/greenjim301/rtsp),当时的视频渲染是用D3D实现的.一直想尝试一下用OpenGL来渲染视频,但却不得空,最近有 ...
- windows 仍在设置此设备的类配置。 (代码 56)_谷歌发布Flutter Alpha:支持Windows
老孟导读:Windows来了,Mac.Linux.Web还远吗? 本文翻译自https://medium.com/flutter/announcing-flutter-windows-alpha-33 ...
- github windows系统监控_谷歌发布Flutter Alpha:支持Windows
老孟导读:Windows来了,Mac.Linux.Web还远吗? 本文翻译自https://medium.com/flutter/announcing-flutter-windows-alpha-33 ...
- 谷歌发布Flutter Alpha:支持Windows
老孟导读:Windows来了,Mac.Linux.Web还远吗? 本文翻译自https://medium.com/flutter/announcing-flutter-windows-alpha-33 ...
- OpenGL渲染视频(二)
目录 一.前言 二.openGL渲染介绍 1.OpenGl渲染管线的流程 2.顶点着色器的介绍 3.片元着色器的介绍 三.openGL着色器语言GLSL介绍 1.数据类型 2.限定符 3.二维图像渲染 ...
最新文章
- 基于rman 全备+归档在线搭建DG
- LeetCode--055--跳跃游戏(java)
- 十九、“文捷笔妙活如水,气定神闲稳若山。”(2021.6.7)
- LeetCode【1--两数之和】 LeetCode【2--两数相加】
- 乔布斯不在了,世界一大步,苹果一小步。
- Linux下安装配置Redis
- Mysql(集群)业务水平切割 垂直切割(Amoeba)
- Luogu1169 [ZJOI2007]棋盘制作
- 基于springboot网上订餐系统设计与实现
- 《Java语言程序设计与数据结构》编程练习答案(第十九章)(一)
- 【干货】32个EMC标准电路分享!
- Unity 创建fnt字体
- 小满 前端埋点SDK 带你 从0 开发 并且发布npm
- 治愈系英语笔记-1-特殊疑问句
- 思科WLC与AP无法正常Join
- python3 教程 下载图片资源
- (PADA)Partial Adversarial Domain Adaptation笔记
- beats 耳机 android,Beats app安卓,Beats app安卓耳机管理预约 v2.3.5 - 游戏盒子下载站...
- 决战面试(二)智力题考察
- reactos操作系统实现(39)
热门文章
- 【人工智能在图像识别技术上应用】
- 独孤思维:长期稳妥的赚钱方法
- VS2019 配色_NBA球员上脚:基德穿AJ13湖人配色,莫兰特的保罗乔治4代
- 发明计算机作文300字,发明作文300字
- 【图像处理】基于matlab边缘检测 Sobel、Roberts、Prewitt
- 安防百科-单了解ONVIF 协议
- 文字校验的工具类--中文,电话号码,邮箱,身份证等信息的校验
- “模型驱动”还不够!企业级低代码开发平台系统架构解密
- 华为防火墙查看日志命令_华为路由器防火墙配置命令总结(上)
- 机器学习——【2】史上最全“特征工程“介绍