写点什么

Flutter OHOS 外接纹理适配简介 - 视频播放

作者:flfljh
  • 2024-11-07
    湖南
  • 本文字数:2217 字

    阅读完需:约 7 分钟

Flutter OHOS 外接纹理适配简介-视频播放


Flutter 在 OHOS 平台使用外接纹理,视频播在注册纹理时,flutter engine 返回 surfaceId。


注:1. 一般而言,为了方便复用,会将 ohos 对接 flutter 外接纹理的功能代码作为一个 module 模块组件单独写一个插件注册到 Flutter engine


  1. 外接纹理背景色为白色,暂不支持修改

视频播放

实现说明

  1. 在 video_player_ohos 插件中实现 ohos 原生播放器:AVplayer。

  2. 实现插件,在 onAttachedToEngine 中,从入参 FlutterPluginBinding 中获取 TextureRegistry(此处放入 FlutterState 中封装)。


export class VideoPlayerPlugin implements FlutterPlugin, AbilityAware {
  private pluginBinding: FlutterPluginBinding | null = null;
  private videoPlayerApi: VideoPlayerApiImpl | null = null;
  private flutterState: FlutterState | null = null;

  getUniqueClassName(): string {
return TAG;
  }

  onAttachedToEngine(binding: FlutterPluginBinding): void {
this.pluginBinding = binding;
Log.i(TAG, "VideoPlayer onAttachedToEngine");
this.flutterState = new FlutterState(this.pluginBinding.getBinaryMessenger(), this.pluginBinding.getTextureRegistry());
  }


  1. 在创建视频播放器的方法中,(先从 FlutterState 拿出 TextureRegistry)同样的先获取 textureId,再注册纹理到 engine,得到 surfaceId(surfaceId 在返回的 SurfaceTextureEntry 对象中):


   let flutterRenderer = this.flutterState.getTextureRegistry();
let uri: string = arg.getUri();
let asset: string = arg.getAsset();
let header: Record<string, string= {};
arg.getHttpHeaders().forEach((value, key) ={
  header[key.toString()] = value.toString();
})
let textureId: number = flutterRenderer.getTextureId();
Log.i(TAG, "enter getRawFd, textureId=" + textureId);
let surfaceTextureEntry: SurfaceTextureEntry = flutterRenderer.registerTexture(textureId);
if (asset != null) {
  let avImageGenerator = await media.createAVImageGenerator();
  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)));
} else if (uri != null && uri.startsWith("fd://")) {
  let avImageGenerator = await media.createAVImageGenerator();
  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)));
}
let eventChannel: EventChannel = new EventChannel(this.flutterState.getBinaryMessenger(), "flutter.io/videoPlayer/videoEvents" + textureId.toString());
if (asset != null) {
  let rawFileDescriptor: resourceManager.RawFileDescriptor = await this.getContext().resourceManager.getRawFd("flutter_assets/" + asset);
  let videoPlayer = new VideoPlayer(playerModel, surfaceTextureEntry, rawFileDescriptor, null, eventChannel, this.AudioFocus, null);
  await videoPlayer.createAVPlayer();
  this.videoPlayers.set(textureId.toString(), videoPlayer);
} else if (uri != null) {
  let videoPlayer = new VideoPlayer(playerModel, surfaceTextureEntry, null, uri, eventChannel, this.AudioFocus, header);
  await videoPlayer.createAVPlayer();
  this.videoPlayers.set(textureId.toString(), videoPlayer);
}


  1. Videoplaye 构造方法中取出 surfaceId:


  constructor(playerModel: PlayerModel, textureEntry: SurfaceTextureEntry, url: resourceManager.RawFileDescriptor | null, iUrl: string | null, eventChannel: EventChannel, AudioFocus: Boolean, headers: Record<string, string| null) {
this.playerModel = playerModel;
this.textureEntry = textureEntry;
this.surfaceId = textureEntry.getSurfaceId().toString();
this.url = url;
this.iUrl = iUrl;
this.eventChannel = eventChannel;
this.headers = headers;
if (AudioFocus == true) {
  this.interruptMode = audio.InterruptMode.SHARE_MODE;
  Log.i(TAG, "set interruptMode : " + this.interruptMode);
}
Log.i(TAG, "surfaceId : " + this.surfaceId);
  }


  1. 在 AVplayer 是 AvplayerStatus.INITIALIZED 状态时,把 surfaceId 赋给 AVplayer

  2. case AvplayerStatus.INITIALIZED:
      this.avPlayer.surfaceId = this.surfaceId;
      this.avPlayer.prepare();
    
  3. 第三步创建 AVplayer 时,需要把 textureId 返回给 dart 层,dart 层得到该值,可以在 texture Widget 中使用该外接纹理完成渲染。


用户头像

flfljh

关注

还未添加个人签名 2024-10-29 加入

还未添加个人简介

评论

发布
暂无评论
Flutter OHOS外接纹理适配简介-视频播放_flfljh_InfoQ写作社区