18video性欧美19sex,欧美高清videosddfsexhd,性少妇videosexfreexxx片中国,激情五月激情综合五月看花,亚洲人成网77777色在线播放

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

在HarmonyOS中使用AVPlayer播放流媒體

HarmonyOS開發(fā)者 ? 來源:HarmonyOS開發(fā)者 ? 2025-10-15 11:45 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

一句話總結

HarmonyOS 中,使用 AVPlayer 播放流媒體,不是“能播就行”,而是要“穩(wěn)、準、快、可控”。

本文帶你掌握從創(chuàng)建到釋放的全鏈路操作,覆蓋 HLS/DASH/FLV 等主流協(xié)議,支持碼率切換、軌道選擇、自動重試、緩沖監(jiān)控等高階能力。

一、前置準備:權限 & 環(huán)境配置

1. 添加網絡權限

在 module.json5 中添加:

{
"reqPermissions":[
 {
  "name":"ohos.permission.INTERNET"
 }
]
}

否則訪問任何網絡資源都會失敗。

2. 引入 MediaKit 模塊

import{ media }from'@kit.MediaKit';

推薦使用 @kit.MediaKit,它是 HarmonyOS 官方提供的多媒體核心庫。

二、標準播放流程

順序不能亂,否則可能收不到事件、無法播放。

async avSetupStreamingMediaVideo() {
 if(this.context == undefined)return;
 // 創(chuàng)建avPlayer實例對象。
 this.avPlayer = await media.createAVPlayer();
 // 創(chuàng)建狀態(tài)機變化回調函數(shù)。
  awaitthis.setAVPlayerCallback((avPlayer: media.AVPlayer) => {
  this.percent = avPlayer.width / avPlayer.height; // 計算并保存視頻的寬高比
  this.setVideoWH(); // 調用方法更新視頻顯示區(qū)域的寬高
  this.durationTime =this.getDurationTime(); // 獲取視頻總時長
   setInterval(() => {// 更新當前時間。
   if(!this.isSwiping) {
    this.currentTime =this.getCurrentTime();
    }
   }, SET_INTERVAL);
  });
 // 設置播放資源。
 this.avPlayer.url ="http://media.iyuns.top:1000/http/720p_1m.mp4";
 //開始播放
  avPlay(): void {
  if(this.avPlayer) {
   try{
    this.avPlayer.play();
    }catch(e) {
     console.error(`${this.tag}: avPlay = ${JSON.stringify(e)}`);
    }
   }
  }

三、核心監(jiān)聽事件詳解(缺一不可)

0be55f2a-a8e0-11f0-8c8f-92fbcf53809c.png

示例:監(jiān)聽播放器狀態(tài)變化和監(jiān)聽播放時間

// 狀態(tài)機變化回調函數(shù)。
 this.avPlayer.on('stateChange',async(state, reason) => {
  if(this.avPlayer==null) {
   console.info(`${this.tag}: avPlayer has not init on state change`);
   return;
   }
 // 時間上報監(jiān)聽函數(shù)。
 this.avPlayer.on('timeUpdate',(time:number) =>{
  this.currentTime= time;
  });

四、主流協(xié)議支持一覽表

0c4fd594-a8e0-11f0-8c8f-92fbcf53809c.png

所有協(xié)議均支持 setSource() 直接接入,無需額外封裝。

五、高階功能實戰(zhàn)(讓你的播放器“聰明”起來)

1. 流媒體緩沖狀態(tài)

當下載速率低于片源的碼率時,會出現(xiàn)卡頓。此時,播放器檢測到緩沖區(qū)數(shù)據(jù)不足,會先緩沖一些數(shù)據(jù)再播放,避免連續(xù)卡頓。一次卡頓對應的緩沖事件上報過程為:BUFFERING_START-> BUFFERING_PERCENT 0 -> ... -> BUFFERING_PERCENT 100 -> BUFFERING_END。CACHED_DURATION在卡頓過程和播放過程中都會持續(xù)上報,直至下載至資源末尾。

import{ media }from'@kit.MediaKit';
// 類成員定義avPlayer
privateavPlayer: media.AVPlayer|null=null;
// 創(chuàng)建avPlayer實例對象。
this.avPlayer=awaitmedia.createAVPlayer();
// 監(jiān)聽當前bufferingUpdate緩沖狀態(tài)。
this.avPlayer.on('bufferingUpdate',(infoType : media.BufferingInfoType, value :number) =>{
console.info(`AVPlayer bufferingUpdate, infoType is${infoType}, value is${value}.`);
})

適用于直播、弱網環(huán)境下保障連續(xù)播放。

2. HLS 多碼率切換(自定義清晰度)

當前流媒體HLS協(xié)議流支持多碼率播放,默認情況下,播放器會根據(jù)網絡下載速度選擇合適的碼率。

通過on('availableBitrates')監(jiān)聽當前HLS協(xié)議流可用的碼率。如果監(jiān)聽的碼率列表長度為0,則不支持設置指定碼率。

import{ media }from'@kit.MediaKit';
// 類成員定義avPlayer
privateavPlayer: media.AVPlayer|null=null;
// 創(chuàng)建avPlayer實例對象。
this.avPlayer=awaitmedia.createAVPlayer();
// 監(jiān)聽當前HLS協(xié)議流可用的碼率。
this.avPlayer.on('availableBitrates',(bitrates:Array) =>{
console.info('availableBitrates called, and availableBitrates length is: '+ bitrates.length);
})

通過setBitrate接口設置播放碼率。若用戶設置的碼率不在可用碼率中,播放器將選擇最小且最接近的碼率。該接口只能在prepared/playing/paused/completed狀態(tài)下調用,可通過監(jiān)聽bitrateDone事件確認是否生效。

import{ media }from'@kit.MediaKit';
// 類成員定義avPlayer
privateavPlayer: media.AVPlayer|null=null;
// 創(chuàng)建avPlayer實例對象。
this.avPlayer=awaitmedia.createAVPlayer();
// 監(jiān)聽碼率設置是否生效。
this.avPlayer.on('bitrateDone',(bitrate:number) =>{
console.info('bitrateDone called, and bitrate value is: '+ bitrate);
})
// 設置播放碼率。
this.bitrate:number=96000;
this.avPlayer.setBitrate(this.bitrate);

可配合 UI 提供“清晰度選擇”按鈕。

3. DASH 起播策略設置(首幀更快加載)

為了保證在弱網環(huán)境下的播放體驗,AVPlayer將默認選擇最低的視頻分辨率開始播放,隨后依據(jù)網絡狀況自動調整。開發(fā)者可以根據(jù)具體需求,自定義DASH視頻的起播策略,包括設定視頻的寬度、高度以及色彩格式等參數(shù)。

// 自定義起播分辨率:1920×1080
import{ media }from'@kit.MediaKit';
letmediaSource : media.MediaSource= media.createMediaSourceWithUrl("http://test.cn/dash/aaa.mpd", {"User-Agent":"User-Agent-Value"});
letplaybackStrategy : media.PlaybackStrategy= {preferredWidth:1920,preferredHeight:1080};
this.avPlayer.setMediaSource(mediaSource, playbackStrategy);

弱網環(huán)境下優(yōu)先加載低碼率,提升首幀速度。

4. DASH 音視頻軌道切換(手動選清晰度/語言)

DASH流媒體資源包含多路不同分辨率、碼率、采樣率、編碼格式的音頻、視頻及字幕資源。默認情況下,AVPlayer會依據(jù)網絡狀況自動切換不同碼率的視頻軌道。開發(fā)者可根據(jù)需求選擇指定的音視頻軌道播放,此時自適應碼率切換策略將失效。

設置selectTrack生效的監(jiān)聽事件trackChange。

import{ media }from'@kit.MediaKit';
// 類成員定義avPlayer
privateavPlayer: media.AVPlayer|null=null;
// 創(chuàng)建avPlayer實例對象。
this.avPlayer=awaitmedia.createAVPlayer();
this.avPlayer.on('trackChange',(index:number, isSelect:boolean) =>{
console.info(`trackChange info, index:${index}, isSelect:${isSelect}`);
})
});

調用getTrackDescription獲取所有音視頻軌道列表。開發(fā)者可根據(jù)實際需求,基于MediaDescription各字段信息,確定目標軌道索引

// 以獲取1080p視頻軌道索引為例。
import{ media }from'@kit.MediaKit';
import{BusinessError}from'@kit.BasicServicesKit';
publicvideoTrackIndex:number=0;
// 類成員定義avPlayer
privateavPlayer: media.AVPlayer|null=null;
// 創(chuàng)建avPlayer實例對象。
this.avPlayer=awaitmedia.createAVPlayer();
this.avPlayer.getTrackDescription((error: BusinessError, arrList:Array) =>{
if(arrList !=null) {
 for(leti =0; i < arrList.length; i++) {
? ? ??let?propertyIndex:?Object?= arrList[i][media.MediaDescriptionKey.MD_KEY_TRACK_INDEX];
? ? ??let?propertyType:?Object?= arrList[i][media.MediaDescriptionKey.MD_KEY_TRACK_TYPE];
? ? ??let?propertyWidth:?Object?= arrList[i][media.MediaDescriptionKey.MD_KEY_WIDTH];
? ? ??let?propertyHeight:?Object?= arrList[i][media.MediaDescriptionKey.MD_KEY_HEIGHT];
? ? ??if?(propertyType == media.MediaType.MEDIA_TYPE_VID?&& propertyWidth ==?1920?&& propertyHeight ==?1080) {
? ? ? ??this.videoTrackIndex?=?parseInt(propertyIndex?.toString());?// 獲取1080p視頻軌道索引。
? ? ? }
? ? }
? }?else?{
? ??console.error(`getTrackDescription fail, error:${error}`);
? }
});

在音視頻播放過程中調用selectTrack選擇對應的音視頻軌道,或者調用deselectTrack取消選擇的音視頻軌道。

import{ media }from'@kit.MediaKit';
publicvideoTrackIndex:number=0;
 // 類成員定義avPlayer
privateavPlayer: media.AVPlayer|null=null;
// 創(chuàng)建avPlayer實例對象。
this.avPlayer=awaitmedia.createAVPlayer();
// 切換至目標視頻軌道。
this.avPlayer.selectTrack(this.videoTrackIndex);
// 取消選擇目標視頻軌道。
// this.avPlayer.deselectTrack(this.videoTrackIndex);

適合教育類、影視類 App,讓用戶自由選擇畫質/字幕/語音。

六、常見坑位 & 解決方案(避雷手冊)

0cab9406-a8e0-11f0-8c8f-92fbcf53809c.png

七、一個簡單的開發(fā)實例

import{ media } from'@kit.MediaKit';
import{ emitter } from'@kit.BasicServicesKit';
import{ display } from'@kit.ArkUI';
constTIME_ONE =60000;// 1分鐘的毫秒數(shù)。
constTIME_TWO =1000; // 1秒的毫秒數(shù)。
constSET_INTERVAL =1000;// 每秒更新一次當前播放時間。
constSPEED_ZERO: number =0;// 對應1.00x。
constSPEED_ONE: number =1; // 對應1.25x。
constSPEED_TWO: number =2; // 對應1.75x。
constSPEED_THREE: number =3;// 對應2.00x。
constPROPORTION: number =0.99;
let innerEventFalse: emitter.InnerEvent = {
 eventId:1,
 priority: emitter.EventPriority.HIGH
};
let innerEventTrue: emitter.InnerEvent = {
 eventId:2,
 priority: emitter.EventPriority.HIGH
};
let innerEventWH: emitter.InnerEvent = {
 eventId:3,
 priority: emitter.EventPriority.HIGH
};
@Entry
@Component
struct Index {
privateavPlayer: media.AVPlayer |null=null;
privatecontext: Context | undefined = undefined;
publicvideoTrackIndex: number =0;
publicbitrate: number =0;
@StatedurationTime: number =0;
@StatecurrentTime: number =0;
@Statepercent: number =0;
@StateisSwiping: boolean =false;
@Statetag: string ='StreamingMedia';
privatesurfaceId: string ='';
@StatespeedSelect: number = -1;
publicintervalID: number = -1;
@StatewindowWidth: number =300;
@StatewindowHeight: number =300;
@StatesurfaceW: number |null=null;
@StatesurfaceH: number |null=null;
@StateisPaused: boolean =true;
@StateXComponentFlag: boolean =false;
 getDurationTime(): number {
 returnthis.durationTime;
 }
 getCurrentTime(): number {
 returnthis.currentTime;
 }
 timeConvert(time: number): string {
  let min: number = Math.floor(time / TIME_ONE);
  let second: string = ((time % TIME_ONE) / TIME_TWO).toFixed(0);
 // return `${min}:${(+second < TIME_THREE ? '0' : '') + second}`;
? ? second = second.padStart(2,?'0');
? ??return?`${min}:${second}`;
? }
? async msleepAsync(ms: number): Promise {
 returnnew Promise((resolve, reject) => {
   setTimeout(() => {
    resolve(true)
   }, ms)
  })
 }
 async avSetupStreamingMediaVideo() {
 if(this.context == undefined)return;
 // 創(chuàng)建avPlayer實例對象。
 this.avPlayer = await media.createAVPlayer();
 // 創(chuàng)建狀態(tài)機變化回調函數(shù)。
  awaitthis.setAVPlayerCallback((avPlayer: media.AVPlayer) => {
  this.percent = avPlayer.width / avPlayer.height;
  this.setVideoWH();
  this.durationTime =this.getDurationTime();
   setInterval(() => {// 更新當前時間。
   if(!this.isSwiping) {
    this.currentTime =this.getCurrentTime();
    }
   }, SET_INTERVAL);
  });
 // 情況一:HTTP視頻播放。
 this.avPlayer.url ="http://media.iyuns.top:1000/http/720p_1m.mp4";
 // 情況二:HLS視頻播放。
 // this.avPlayer.url = "http://media.iyuns.top:1000/720-270-480.m3u8";
 // 情況三:DASH視頻播放。
 // this.avPlayer.url = "http://media.iyuns.top:1000/dash/720p/720-1/720-1.mpd";
 // 情況四:通過setMediaSource設置自定義頭域及播放優(yōu)選參數(shù)實現(xiàn)初始播放參數(shù)設置,以流媒體HTTP點播為例。
 /*
  let mediaSource : media.MediaSource = media.createMediaSourceWithUrl("http://media.iyuns.top:1000/http/720p_1m.mp4", {"":""});
  // 設置播放策略,設置為緩沖區(qū)數(shù)據(jù)為20s。
  let playbackStrategy : media.PlaybackStrategy = {preferredBufferDuration: 20};
  // 為avPlayer設置媒體來源和播放策略。
  this.avPlayer.setMediaSource(mediaSource, playbackStrategy);
  * */
 // 情況五:HLS切碼率。
 /*
  this.avPlayer.url = "https://upftimae.dailyworkout.cn/videos/course/c800f81a209b5ee7891f1128ed301db/4/master.m3u8";
  let bitrate: number = 0;
  // 監(jiān)聽當前HLS協(xié)議流可用的碼率。
  this.avPlayer.on('availableBitrates', (bitrates: Array) => {
   console.info('availableBitrates called, and availableBitrates length is: ' + bitrates.length);
   this.bitrate = bitrates[0]; // 保存需要切換的碼率。
  })
  // 監(jiān)聽碼率設置是否生效。
  this.avPlayer.on('bitrateDone', (bitrate: number) => {
   console.info('bitrateDone called, and bitrate value is: ' + bitrate);
  })
  * */
 // 情況六:DASH切換音視頻軌道。
 /*
  this.avPlayer.url = "http://poster-inland.hwcloudtest.cn/AiMaxEngine/ProductionEnvVideo/DASH_SDR_MultiAudio_MultiSubtitle_yinHeHuWeiDui3/DASH_SDR_MultiAudio_MultiSubtitle_yinHeHuWeiDui3.mpd";
  //
  this.avPlayer.getTrackDescription((error: BusinessError, arrList: Array) => {
   if (arrList != null) {
    for (let i = 0; i < arrList.length; i++) {
? ? ? ? ? let propertyIndex: Object = arrList[i][media.MediaDescriptionKey.MD_KEY_TRACK_INDEX];
? ? ? ? ? let propertyType: Object = arrList[i][media.MediaDescriptionKey.MD_KEY_TRACK_TYPE];
? ? ? ? ? let propertyWidth: Object = arrList[i][media.MediaDescriptionKey.MD_KEY_WIDTH];
? ? ? ? ? let propertyHeight: Object = arrList[i][media.MediaDescriptionKey.MD_KEY_HEIGHT];
? ? ? ? ? if (propertyType == media.MediaType.MEDIA_TYPE_VID && propertyWidth == 1920 && propertyHeight == 1080) {
? ? ? ? ? ? this.videoTrackIndex = parseInt(propertyIndex.toString()); // 獲取1080p視頻軌道索引。
? ? ? ? ? }
? ? ? ? }
? ? ? } else {
? ? ? ? console.error(`getTrackDescription fail, error:${error}`);
? ? ? }
? ? });
? ? * */
? }
??// HLS切換碼率。
? changeBitrate(bitrate: number) {
? ??if?(this.avPlayer ==?null) {
? ? ??return;
? ? }
? ??// 設置播放碼率。
? ??try?{
? ? ??this.avPlayer.setBitrate(bitrate);
? ? }?catch?(error) {
? ? ? console.error(`${this.tag}: setBitrate failed, error message?is?= ${JSON.stringify(error.message)}`);
? ? }
? }
??// DASH切換音視頻軌道。
? changeTrack(track: number) {
? ??if?(this.avPlayer ==?null) {
? ? ??return;
? ? }
? ??// 切換至目標視頻軌道。
? ??try?{
? ? ??this.avPlayer.selectTrack(track);
? ? }?catch?(error) {
? ? ? console.error(`${this.tag}: selectTrack failed, error message?is?= ${JSON.stringify(error.message)}`);
? ? }
? ??// 取消選擇目標視頻軌道。
? ??/*
? ? try {
? ? ? this.avPlayer.deselectTrack(track);
? ? } catch (error) {
? ? ? console.error(`${this.tag}: deselectTrack failed, error message is = ${JSON.stringify(error.message)}`);
? ? }
? ? * */
? }
? avPlay(): void {
? ??if?(this.avPlayer) {
? ? ??try?{
? ? ? ??this.avPlayer.play();
? ? ? }?catch?(e) {
? ? ? ? console.error(`${this.tag}: avPlay = ${JSON.stringify(e)}`);
? ? ? }
? ? }
? }
? avPause(): void {
? ??if?(this.avPlayer) {
? ? ??try?{
? ? ? ??this.avPlayer.pause();
? ? ? ? console.info(`${this.tag}: avPause==`);
? ? ? }?catch?(e) {
? ? ? ? console.error(`${this.tag}: avPause== ${JSON.stringify(e)}`);
? ? ? }
? ? }
? }
? async avSeek(seekTime: number, mode: SliderChangeMode): Promise {
 if(this.avPlayer) {
  try{
    console.info(`${this.tag}: videoSeek seekTime== ${seekTime}`);
   this.avPlayer.seek(seekTime,2);
   this.currentTime = seekTime;
   }catch(e) {
    console.error(`${this.tag}: videoSeek== ${JSON.stringify(e)}`);
   }
  }
 }
 avSetSpeed(speed: number): void {
 if(this.avPlayer) {
  try{
   this.avPlayer.setSpeed(speed);
    console.info(`${this.tag}: avSetSpeedenum${speed}`);
   }catch(e) {
    console.error(`${this.tag}: avSetSpeed == ${JSON.stringify(e)}`);
   }
  }
 }
// 注冊avplayer回調函數(shù)。
 async setAVPlayerCallback(callback: (avPlayer: media.AVPlayer) => void, vType?: number): Promise {
 // seek操作結果回調函數(shù)。
 if(this.avPlayer ==null) {
   console.error(`${this.tag}: avPlayer has notinit!`);
  return;
  }
 this.avPlayer.on('seekDone', (seekDoneTime) => {
   console.info(`${this.tag}: setAVPlayerCallback AVPlayer seek succeeded, seek timeis${seekDoneTime}`);
  });
 this.avPlayer.on('speedDone', (speed) => {
   console.info(`${this.tag}: setAVPlayerCallback AVPlayer speedDone, speedis${speed}`);
  });
 // error回調監(jiān)聽函數(shù),當avPlayer在操作過程中出現(xiàn)錯誤時調用reset接口觸發(fā)重置流程。
 this.avPlayer.on('error', (err) => {
   console.error(`${this.tag}: setAVPlayerCallback Invoke avPlayer failed ${JSON.stringify(err)}`);
  if(this.avPlayer ==null) {
    console.error(`${this.tag}: avPlayer has notiniton error`);
   return;
   }
  this.avPlayer.reset();
  });
 // 狀態(tài)機變化回調函數(shù)。
 this.avPlayer.on('stateChange', async (state, reason) => {
  if(this.avPlayer ==null) {
    console.info(`${this.tag}: avPlayer has notiniton state change`);
   return;
   }
   switch (state) {
    case'idle':// 成功調用reset接口后觸發(fā)該狀態(tài)機上報。
     console.info(`${this.tag}: setAVPlayerCallback AVPlayer state idle called.`);
    break;
    case'initialized':// avplayer 設置播放源后觸發(fā)該狀態(tài)上報。
     console.info(`${this.tag}: setAVPlayerCallback AVPlayer state initialized called.`);
    if(this.surfaceId) {
     this.avPlayer.surfaceId =this.surfaceId;// 設置顯示畫面,當播放的資源為純音頻時無需設置。
      console.info(`${this.tag}: setAVPlayerCallbackthis.avPlayer.surfaceId = ${this.avPlayer.surfaceId}`);
     this.avPlayer.prepare();
     }
    break;
    case'prepared':// prepare調用成功后上報該狀態(tài)機。
     console.info(`${this.tag}: setAVPlayerCallback AVPlayer state prepared called.`);
    this.avPlayer.on('bufferingUpdate', (infoType: media.BufferingInfoType, value: number) => {
      console.info(`${this.tag}: bufferingUpdate called, infoType value: ${infoType}, value:${value}}`);
     })
    this.durationTime =this.avPlayer.duration;
    this.currentTime =this.avPlayer.currentTime;
    this.avPlayer.play();// 調用播放接口開始播放。
     console.info(`${this.tag}:
      setAVPlayerCallback speedSelect: ${this.speedSelect}, duration: ${this.durationTime}`);
    if(this.speedSelect != -1) {
      switch (this.speedSelect) {
       case SPEED_ZERO:
       this.avSetSpeed(media.PlaybackSpeed.SPEED_FORWARD_1_00_X);
       break;
       case SPEED_ONE:
       this.avSetSpeed(media.PlaybackSpeed.SPEED_FORWARD_1_25_X);
       break;
       case SPEED_TWO:
       this.avSetSpeed(media.PlaybackSpeed.SPEED_FORWARD_1_75_X);
       break;
       case SPEED_THREE:
       this.avSetSpeed(media.PlaybackSpeed.SPEED_FORWARD_2_00_X);
       break;
      }
     }
     callback(this.avPlayer);
    break;
    case'playing':// play成功調用后觸發(fā)該狀態(tài)機上報。
     console.info(`${this.tag}: setAVPlayerCallback AVPlayer state playing called.`);
    if(this.intervalID != -1) {
      clearInterval(this.intervalID)
     }
    this.intervalID = setInterval(() => {// 更新當前時間。
      AppStorage.setOrCreate('durationTime',this.durationTime);
      AppStorage.setOrCreate('currentTime',this.currentTime);
     },100);
     let eventDataTrue: emitter.EventData = {
     data: {
      'flag':true
      }
     };
     let innerEventTrue: emitter.InnerEvent = {
      eventId:2,
      priority: emitter.EventPriority.HIGH
     };
     emitter.emit(innerEventTrue, eventDataTrue);
    break;
    case'completed':// 播放結束后觸發(fā)該狀態(tài)機上報。
     console.info(`${this.tag}: setAVPlayerCallback AVPlayer state completed called.`);
     let eventDataFalse: emitter.EventData = {
     data: {
      'flag':false
      }
     };
     let innerEvent: emitter.InnerEvent = {
      eventId:1,
      priority: emitter.EventPriority.HIGH
     };
     emitter.emit(innerEvent, eventDataFalse);
    if(this.intervalID != -1) {
      clearInterval(this.intervalID)
     }
    this.avPlayer.off('bufferingUpdate')
     AppStorage.setOrCreate('currentTime',this.durationTime);
    break;
    case'released':
     console.info(`${this.tag}: setAVPlayerCallback released called.`);
    break
    case'stopped':
     console.info(`${this.tag}: setAVPlayerCallback AVPlayer state stopped called.`);
    break
    case'error':
     console.error(`${this.tag}: setAVPlayerCallback AVPlayer state error called.`);
    break
    case'paused':
     console.info(`${this.tag}: setAVPlayerCallback AVPlayer state paused called.`);
    break
    default:
     console.info(`${this.tag}: setAVPlayerCallback AVPlayer state unknown called.`);
    break;
   }
  });
 // 時間上報監(jiān)聽函數(shù)。
 this.avPlayer.on('timeUpdate', (time: number) => {
  this.currentTime = time;
  });
 }
 aboutToAppear() {
 this.windowWidth = display.getDefaultDisplaySync().width;
 this.windowHeight = display.getDefaultDisplaySync().height;
 if(this.percent >=1) {// 橫向視頻。
  this.surfaceW = Math.round(this.windowWidth * PROPORTION);
  this.surfaceH = Math.round(this.surfaceW /this.percent);
  }else{// 縱向視頻。
  this.surfaceH = Math.round(this.windowHeight * PROPORTION);
  this.surfaceW = Math.round(this.surfaceH *this.percent);
  }
 this.isPaused =true;
 this.context =this.getUIContext().getHostContext();
 }
 aboutToDisappear() {
 if(this.avPlayer ==null) {
   console.info(`${this.tag}: avPlayer has notinitaboutToDisappear`);
  return;
  }
 this.avPlayer.release((err) => {
  if(err ==null) {
    console.info(`${this.tag}: videoRelease release success`);
   }else{
    console.error(`${this.tag}: videoRelease release failed, error messageis= ${JSON.stringify(err.message)}`);
   }
  });
  emitter.off(innerEventFalse.eventId);
 }
 onPageHide() {
 this.avPause();
 this.isPaused =false;
 }
 onPageShow() {
  emitter.on(innerEventTrue, (res: emitter.EventData) => {
  if(res.data) {
   this.isPaused = res.data.flag;
   this.XComponentFlag = res.data.flag;
   }
  });
  emitter.on(innerEventFalse, (res: emitter.EventData) => {
  if(res.data) {
   this.isPaused = res.data.flag;
   }
  });
  emitter.on(innerEventWH, (res: emitter.EventData) => {
  if(res.data) {
   this.windowWidth = res.data.width;
   this.windowHeight = res.data.height;
   this.setVideoWH();
   }
  });
 }
 setVideoWH(): void {
 if(this.percent >=1) {// 橫向視頻。
  this.surfaceW = Math.round(this.windowWidth * PROPORTION);
  this.surfaceH = Math.round(this.surfaceW /this.percent);
  }else{// 縱向視頻。
  this.surfaceH = Math.round(this.windowHeight * PROPORTION);
  this.surfaceW = Math.round(this.surfaceH *this.percent);
  }
 }
@Builder
 CoverXComponent() {
 // ...
 }
 build() {
 // ...
 }
}

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 流媒體
    +關注

    關注

    1

    文章

    200

    瀏覽量

    17139
  • avplayer
    +關注

    關注

    0

    文章

    5

    瀏覽量

    1027
  • HarmonyOS
    +關注

    關注

    80

    文章

    2144

    瀏覽量

    35227

原文標題:【HarmonyOS-媒體技術-AVPlayer】手把手教你用 AVPlayer 實現(xiàn)流媒體播放(ArkTS 詳解)

文章出處:【微信號:HarmonyOS_Dev,微信公眾號:HarmonyOS開發(fā)者】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    基于開源鴻蒙的AVPlayer視頻播控開發(fā)樣例

    開源鴻蒙生態(tài)建設中,多媒體能力是構建豐富用戶體驗的核心要素。本開發(fā)樣例基于AVPlayer實現(xiàn),AvPlayer支持流媒體和本地資源解析、
    的頭像 發(fā)表于 08-21 10:22 ?1761次閱讀
    基于開源鴻蒙的<b class='flag-5'>AVPlayer</b>視頻播控開發(fā)樣例

    鴻蒙開發(fā)-視頻播放器方案

    HarmonyOS系統(tǒng)中,提供兩種視頻播放開發(fā)的方案: [AVPlayer]:功能較完善的音視頻播放ArkTS/JS API,集成了
    發(fā)表于 02-19 17:20

    USB MP4流媒體帶來的好處

    USB MP4流媒體帶來的好處什么是流媒體呢?從硬件角度講是指一些便攜的,播放時不占用播放設備內存,可即時播放的數(shù)碼設備,例如U盤、MP3、
    發(fā)表于 05-24 18:19

    基于流媒體技術的手機視頻播放系統(tǒng)的研究與實現(xiàn)

    應用。根據(jù)多個市場調查來看,無線流媒體業(yè)務己經或者即將成為各大無線營運商的新的業(yè)務成長點,用戶數(shù)將逐年飛速的遞增。所以,手機端的流媒體播放器越來越成為新一代手機里面必備的軟件之一。本人的主要工作如下:1)綜合
    發(fā)表于 04-24 09:24

    嵌入式Linux機頂盒流媒體播放器的設計流程是什么?

    、數(shù)字化、操作簡單的基于計算機網絡通訊技術和多媒體應用的網絡化流媒體播放器已成為計算機、通信、消費電子產品領域(3C 產業(yè)-Computer、Communication、Consumer Electronics)技術發(fā)展的主要方向之一。
    發(fā)表于 08-22 06:56

    HarmonyOS HiSpark AI Camera】流媒體后視鏡

    項目名稱:流媒體后視鏡試用計劃:申請理由本人在車機應用開發(fā)領域有五年多的學習和開發(fā)經驗,曾設計過車機端中控和儀表應用層的開發(fā),對想借助發(fā)燒友論壇學習華為海思Hi3516DV300芯片實現(xiàn)流媒體后視鏡
    發(fā)表于 11-19 20:50

    如何去實現(xiàn)一種嵌入式流媒體播放器的設計?

    一種基于PXA270平臺的嵌入式流媒體播放器設計
    發(fā)表于 06-04 06:45

    什么是流媒體服務器?

    介紹一下什么是流媒體服務器?! ∑鋵?b class='flag-5'>流媒體服務器從廣義上來說,是屬于視頻服務器的一種。它主要是將視頻或者音頻文件進行數(shù)據(jù)壓縮,然后存儲等,遠程監(jiān)控及視頻應用方面,流媒體服務器都有廣泛
    發(fā)表于 06-30 09:28

    流媒體播放器QT4.8.5,如何安裝phonon呢?

    如題,我需要一款流媒體播放器,看其它帖子qt4.8.5推薦用phonon,但是提供的qt中沒有
    發(fā)表于 11-28 07:41

    HarmonyOS音頻開發(fā)指導:使用AVPlayer開發(fā)音頻播放功能

    播放API,有助于降低開發(fā)工作量,實現(xiàn)更佳的音頻播放效果。 ● ??AVPlayer??:功能較完善的音頻、視頻播放ArkTS/JS API,集成了
    發(fā)表于 10-19 14:26

    基于Directshow的H.264流媒體播放器設計

    H.264視頻編解碼標準具有高壓縮比和優(yōu)良的網絡親和性,被普遍認為是最有影響力的流媒體視頻壓縮標準。將Direct-show和H.264兩種相結合的流媒體播放器無疑將具有非常優(yōu)秀的性能
    發(fā)表于 03-11 11:36 ?5785次閱讀
    基于Directshow的H.264<b class='flag-5'>流媒體播放</b>器設計

    Symbian平臺上實現(xiàn)流媒體播放

    現(xiàn)有基于Symbian OS 的多媒體播放器的相關文獻中,討論了基于Symbian 平臺的流媒體播放器移動客戶端的設計原理,給出了指導性意見,并在結構、緩沖等方面給出了優(yōu)化建議,在此基礎
    發(fā)表于 09-29 15:56 ?2029次閱讀
    Symbian平臺上實現(xiàn)<b class='flag-5'>流媒體播放</b>器

    嵌入式流媒體播放系統(tǒng)的設計與實現(xiàn)

    基于推廣3G流媒體服務的目的,介紹流媒體工作原理的基礎之上,通過設計嵌入式播放終端支持流媒體播放
    發(fā)表于 11-03 16:09 ?61次下載

    IPTV機頂盒的流媒體播放器設計

    介紹了IPTV 機頂盒流媒體播放器的設計過程 ,組成了 IPTV 機頂盒的流媒體播放器。該播放器經測試 ,性能穩(wěn)定。
    發(fā)表于 02-20 10:25 ?2470次閱讀
    IPTV機頂盒的<b class='flag-5'>流媒體播放</b>器設計

    流媒體同步播放器ActiveX控件解析

    目前視頻播放器很多,可以播放各種各樣的文件和流,但大多只支持一個文件或一個流播放,若要播放多個文件就需手工打開多個播放器。
    發(fā)表于 11-01 11:10 ?0次下載
    多<b class='flag-5'>流媒體</b>同步<b class='flag-5'>播放</b>器ActiveX控件解析