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

这篇具有很好参考价值的文章主要介绍了Flutter 用Texture控件在Windows平台实现视频渲染。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

提示:阅读此文章之前需要有C++开发经验,知道如何利用channel在C++和Dart之间做通信。

前言

一、PlatformView与Texture是什么?

二、使用步骤

1.在Flutter需要显示视频的地方声明Texture组件

2.在Windows插件代码里面创建TextureRenderer类

3.Flutter通过channel调用Windows插件创建Texture

4.Windows插件部分C++更新视频RGBA,并通知flutter刷新界面

三、运行效果演示

总结


前言

        Flutter渲染视频在移动端比较容易,可以用PlatformView,Texture等,但在Windows平台无法使用PlatformView,原因是Windows的每一个窗口都是一个窗口句柄(HWND),如果强行的增加一 个PlatformView,那以后想在PlatformView所占据的位置弹出其他Flutter控件,会被遮盖,因此Windows平台视频渲染只能用Texture,效率并不像网上提到的那么并。目前Windows平台的示例代码几乎搜索不到,笔者在对接声网和网易两家公司RTC SDK的过程中,成功渲染了两家公司的多媒体播放器和RTC提供的视频,确定了Windows平台使用Texture渲染视频的方法,写下此文章,希望对后来的开发者有些许帮助。


一、PlatformView与Texture是什么?

PlatformView主要适用于原生已经很成熟的组件,嵌入到Flutter中,节省开发时间,例如WebView,视频播放器等。由于Windows窗口机制的原因,在Windows平台并不支持PlatformView。

Texture是一个颜色数据缓存区,只要平台将缓存区更新后,通知Flutter刷新界面即可。例如视频渲染,只需要将当前视频帧的RGBA缓存区拷贝到Texture的缓存区,然后Flutter刷新界面即可实现视频渲染,这种方式更dart。

二、使用步骤

1.在Flutter需要显示视频的地方声明Texture组件

代码如下:

 Container(
  color: Colors.black,
    child: Texture(textureId: (widget.viewModel.textureId))
);

2.在Windows插件代码里面创建TextureRenderer类

代码如下:

class TextureRenderer {
public:
    TextureRenderer(flutter::BinaryMessenger* messenger,
        flutter::TextureRegistrar* registrar);
bool TextureRenderer::onRenderVideoFrame(unsigned int uid, agora::media::IVideoFrameObserver::VideoFrame& videoFrame);

private:
    flutter::BinaryMessenger* messenger_ = nullptr;
    flutter::TextureRegistrar* registrar_ = nullptr;
    std::unique_ptr<TextureRenderer> fullScreenTextureRenderer_;    //全员看他纹理
    std::map<int64_t, std::unique_ptr<TextureRenderer>> renderers_; //通用的直播渲染纹理

}

TextureRenderer::TextureRenderer(flutter::BinaryMessenger *messenger,
                                 flutter::TextureRegistrar *registrar)
    : registrar_(registrar), 
      texture_(PixelBufferTexture(std::bind(&TextureRenderer::CopyPixelBuffer,
                                            this, std::placeholders::_1,
                                            std::placeholders::_2))),
      uid_(0), pixel_buffer_(new FlutterDesktopPixelBuffer{nullptr, 0, 0}) {
    texture_id_ = registrar->RegisterTexture(&texture_);
    channel_ = std::make_unique<MethodChannel<EncodableValue>>(
      messenger,
      "strong_live_player/texture_render_" + std::to_string(texture_id_),
      &flutter::StandardMethodCodec::GetInstance());
    channel_->SetMethodCallHandler([this](const auto &call, auto result) {
    this->HandleMethodCall(call, std::move(result));
  });
}

3.Flutter通过channel调用Windows插件创建Texture

Flutter层面通过channel调用C++的createTextureRender函数后,会创建上面提到的第二步提到的TextureRender类实例,并与第一步提到的Flutter层面的Texture控件绑定。

PlayerViewModel init(var callback) {
    AgoraMediaPlayerKit.channel.invokeMethod('createTextureRender', {
    }).then((value) {
      textureId = value;
      _channel = MethodChannel('agora_media_player_kit/texture_render_$value');
      _channel?.setMethodCallHandler(_platformCallHandler);
      callback();
      refresh();
    });
    return this;
  }

 4.Windows插件部分C++更新视频RGBA,并通知flutter刷新界面

这一步是收到播放器的视频帧回调后,通知Flutter层面进行渲染。所做的工作就是把视频帧的RGBA缓存区拷贝到Flutter底层提供的pixel_buffer。 并通知刷新,至此,视频渲染工作完成。缓存区的大小为 视频宽度 * 视频高度 * 4,之所以要乘以4,是因为每个颜色点由一个32位整数组成,每个颜色点的每一BIT排列顺序为 RGBA,分别代表红、绿、蓝、透明度,值为0~255。 代码如下:


bool TextureRenderer::onRenderVideoFrame(unsigned int uid, agora::media::IVideoFrameObserver::VideoFrame& videoFrame)
{
	std::lock_guard<std::mutex> lock_guard(mutex_);
	if (pixel_buffer_->width != videoFrame.width ||
		pixel_buffer_->height != videoFrame.height) {
		if (pixel_buffer_->buffer) {
			delete[] pixel_buffer_->buffer;
		}
		pixel_buffer_->buffer = new uint8_t[videoFrame.width * videoFrame.height * 4];
	}
	memcpy((void*)pixel_buffer_->buffer, videoFrame.yBuffer,
		videoFrame.width * videoFrame.height * 4);
	pixel_buffer_->width = videoFrame.width;
	pixel_buffer_->height = videoFrame.height;
	registrar_->MarkTextureFrameAvailable(texture_id_);
	return true;
}

三、运行效果演示

20220924-100136


总结

以上就是今天要讲的内容,Flutter在Windows上使用Texture进行视频渲染,对于不懂C++的人来说可能有点难懂。代码只有最关键的部分,如果有疑问,可以回复留言交流。文章来源地址https://www.toymoban.com/news/detail-411077.html

到了这里,关于Flutter 用Texture控件在Windows平台实现视频渲染的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Linux平台下基于OpenGL实现YUV视频渲染

    源码详见https://github.com/samxfb/linux-opengl-render

    2024年01月21日
    浏览(43)
  • 在Winform(C++/CLR)平台设计的(本地&在线)音乐播放器(基于WMP(Windows Media Player)控件实现)

    首先,祝贺阿根廷获得2022世界杯冠军! Winform作为一个比较老的平台,应用其实越来越少了,而即使设计Winform程序,多数人也会选择C#,而不是C++。但是题主在学校学习一门课程被迫使用了Winform/C++,并完成了课程作业,在此分享以下自己的作业,也当作学习纪录。在完成这

    2024年02月09日
    浏览(44)
  • 【unity shader】水体渲染基础-基于texture distortion的流体流动材质

    当液体静止时,它在视觉上与固体没有太大区别。 但大多数时候,我们的性能不一定支持去实现特别复杂的水物理模拟, 需要的只是在常规的静态材料的表面上让其运动起来。我们可以对网格的 UV 坐标实现动态变化,从而让表面的纹理效果实现变形的动态变化。 1.1. uv实时

    2024年02月03日
    浏览(54)
  • Flutter 实现任意控件拖动

    使用flutter开发是需要控件能拖动,比如画板中的元素,或者工具条,搜索框,每个都单独去实现拖动还是比较麻烦的,将拖动功能封装成一个控件,需要的时候直接使用拖动控件作为父控件这样就方便很多了。 使用translate变换位置即可 这一步不是必须的,但是如果需要限制

    2024年02月15日
    浏览(42)
  • 【Flutter】Flutter Text 控件实现下划线、删除线、虚线、加粗、斜体

    在 Flutter 开发中,我们经常需要对 Text 控件进行各种样式的设置,包括但不限于下划线、删除线、虚线、加粗和斜体等。这些样式的设置可以帮助我们更好地展示文本内容,提升用户体验。本文将详细介绍如何在 Flutter 3.10.0 或更高版本中实现这些效果。阅读本文后,你将掌握

    2024年02月06日
    浏览(39)
  • Flutter 实现按位置大小比例布局的控件

    做视频监控项目时需要需要展示多分屏,比如2x2、3x3、414等等,如果每一种分屏都单独实现会很麻烦,而且不能支持用户定制。最好的方式还是实现一个通用的分屏容器,而且采样比例计算位置大小,可以适配任意尺寸。 最直观的实现方式是获取控件宽高然后按比例计算,但

    2024年02月13日
    浏览(40)
  • Flutter一天一控件之ListTile(列表的实现)

    Flutter中的ListTile控件是一种常用的列表项控件,它可以用于显示列表中的每一个项,通常包含标题、副标题、图标等内容。ListTile控件的外观和行为类似于Android中的ListView中的列表项。 上面的代码中,我们创建了一个ListTile控件,包含一个左侧图标、一个标题、一个副标题和

    2024年02月05日
    浏览(32)
  • Flutter桌面开发 — Windows平台App安装失败或无法运行的问题及其解决方式

    文中所提及的问题,大多和Windows系统缺少Visual C++ 可再发行组件相关,所以先写怎样安装 Visual C++ Redistributable 即 vc_redist.exe 。 下载地址:https://www.microsoft.com/zh-CN/download/details.aspx?id=53587 点击下载,然后勾选对应的系统,然后点击next。下载完成后安装该软件。 错误描述:无法

    2024年02月04日
    浏览(73)
  • Android应用-Flutter实现丝滑的滑动删除、移动排序等-Dismissible控件详解

    Dismissible 是 Flutter 中用于实现可滑动删除或拖拽操作的一个有用的小部件。主要用于在用户对列表项或任何其他可滑动的元素执行删除或拖动操作时,提供一种简便的实现方式。 列表项删除: 允许用户在列表中通过滑动手势删除某个项。 左右滑动: 提供可自定义的背景,当

    2024年02月04日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包