HarmonyOS 使用XComponent 播放视频通过等比例缩放调整播放区域,通过截图功能截取出的图片显示异常

操作步骤:

1、视频等比例显示,调整播放区域。

this.xComponentController!.setXComponentSurfaceRect({offsetX:offX,offsetY:offY,surfaceWidth:videoWidth ,surfaceHeight:videoHeight});

2、读取pixmap:

public async getVideoFrame():Promise<PixelMap>{ 
 let rect:SurfaceRect = this.xComponentController?.getXComponentSurfaceRect() as SurfaceRect; 
 let region: image.Region = { x:rect.offsetX as number, y:rect.offsetY as number, size: { width: Math.trunc(rect.surfaceWidth) , height: Math.trunc(rect.surfaceHeight) } }; 
 let pix = await image.createPixelMapFromSurface(this.surfaceId, region); 
 return pix; 
}

x为0

y为160

width:1208

height: 680

3. 保存为图片

SaveButton({text:SaveDescription.SAVE_IMAGE}) 
 .onClick(async () => { 
  try { 
   let pixmap = await this.livePlayerModel.getVideoFrame(); 
   try{ 
    const imagePackerApi = image.createImagePacker(); 
    let packOpts : image.PackingOption = { format:"image/jpeg", quality:98 }; 
    let data = await imagePackerApi.packing(pixmap, packOpts); 
    let context = getContext(); 
    let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context); 
    let uri = await phAccessHelper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'jpg'); 
    const file = await fs.open(uri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); 
    let len = await fs.write(file.fd, data); 
    await fs.close(file.fd); 
   } 
   catch (error){ 
    this.onPlayerError(error); 
   } 
  } 
  catch (error){ 
   this.onPlayerError(error); 
  } 
 })

4. 保存后的图片如附件,上面为黑色,下面缺失一部分画面。

HarmonyOS
2024-11-12 10:47:02
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
FengTianYa
.xComponentController!.setXComponentSurfaceRect({offsetX:offX,offsetY:offY,surfaceWidth:videoWidth ,surfaceHeight:videoHeight});

设置宽高,还是显示的完整视频流,只是设置的显示的画面(surface)宽高。

let region: image.Region = { 
  x: rect.offsetX as number, 
  y: rect.offsetY as number, 
  size: { width: Math.trunc(rect.surfaceWidth), height: Math.trunc(rect.surfaceHeight) } 
}; 
let pix = await image.createPixelMapFromSurface(this.surfaceId, region);

​createPixelMapFromSurface接口是根据region把完整视频流的画面做裁剪,因为代码里传入的是显示surface的宽高,相较于完整视频流画面的宽高有缩小,所以导致保存的图片画面不全

如果希望截图完整视频播放画面,可以将该createPixelMapFromSurface接口入参region的宽高设置的和视频大小保持一致:​

let region: image.Region = { 
  x: rect.offsetX as number, 
  y: rect.offsetY as number, 
  size: { width: Math.trunc(avPlayer.width), height: Math.trunc(avPlayer.height) } 
};

demo中Region修改为:

let region: image.Region = { 
  x: rect.offsetX as number, 
  y: rect.offsetY as number, 
  size: { 
    width: Math.trunc(this.playVideoModel!.avPlayer?.width as number), 
    height: Math.trunc(this.playVideoModel!.avPlayer?.height as number) 
  } 
};
分享
微博
QQ
微信
回复
9天前
相关问题
HarmonyOS 列表视频滚动播放
244浏览 • 1回复 待解决
使用AVPlayer实现视频播放
1058浏览 • 1回复 待解决
HarmonyOS 怎么获取视频播放时长?
129浏览 • 1回复 待解决
avplayer播放视频demo
1308浏览 • 1回复 待解决
AVPlayer实现视频播放
764浏览 • 1回复 待解决
如何显示通过网络加载图片
2523浏览 • 1回复 待解决
使用AudioRenderer开发音频播放功能
1009浏览 • 1回复 待解决