Flutter跨平台外接纹理首帧鸿蒙化定制指南
Flutter外接纹理机制成功适配OpenHarmony平台,支持视频播放和相机预览等场景的原生内容渲染。本指南介绍了如何使用自定义功能设置纹理第一帧背景,包括颜色和图像两种方式。开发者可通过setTextureBackGroundColor方法设置纯色背景,或使用setTextureBackGroundPixelMap方法设置图像背景,提升视频加载阶段的用户体验。文中提供了详细的环境配置说明、A

插件介绍
Flutter外接纹理(External Texture)机制已成功适配OpenHarmony平台,为开发者提供了高效的原生内容渲染能力。在视频播放、相机预览等场景中,外接纹理能够直接渲染OpenHarmony平台的原生内容,实现无缝对接。
本指南将介绍如何使用Flutter OHOS外接纹理第一帧自定义功能,通过flutterRenderer.setTextureBackGroundColor和flutterRenderer.setTextureBackGroundPixelMap方法,在视频加载或播放之前设置纹理的背景颜色和图像,提升用户体验。
环境搭建
前置条件
- Flutter SDK 3.0.0及以上
- OpenHarmony SDK API 9及以上
- DevEco Studio 3.0及以上
项目配置
确保你的Flutter项目已经支持OpenHarmony平台,若尚未配置,可参考官方文档进行设置。
包的引入
由于本功能为自定义修改版本,需要以Git形式引入。在项目的pubspec.yaml文件中添加以下依赖配置:
dependencies:
external_texture_customization:
git:
url: "https://atomgit.com/"
path: "packages/external_texture_customization"
添加依赖后,执行flutter pub get命令获取包资源。
FlutterState与TextureRegistry
在使用外接纹理第一帧自定义功能前,需要了解FlutterState类和TextureRegistry接口:
FlutterState类
FlutterState类管理着与Flutter引擎的通信和纹理注册,是访问flutterRenderer的关键:
export class FlutterState {
private binaryMessenger: BinaryMessenger;
private textureRegistry: TextureRegistry;
constructor(binaryMessenger: BinaryMessenger, textureRegistry: TextureRegistry) {
this.binaryMessenger = binaryMessenger;
this.textureRegistry = textureRegistry;
}
getBinaryMessenger(): BinaryMessenger {
return this.binaryMessenger;
}
getTextureRegistry(): TextureRegistry {
return this.textureRegistry;
}
}
TextureRegistry接口
TextureRegistry是管理纹理的核心接口,flutterRenderer就是TextureRegistry的实例,通过它可以调用设置背景的相关方法:
// 获取flutterRenderer实例
TextureRegistry flutterRenderer = flutterState.getTextureRegistry();
API调用方法
1. 设置纹理背景颜色
使用setTextureBackGroundColor方法设置纹理的背景颜色:
/// 设置纹理背景颜色
/// textureId: 纹理的唯一标识
/// color: 32位十六进制颜色值,格式为0xAABBGGRR
flutterRenderer.setTextureBackGroundColor(textureId, 0xFF0000FF);
颜色值格式说明:
AA: Alpha通道,控制透明度(00完全透明,FF完全不透明)BB: 蓝色分量GG: 绿色分量RR: 红色分量
例如:0xFF0000FF表示不透明的红色背景。
2. 设置纹理背景图像
使用setTextureBackGroundPixelMap方法将图像设置为纹理的背景:
/// 设置纹理背景图像
/// textureId: 纹理的唯一标识
/// pixelMap: 图像的PixelMap对象
flutterRenderer.setTextureBackGroundPixelMap(textureId, pixelMap);
代码示例
示例1:设置红色背景
// 在纹理创建后设置背景颜色
int textureId = // 注册纹理后获取的ID
TextureRegistry flutterRenderer = flutterState.getTextureRegistry();
// 设置红色背景
flutterRenderer.setTextureBackGroundColor(textureId, 0xFF0000FF);
示例2:设置视频第一帧作为背景
下面是一个完整的示例,展示如何从视频中提取第一帧并设置为纹理背景:
import 'dart:async';
import 'package:media_kit/media_kit.dart';
// 获取视频第一帧并设置为纹理背景
Future<void> setVideoFirstFrameAsBackground(
int textureId,
FlutterState flutterState,
String videoPath
) async {
TextureRegistry flutterRenderer = flutterState.getTextureRegistry();
try {
// 创建AVImageGenerator实例
let avImageGenerator = await media.createAVImageGenerator();
// 设置视频源
if (videoPath.startsWith('assets/')) {
// 处理资产文件
avImageGenerator.fdSrc = await this.getContext().resourceManager.getRawFd(
"flutter_assets/" + videoPath.replaceFirst('assets/', '')
);
} else if (videoPath.startsWith('fd://')) {
// 处理本地文件
avImageGenerator.fdSrc = {
fd: Number.parseInt(videoPath.replace("fd://", ""))
};
}
// 提取第一帧图像
let pixelMap = await avImageGenerator.fetchFrameByTime(
0,
media.AVImageQueryOptions.AV_IMAGE_QUERY_NEXT_SYNC,
{
width: -1, // 使用原始宽度
height: -1 // 使用原始高度
}
);
// 设置为纹理背景
flutterRenderer.setTextureBackGroundPixelMap(textureId, pixelMap);
// 释放资源
avImageGenerator.release();
} catch (e) {
print('设置视频第一帧失败: $e');
// 设置默认背景颜色作为 fallback
flutterRenderer.setTextureBackGroundColor(textureId, 0xFF000000);
}
}
示例3:在video_player_ohos中的实际应用
以下是在video_player_ohos插件中使用这些方法的完整示例:
if (asset != null) {
Log.i(TAG, "asset create called, asset is" + asset);
let avMetaExtractor = await media.createAVMetadataExtractor();
avMetaExtractor.fdSrc = await this.getContext().resourceManager.getRawFd("flutter_assets/" + asset);
let mateData = await avMetaExtractor.fetchMetadata();
if (mateData.hasVideo == CommonConstants.YES) {
let avImageGenerator = await media.createAVImageGenerator();
Log.i(TAG, "asset video create");
avImageGenerator.fdSrc = await this.getContext().resourceManager.getRawFd("flutter_assets/" + asset);
let pixelMap = await avImageGenerator.fetchFrameByTime(0, media.AVImageQueryOptions.AV_IMAGE_QUERY_NEXT_SYNC, {
width: -1,
height: -1
});
this.pixelMaps.set(JSON.stringify(arg), pixelMap);
avImageGenerator.release();
flutterRenderer.setTextureBackGroundPixelMap(textureId, this.pixelMaps.get(JSON.stringify(arg)));
}
avMetaExtractor.release();
} else if (uri != null && uri.startsWith("fd://")) {
Log.i(TAG, "local create called, file is" + uri);
let avMetaExtractor = await media.createAVMetadataExtractor();
avMetaExtractor.fdSrc = {
fd: Number.parseInt(uri.replace("fd://", ""))
};
let mateData = await avMetaExtractor.fetchMetadata();
if (mateData.hasVideo == CommonConstants.YES) {
let avImageGenerator = await media.createAVImageGenerator();
Log.i(TAG, "local video create");
avImageGenerator.fdSrc = {
fd: Number.parseInt(uri.replace("fd://", ""))
};
let pixelMap = await avImageGenerator.fetchFrameByTime(0, media.AVImageQueryOptions.AV_IMAGE_QUERY_NEXT_SYNC, {
width: -1,
height: -1
});
this.pixelMaps.set(JSON.stringify(arg), pixelMap);
avImageGenerator.release();
flutterRenderer.setTextureBackGroundPixelMap(textureId, this.pixelMaps.get(JSON.stringify(arg)));
}
avMetaExtractor.release();
}
// 设置红色背景作为fallback
flutterRenderer.setTextureBackGroundColor(textureId, 0xFF0000FF);
注意事项
-
纹理ID有效性:确保在调用背景设置方法前,已经为纹理分配了有效的
textureId -
内存管理:使用
setTextureBackGroundPixelMap后,注意适当管理PixelMap的内存,避免内存泄漏 -
资源路径:确保视频或图像资源的路径正确,特别是资产文件需要放在
flutter_assets目录下 -
兼容性考虑:
- Flutter 3.7版本之前,外接纹理默认第一帧为白色背景
- Flutter 3.22版本之后,外接纹理默认没有背景色
- 建议同时设置背景颜色和背景图像,以确保在不同版本下都有良好的显示效果
-
错误处理:在实际应用中,建议添加适当的错误处理机制,确保在资源加载失败时能够提供合理的fallback方案
总结
Flutter OHOS外接纹理第一帧自定义功能为开发者提供了灵活的背景设置能力,通过flutterRenderer.setTextureBackGroundColor和flutterRenderer.setTextureBackGroundPixelMap方法,可以:
- 根据业务需求自定义纹理背景颜色
- 将视频第一帧作为纹理背景,提升用户体验
- 为不同场景提供个性化的视觉效果
这些功能的实现,解决了之前外接纹理默认白色背景无法满足所有业务场景的问题,特别是在视频播放等场景中,能够提供更加合理和专业的视觉呈现。
与iOS和Android平台相比,OpenHarmony平台的实现提供了类似的功能,但具有更好的灵活性和可定制性,为跨平台开发提供了统一的解决方案。
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
更多推荐


所有评论(0)