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,  ),);  }
   复制代码
 
评论