Flutter OS 外接纹理适配简介
Flutter 在 OHOS 平台使用外接纹理,视频播放和相机预览使用方法是一致的,在注册纹理时,flutter engine 返回 surfaceId。图片场景,则是以 PixelMap 的形式注册到 flutter engine。
注:1. 一般而言,为了方便复用,会将 ohos 对接 flutter 外接纹理的功能代码作为一个 module 模块组件单独写一个插件注册到 Flutter engine
外接纹理背景色为白色,暂不支持修改
相机预览
实现说明
1. 实现插件,在 onAttachedToEngine 中,从入参 FlutterPluginBinding 中获取 TextureRegistry
const TAG = "CameraPlugin";
export class CameraPlugin implements FlutterPlugin, MethodCallHandler {
private binding: FlutterPluginBinding | null = null;
private mMethodChannel: MethodChannel | null = null;
private textureRegistry: TextureRegistry | null = null;
private textureId: number = -1;
private surfaceId: number = -1;
getUniqueClassName(): string {
return TAG;
}
onAttachedToEngine(binding: FlutterPluginBinding): void {
Log.e(TAG, "CameraPlugin onAttachedToEngine");
this.binding = binding;
this.mMethodChannel = new MethodChannel(binding.getBinaryMessenger(), "CameraControlChannel");
this.mMethodChannel.setMethodCallHandler(this);
this.textureRegistry = binding.getTextureRegistry();
}
复制代码
2. 在 onMethodCall 中实现注册纹理的响应方法
onMethodCall(call: MethodCall, result: MethodResult): void {
let method: string = call.method;
Log.e(TAG, "Received '" + method + "' message.");
switch (method) {
case "registerTexture":
this.registerCameraTexture();
result.success(this.textureId);
break;
case "startCamera":
this.startCamera();
result.success(null);
break;
case "unregisterTexture":
this.unregisterTexture(call.argument("textureId"));
result.success(null);
break;
}
}
复制代码
registerCameraTexture 中实现注册纹理,先获取 textureId,再使用该 textureId 去注册纹理到 flutter engine,返回 surfaceId。
registerCameraTexture(): void {
Log.i(TAG, "start register Camera texture in flutter engine");
this.textureId = this.textureRegistry!.getTextureId();
this.surfaceId = this.textureRegistry!.registerTexture(this.textureId)!.getSurfaceId();
}
复制代码
3. 在启动相机预览中,使用前面获取到的 surfaceId。
startSession() {
console.log(`[camera test] 已经授权,相机开始拍摄`);
let cameraManager = getCameraManager(getContext(this) as common.BaseContext);
let cameraDevices = getCameraDevices(cameraManager);
let cameraInput = getCameraInput(cameraDevices[0], cameraManager);
if (cameraInput != null) {
getSupportedOutputCapability(cameraDevices[0], cameraManager, cameraInput)
.then((supportedOutputCapability) => {
if (supportedOutputCapability != undefined) {
let previewOutput = getPreviewOutput(cameraManager, supportedOutputCapability, this.surfaceId.toString());
let captureSession = getCaptureSession(cameraManager);
if (captureSession != undefined && previewOutput != undefined && cameraInput != null) {
beginConfig(captureSession);
setSessionCameraInput(captureSession, cameraInput);
setSessionPreviewOutput(captureSession, previewOutput);
startSession(captureSession);
}
}
});
}
}
复制代码
4 . dart 侧通过 MethodChannel 触发,触发纹理注册和启动相机预览。
class _CameraPageState extends State<CameraPage> {
final MethodChannel _channel = MethodChannel('CameraControlChannel');
int textureId = -1;
@override
void initState() {
super.initState();
newTexture();
startCamera();
}
@override
void dispose() {
super.dispose();
if (textureId >= 0) {
_channel.invokeMethod('unregisterTexture', {'textureId': textureId});
}
}
void startCamera() async {
await _channel.invokeMethod('startCamera');
}
void newTexture() async {
int id = await _channel.invokeMethod('registerTexture');
setState(() {
this.textureId = id;
});
}
复制代码
预览画面使用获取到的 textureId 构造一个 texture widget。
Widget getTextureBody(BuildContext context) {
return Container(
width: 500,
height: 500,
child: Texture(
textureId: textureId,
),
);
}
复制代码
评论