提示:閱讀此文章之前需要有C++開發(fā)經(jīng)驗(yàn),知道如何利用channel在C++和Dart之間做通信。
前言
一、PlatformView與Texture是什么?
二、使用步驟
1.在Flutter需要顯示視頻的地方聲明Texture組件
2.在Windows插件代碼里面創(chuàng)建TextureRenderer類
3.Flutter通過channel調(diào)用Windows插件創(chuàng)建Texture
4.Windows插件部分C++更新視頻RGBA,并通知flutter刷新界面
三、運(yùn)行效果演示
總結(jié)
前言
????????Flutter渲染視頻在移動端比較容易,可以用PlatformView,Texture等,但在Windows平臺無法使用PlatformView,原因是Windows的每一個窗口都是一個窗口句柄(HWND),如果強(qiáng)行的增加一?個PlatformView,那以后想在PlatformView所占據(jù)的位置彈出其他Flutter控件,會被遮蓋,因此Windows平臺視頻渲染只能用Texture,效率并不像網(wǎng)上提到的那么并。目前Windows平臺的示例代碼幾乎搜索不到,筆者在對接聲網(wǎng)和網(wǎng)易兩家公司RTC SDK的過程中,成功渲染了兩家公司的多媒體播放器和RTC提供的視頻,確定了Windows平臺使用Texture渲染視頻的方法,寫下此文章,希望對后來的開發(fā)者有些許幫助。
一、PlatformView與Texture是什么?
PlatformView主要適用于原生已經(jīng)很成熟的組件,嵌入到Flutter中,節(jié)省開發(fā)時間,例如WebView,視頻播放器等。由于Windows窗口機(jī)制的原因,在Windows平臺并不支持PlatformView。
Texture是一個顏色數(shù)據(jù)緩存區(qū),只要平臺將緩存區(qū)更新后,通知Flutter刷新界面即可。例如視頻渲染,只需要將當(dāng)前視頻幀的RGBA緩存區(qū)拷貝到Texture的緩存區(qū),然后Flutter刷新界面即可實(shí)現(xiàn)視頻渲染,這種方式更dart。
二、使用步驟
1.在Flutter需要顯示視頻的地方聲明Texture組件
代碼如下:
Container( color: Colors.black, child: Texture(textureId: (widget.viewModel.textureId)) );
2.在Windows插件代碼里面創(chuàng)建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調(diào)用Windows插件創(chuàng)建Texture
Flutter層面通過channel調(diào)用C++的createTextureRender函數(shù)后,會創(chuàng)建上面提到的第二步提到的TextureRender類實(shí)例,并與第一步提到的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刷新界面
這一步是收到播放器的視頻幀回調(diào)后,通知Flutter層面進(jìn)行渲染。所做的工作就是把視頻幀的RGBA緩存區(qū)拷貝到Flutter底層提供的pixel_buffer。?并通知刷新,至此,視頻渲染工作完成。緩存區(qū)的大小為 視頻寬度 * 視頻高度 * 4,之所以要乘以4,是因?yàn)槊總€顏色點(diǎn)由一個32位整數(shù)組成,每個顏色點(diǎn)的每一BIT排列順序?yàn)?RGBA,分別代表紅、綠、藍(lán)、透明度,值為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;
}
三、運(yùn)行效果演示
20220924-100136文章來源:http://www.zghlxwxcb.cn/news/detail-411077.html
總結(jié)
以上就是今天要講的內(nèi)容,F(xiàn)lutter在Windows上使用Texture進(jìn)行視頻渲染,對于不懂C++的人來說可能有點(diǎn)難懂。代碼只有最關(guān)鍵的部分,如果有疑問,可以回復(fù)留言交流。文章來源地址http://www.zghlxwxcb.cn/news/detail-411077.html
到了這里,關(guān)于Flutter 用Texture控件在Windows平臺實(shí)現(xiàn)視頻渲染的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!