HarmonyOS NEXT 基于原生能力獲取視頻縮略圖

大家好,我是 V 哥。
不得不佩服 HarmonyOS NEXT 原生能力的強(qiáng)大,如果你想在 鴻蒙 APP 開發(fā)中獲取視頻縮略圖,不用依賴第三方庫,就可以高效和穩(wěn)定的實(shí)現(xiàn),AVMetadataHelper就是一個(gè)好幫手,下面 V 哥整理實(shí)現(xiàn)步驟的代碼,幫助你快速理解,開整。

想要學(xué)習(xí)鴻蒙開發(fā),一定繞不開學(xué)習(xí) ArkTS 語言,V 哥寫了三本鴻蒙開發(fā)之路的書,第一本《鴻蒙 HarmonyOS NEXT開發(fā)之路 卷1 ArkTS 篇》已上市,歡迎鴻蒙開發(fā)愛好者讀一讀,可以幫助你快速系統(tǒng)的拿下 ArkTS,每二本鴻蒙應(yīng)用開發(fā)篇和項(xiàng)目實(shí)踐篇也即將上市,清華大學(xué)出版社正在緊張校稿中。

image.png

總結(jié)步驟:

  1. 導(dǎo)入必要的模塊,如media和fileio。
  2. 申請存儲(chǔ)權(quán)限。
  3. 獲取視頻文件的URI或路徑。
  4. 使用AVMetadataHelper獲取縮略圖的PixelMap。
  5. 將PixelMap轉(zhuǎn)換為ImageSource并顯示。
  6. 處理可能的錯(cuò)誤和異常。

在HarmonyOS NEXT中,可以通過媒體服務(wù)提供的原生能力獲取視頻縮略圖。以下是基于ArkTS的完整實(shí)現(xiàn)方案:

import avmetadata from '@ohos.multimedia.avmetadata';
import fileIo from '@ohos.fileio';

@Entry
@Component
struct VideoThumbnailExample {
  @State thumbnail: PixelMap | null = null;

  // 獲取視頻縮略圖的核心方法
  async getVideoThumbnail(videoPath: string) {
    try {
      // 1. 創(chuàng)建AVMetadataHelper實(shí)例
      const avMetadataHelper = avmetadata.createAVMetadataHelper();
      
      // 2. 設(shè)置視頻源(支持URI和文件描述符兩種方式)
      const fd = await fileIo.open(videoPath, 0o0); // 0o0表示只讀模式
      await avMetadataHelper.setSource(fd, avmetadata.AVMetadataSourceType.AV_METADATA_SOURCE_TYPE_FD);
      
      // 3. 獲取縮略圖(參數(shù)為時(shí)間戳微秒)
      const timeUs = 0; // 獲取首幀縮略圖
      this.thumbnail = await avMetadataHelper.fetchVideoFrameByTime(timeUs, {
        width: 320,   // 縮略圖寬度
        height: 240,  // 縮略圖高度
        colorFormat: 4 // ImageFormat.ARGB_8888
      });
      
      // 4. 釋放資源
      avMetadataHelper.release();
      fileIo.close(fd);
    } catch (err) {
      console.error('獲取縮略圖失敗:', err.code, err.message);
    }
  }

  build() {
    Column() {
      if (this.thumbnail) {
        // 顯示縮略圖
        Image(this.thumbnail)
          .width(320)
          .height(240)
          .margin(10)
      } else {
        Text('正在加載縮略圖...')
      }
      
      Button('選擇視頻')
        .onClick(async () => {
          // 這里需要實(shí)現(xiàn)視頻文件選擇邏輯
          const demoVideoPath = 'xxx'; // 替換為實(shí)際視頻路徑
          await this.getVideoThumbnail(demoVideoPath);
        })
    }
  }
}

實(shí)現(xiàn)原理說明:

  1. 核心API:
    ? @ohos.multimedia.avmetadata:提供音視頻元數(shù)據(jù)操作能力
    ? createAVMetadataHelper:創(chuàng)建元數(shù)據(jù)操作實(shí)例
    ? fetchVideoFrameByTime:關(guān)鍵方法,按指定時(shí)間戳獲取視頻幀

  2. 參數(shù)配置:
    ? 時(shí)間戳選擇:timeUs參數(shù)支持微秒級精度(0表示首幀)
    ? 輸出尺寸:建議保持視頻原始寬高比
    ? 顏色格式:推薦使用ARGB_8888格式(數(shù)值4)

  3. 權(quán)限要求:
    module.json5中添加權(quán)限聲明:

   "requestPermissions": [
     {
       "name": "ohos.permission.READ_MEDIA",
       "reason": "需要讀取視頻文件"
     }
   ]
  1. 性能優(yōu)化:
    ? 緩存機(jī)制: 對已生成的縮略圖進(jìn)行本地緩存
    ? 異步操作: 所有IO操作都應(yīng)在異步任務(wù)中執(zhí)行
    ? 資源釋放: 必須及時(shí)調(diào)用release()釋放Native資源

擴(kuò)展功能實(shí)現(xiàn):

  1. 多幀縮略圖獲?。?/strong>
async getMultiThumbnails(videoPath: string, intervals: number) {
  const helper = avmetadata.createAVMetadataHelper();
  const fd = await fileIo.open(videoPath, 0o0);
  await helper.setSource(fd);
  
  const duration = await helper.getDuration();
  const step = duration / intervals;
  
  const thumbnails = [];
  for (let i = 0; i < intervals; i++) {
    const frame = await helper.fetchVideoFrameByTime(i * step);
    thumbnails.push(frame);
  }
  
  helper.release();
  fileIo.close(fd);
  return thumbnails;
}
  1. 自定義尺寸縮略圖:
const options = {
  width: 480,
  height: 360,
  colorFormat: 4,
  frameStrategy: avmetadata.FrameStrategy.FRAME_STRATEGY_BEST_FIT // 自動(dòng)適配最佳尺寸
};

注意事項(xiàng):

  1. 支持的視頻格式:MP4、3GP、MKV、AVI等主流格式

  2. 錯(cuò)誤處理建議:

try {
  // 獲取縮略圖操作
} catch (err) {
  if (err.code === 5400101) {
    console.error('文件格式不支持');
  } else if (err.code === 5400103) {
    console.error('指定時(shí)間超出視頻時(shí)長');
  }
}
  1. 性能指標(biāo)參考:
  • 1080P視頻首幀獲取時(shí)間:< 300ms
  • 單幀處理內(nèi)存消耗:< 15MB

利用HarmonyOS的原生媒體處理能力,相比第三方庫具有更好的性能表現(xiàn)和格式兼容性。實(shí)際開發(fā)也會(huì)結(jié)合LazyForEach實(shí)現(xiàn)視頻列表的縮略圖懶加載,同時(shí)配合緩存機(jī)制優(yōu)化用戶體驗(yàn)。關(guān)注威哥愛編程,鴻蒙開發(fā)一定行。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容