最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

HarmonyOS鎖屏音頻播放功能完整實(shí)現(xiàn)步驟

 更新時(shí)間:2026年06月10日 09:20:57   作者:90后晨仔  
HarmonyOS音頻模塊支持音頻業(yè)務(wù)的開發(fā),提供音頻相關(guān)的功能,主要包括音頻播放、音頻采集、音量管理和短音播放等,這篇文章主要介紹了HarmonyOS鎖屏音頻播放功能完整實(shí)現(xiàn)步驟的相關(guān)資料,需要的朋友可以參考下

引言

在音頻類應(yīng)用開發(fā)中,鎖屏狀態(tài)下的音頻播放與播控能力是一項(xiàng)核心用戶體驗(yàn)需求。當(dāng)用戶鎖屏后,系統(tǒng)播控中心需要展示當(dāng)前播放的音頻信息,并支持用戶進(jìn)行播放/暫停、切歌、快進(jìn)快退等操作。本文將詳細(xì)介紹如何在 HarmonyOS 上實(shí)現(xiàn)完整的鎖屏音頻播放功能。

一、技術(shù)棧與核心概念

1.1 AVSession Kit 簡介

AVSession Kit(音頻媒體會話套件)是 HarmonyOS 官方提供的一套用于管理媒體播放會話的 API。通過它,應(yīng)用可以將當(dāng)前播放的媒體信息(標(biāo)題、作者、封面、播放進(jìn)度等)同步到系統(tǒng)播控中心,并接收用戶從鎖屏、控制中心下發(fā)的播控指令。

1.2 核心類與接口

類/接口用途
createAVSession()創(chuàng)建媒體會話實(shí)例
AVSession.activate()激活會話,開始與系統(tǒng)播控中心交互
AVSession.setAVMetadata()設(shè)置媒體元數(shù)據(jù)(標(biāo)題、作者、封面等)
AVSession.setAVPlaybackState()設(shè)置播放狀態(tài)(播放/暫停、進(jìn)度、倍速等)
AVSession.on(event, callback)注冊播控命令監(jiān)聽器

1.3 會話類型(AVSessionType)

系統(tǒng)播控中心展示的按鈕樣式由會話類型決定:

  • audio 類型:顯示「上一首、播放/暫停、下一首」等音頻類按鈕
  • video 類型:顯示「快退、上一首、播放/暫停、下一首、快進(jìn)」等視頻類按鈕

選擇正確的會話類型對播控中心展示效果至關(guān)重要。

二、權(quán)限與后臺能力配置

2.1 后臺播放模式

要實(shí)現(xiàn)鎖屏后繼續(xù)播放,需要在應(yīng)用的能力配置中聲明后臺播放模式:

{
  "backgroundModes": ["audioPlayback"]
}

這告訴系統(tǒng):本應(yīng)用在后臺時(shí)需要保持音頻播放能力。

2.2 權(quán)限聲明

同時(shí)需要在模塊配置中聲明媒體播放權(quán)限:

{
  "requestPermissions": [
    {
      "name": "ohos.permission.MEDIA_PLAYBACK"
    }
  ]
}

三、完整實(shí)現(xiàn)步驟

步驟1:創(chuàng)建并激活 AVSession

在應(yīng)用啟動(dòng)或音頻播放初始化時(shí),創(chuàng)建媒體會話:

import { avSession as AVSessionKit } from '@kit.AVSessionKit';
import { common } from '@kit.AbilityKit';

// 創(chuàng)建 AVSession
const session = await AVSessionKit.createAVSession(
  context,            // 應(yīng)用上下文
  'AudioSession',     // 會話標(biāo)識
  'audio'             // 會話類型:'audio' 或 'video'
);

// 激活會話
await session.activate();

注意:創(chuàng)建會話后應(yīng)立即激活(activate),這樣系統(tǒng)播控中心才能感知到你的應(yīng)用在播放音頻。

步驟2:注冊播控命令監(jiān)聽器

監(jiān)聽用戶從鎖屏/控制中心發(fā)出的播控指令,并在回調(diào)中執(zhí)行對應(yīng)的播放邏輯:

// 播放
session.on('play', () => {
  // 調(diào)用播放器的播放方法
});

// 暫停
session.on('pause', () => {
  // 調(diào)用播放器的暫停方法
});

// 上一首
session.on('playPrevious', () => {
  // 切換到上一首音頻
});

// 下一首
session.on('playNext', () => {
  // 切換到下一首音頻
});

// 進(jìn)度跳轉(zhuǎn)(seek)
session.on('seek', (seekTime: number) => {
  // seekTime 單位為毫秒,調(diào)用播放器的 seek 方法
});

// 快退
session.on('rewind', () => {
  // 向后跳轉(zhuǎn)指定時(shí)長(如15秒)
});

// 快進(jìn)
session.on('fastForward', () => {
  // 向前跳轉(zhuǎn)指定時(shí)長(如15秒)
});

步驟3:同步媒體元數(shù)據(jù)

當(dāng)切換音頻時(shí),將新音頻的元數(shù)據(jù)同步到系統(tǒng)播控中心:

import { avSession as AVSessionKit } from '@kit.AVSessionKit';

const metadata: AVSessionKit.AVMetadata = {
  assetId: '1001',              // 媒體唯一ID
  title: '音頻標(biāo)題',             // 標(biāo)題
  artist: '作者名稱',            // 作者
  duration: 180000,             // 總時(shí)長(毫秒)
  mediaImage: pixelMapOrUrl     // 封面圖片(PixelMap 對象或圖片URL)
};

session.setAVMetadata(metadata).then(() => {
  // 元數(shù)據(jù)設(shè)置成功
}).catch((err) => {
  // 處理錯(cuò)誤
});

步驟4:同步播放狀態(tài)與進(jìn)度

播放狀態(tài)變化(播放/暫停)或進(jìn)度更新時(shí),同步給系統(tǒng):

const playbackState: AVSessionKit.AVPlaybackState = {
  state: AVSessionKit.PlaybackState.PLAYBACK_STATE_PLAY,  // 或 PLAYBACK_STATE_PAUSE
  speed: 1.0,
  position: {
    elapsedTime: 30000,   // 當(dāng)前播放位置(毫秒)
    updateTime: new Date().getTime()  // 更新時(shí)間戳
  },
  duration: 180000        // 總時(shí)長(毫秒)
};

session.setAVPlaybackState(playbackState);

關(guān)鍵提示position.updateTime 字段很重要,系統(tǒng)播控中心會根據(jù)這個(gè)時(shí)間戳和 elapsedTime 來計(jì)算當(dāng)前進(jìn)度顯示。

步驟5:封面圖片處理

鎖屏播控中心的封面圖片可以是以下兩種形式:

方式一:直接使用圖片 URL

const metadata: AVSessionKit.AVMetadata = {
  // ... 其他字段
  mediaImage: 'https://example.com/cover.jpg'
};

方式二:下載圖片并轉(zhuǎn)換為 PixelMap

如果需要更高質(zhì)量的展示效果,可以先下載圖片并轉(zhuǎn)換為 PixelMap 對象:

import { image } from '@kit.ImageKit';
import { http } from '@kit.NetworkKit';

async function downloadImageAsPixelMap(imageUrl: string): Promise<image.PixelMap | null> {
  try {
    // 1. 通過 HTTP 下載圖片數(shù)據(jù)
    const request = http.createHttp();
    const response = await request.request(imageUrl, {
      method: http.RequestMethod.GET,
      expectDataType: http.HttpDataType.ARRAY_BUFFER
    });
    const arrayBuffer = response.result as ArrayBuffer;
    request.destroy();

    // 2. 創(chuàng)建圖片源
    const imageSource = image.createImageSource(arrayBuffer);
    
    // 3. 創(chuàng)建 PixelMap
    const decodingOptions: image.DecodingOptions = {
      editable: false,
      desiredPixelFormat: 3,  // RGBA_8888
      desiredDynamicRange: image.DecodingDynamicRange.AUTO
    };
    const pixelMap = await imageSource.createPixelMap(decodingOptions);
    imageSource.release();
    
    return pixelMap;
  } catch (err) {
    return null;
  }
}

四、快進(jìn)與快退的實(shí)現(xiàn)

4.1 選擇正確的會話類型

要在鎖屏播控中心顯示快進(jìn)快退按鈕,需要使用 video 類型的會話:

// 使用 video 類型,播控中心將顯示快退和快進(jìn)按鈕
const session = await AVSessionKit.createAVSession(context, 'AudioSession', 'video');

4.2 實(shí)現(xiàn)快進(jìn)快退邏輯

// 快退 15 秒
function rewind(currentPosition: number): number {
  const REWIND_TIME = 15 * 1000;  // 15秒
  const newPosition = Math.max(0, currentPosition - REWIND_TIME);
  // 調(diào)用播放器 seek 到 newPosition
  // 同步新的播放狀態(tài)到 AVSession
  return newPosition;
}

// 快進(jìn) 15 秒
function fastForward(currentPosition: number, duration: number): number {
  const FORWARD_TIME = 15 * 1000;  // 15秒
  const newPosition = Math.min(duration, currentPosition + FORWARD_TIME);
  // 調(diào)用播放器 seek 到 newPosition
  // 同步新的播放狀態(tài)到 AVSession
  return newPosition;
}

// 注冊快退快進(jìn)監(jiān)聽器
session.on('rewind', () => {
  const newPos = rewind(currentPositionRef.current);
  currentPositionRef.current = newPos;
  syncPlaybackStateToSession(true, newPos, durationRef.current);
});

session.on('fastForward', () => {
  const newPos = fastForward(currentPositionRef.current, durationRef.current);
  currentPositionRef.current = newPos;
  syncPlaybackStateToSession(true, newPos, durationRef.current);
});

五、前后臺切換與狀態(tài)管理

5.1 從后臺恢復(fù)時(shí)的狀態(tài)處理

當(dāng)應(yīng)用從后臺(鎖屏狀態(tài))切換回前臺時(shí),需要注意:

  1. 不要中斷正在播放的音頻:如果播放器正在播放,保持播放狀態(tài)
  2. 同步最新的播放進(jìn)度:確保切換時(shí)的進(jìn)度是最新的
function onAppForeground(): void {
  // 檢查播放器狀態(tài)
  if (playerState === 'playing' || playerState === 'paused' || playerState === 'prepared') {
    // 播放器正在工作中,不中斷播放
    return;
  }
  
  // 其他恢復(fù)邏輯...
}

5.2 切換歌曲時(shí)的狀態(tài)重置

每次切換到新的音頻時(shí),必須重置以下狀態(tài):

  • currentTime(當(dāng)前播放時(shí)間):重置為 0
  • durationTime(總時(shí)長):重置為新音頻的時(shí)長
  • AVSession 播放狀態(tài):同步新的進(jìn)度為 0
// 切換歌曲時(shí)
function switchToNewAudio(): void {
  // 1. 重置本地狀態(tài)
  currentTime = 0;
  durationTime = 0;
  
  // 2. 設(shè)置新的音頻 URL 并開始播放
  
  // 3. 同步元數(shù)據(jù)到 AVSession
  session.setAVMetadata({
    assetId: newAudio.id,
    title: newAudio.title,
    artist: newAudio.artist,
    duration: newAudio.duration,
    mediaImage: newAudio.coverImage
  });
  
  // 4. 同步播放狀態(tài),進(jìn)度從 0 開始
  session.setAVPlaybackState({
    state: AVSessionKit.PlaybackState.PLAYBACK_STATE_PLAY,
    speed: 1.0,
    position: {
      elapsedTime: 0,
      updateTime: new Date().getTime()
    },
    duration: newAudio.duration
  });
}

六、常見問題與最佳實(shí)踐

問題1:鎖屏播控中心沒有立即顯示

原因:可能是元數(shù)據(jù)設(shè)置時(shí)機(jī)不對,或者會話未正確激活。

解決

  1. 確保 createAVSession() 后立即調(diào)用 activate()
  2. 在播放器開始播放后立即調(diào)用 setAVMetadata()setAVPlaybackState()
  3. 添加日志確認(rèn) API 調(diào)用成功

問題2:封面圖片不顯示

原因:封面圖片的格式或大小不符合要求,或者下載失敗。

解決

  1. 優(yōu)先使用 PixelMap 格式(比 URL 更可靠)
  2. 控制圖片大?。ńㄗh 400x400 像素以內(nèi))
  3. 確保圖片下載成功(添加錯(cuò)誤處理日志)

問題3:切換歌曲后進(jìn)度條顯示舊的進(jìn)度

原因:切換歌曲時(shí)沒有重置播放進(jìn)度和時(shí)長,導(dǎo)致 AVSession 保存了舊的進(jìn)度信息。

解決

  1. 每次切換歌曲時(shí)重置 currentTime = 0durationTime = 新時(shí)長
  2. 同步 setAVPlaybackState() 時(shí)將 elapsedTime 設(shè)為 0
  3. 同步 setAVMetadata() 時(shí)將 duration 設(shè)為新音頻的時(shí)長

問題4:解鎖后播放被中斷

原因:應(yīng)用從后臺切回前臺時(shí),onForeground 邏輯意外地重啟了播放器。

解決

  1. onForeground 回調(diào)中先檢查播放器當(dāng)前狀態(tài)
  2. 如果播放器正在 playing / paused / prepared,直接返回不做任何操作
  3. 只在播放器狀態(tài)異常時(shí)才執(zhí)行恢復(fù)邏輯

七、完整流程時(shí)序圖

下面是一次完整的鎖屏播放交互流程:

用戶操作                     應(yīng)用側(cè)                    系統(tǒng)播控中心
  │                            │                            │
  ├─ 點(diǎn)擊播放                 │                              │
  │ ─────────────────────────>│                            │
  │                            │ 1. 創(chuàng)建并激活 AVSession    │
  │                            │ 2. setAVMetadata()         │
  │                            │ 3. setAVPlaybackState()    │
  │                            │ ─────────────────────────> │
  │                            │                            │ 顯示音頻信息
  │                            │                            │ 和播放控制按鈕
  │                            │                            │
  ├─ 鎖屏                     │                            │
  │ ──────────────────────────┤───────────────────────────?│
  │                            │                            │ 鎖屏播控中心可見
  │                            │                            │
  │                            │                            │ 用戶點(diǎn)擊快進(jìn)
  │                            │ 4. on('fastForward')       │ <───────────────────
  │                            │ <───────────────────────── │
  │                            │                            │
  │                            │ 5. 播放器 seek +15秒       │
  │                            │ 6. setAVPlaybackState()    │
  │                            │ ─────────────────────────? │ 更新進(jìn)度條顯示
  │                            │                            │
  │                            │                            │ 用戶點(diǎn)擊下一首
  │                            │ 7. on('playNext')          │ <───────────────────
  │                            │ <───────────────────────── │
  │                            │                            │
  │                            │ 8. 切換音頻 + 重置進(jìn)度     │
  │                            │ 9. setAVMetadata()         │
  │                            │ 10. setAVPlaybackState()   │
  │                            │ ─────────────────────────? │ 顯示新音頻信息
  │                            │                            │

八、總結(jié)

實(shí)現(xiàn) HarmonyOS 鎖屏音頻播放的核心要點(diǎn):

  1. 正確配置權(quán)限和后臺模式:確保應(yīng)用在后臺可以繼續(xù)播放
  2. 創(chuàng)建和管理 AVSession 生命周期:與播放狀態(tài)保持一致
  3. 及時(shí)同步元數(shù)據(jù)和播放狀態(tài):讓鎖屏播控中心展示正確的信息
  4. 監(jiān)聽并響應(yīng)系統(tǒng)播控命令:實(shí)現(xiàn)完整的雙向交互
  5. 合理管理前后臺切換和歌曲切換:避免狀態(tài)錯(cuò)亂和播放中斷

通過本文介紹的方法,你可以實(shí)現(xiàn)一個(gè)體驗(yàn)流暢、與系統(tǒng)播控中心完美集成的音頻播放功能。

參考文檔

到此這篇關(guān)于HarmonyOS鎖屏音頻播放功能完整實(shí)現(xiàn)步驟的文章就介紹到這了,更多相關(guān)HarmonyOS鎖屏音頻播放內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 解決Git?Bash中文亂碼的問題

    解決Git?Bash中文亂碼的問題

    這篇文章介紹了解決Git?Bash中文亂碼的的方法,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • Debezium 與 Apache Kafka 的集成方式步驟詳解

    Debezium 與 Apache Kafka 的集成方式步驟詳解

    本文詳細(xì)介紹了如何將Debezium與Apache Kafka集成,包括集成概述、步驟、注意事項(xiàng)等,通過KafkaConnect,Debezium可以捕獲數(shù)據(jù)庫變更并實(shí)時(shí)發(fā)送到Kafka Topic,實(shí)現(xiàn)數(shù)據(jù)的實(shí)時(shí)同步和分析,感興趣的朋友一起看看吧
    2025-02-02
  • 用asp與php實(shí)現(xiàn)百度ping服務(wù)的代碼

    用asp與php實(shí)現(xiàn)百度ping服務(wù)的代碼

    分別用asp與php實(shí)現(xiàn)百度ping服務(wù)的代碼,需要的朋友可以參考下
    2012-02-02
  • 最新Adobe?2022全新上線?Adobe?2022永久免費(fèi)使用教程

    最新Adobe?2022全新上線?Adobe?2022永久免費(fèi)使用教程

    目前adobe2022的配置要求CPU至少是四核,運(yùn)行內(nèi)存至少是16GB,只支持windows10系統(tǒng),版本號是1809以及更高的版本,下面跟隨小編看下最新Adobe?2022全新上線?Adobe?2022永久免費(fèi)使用教程,感興趣的朋友一起看看吧
    2021-12-12
  • Git基礎(chǔ)之git與SVN版本控制優(yōu)缺點(diǎn)區(qū)別分析

    Git基礎(chǔ)之git與SVN版本控制優(yōu)缺點(diǎn)區(qū)別分析

    這篇文章主要為大家介紹了Git基礎(chǔ)之git與SVN優(yōu)缺點(diǎn)及區(qū)別分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-04-04
  • 如何將服務(wù)器上的python代碼通過QQ發(fā)送回傳信息(附實(shí)現(xiàn)方法)

    如何將服務(wù)器上的python代碼通過QQ發(fā)送回傳信息(附實(shí)現(xiàn)方法)

    這篇文章主要介紹了我將服務(wù)器上的python代碼通過QQ發(fā)送回傳信息(附實(shí)現(xiàn)方法),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-05-05
  • Vscode ChatGPT插件使用(無需代理注冊)

    Vscode ChatGPT插件使用(無需代理注冊)

    本文主要介紹了Vscode ChatGPT插件使用(無需代理注冊),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • delphi使用Chilkat 組件和庫從SFTP下載文件的方法

    delphi使用Chilkat 組件和庫從SFTP下載文件的方法

    這篇文章主要介紹了delphi使用Chilkat 組件和庫從SFTP下載文件的方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-08-08
  • webstorm配置eslint一鍵格式化代碼的方法詳解

    webstorm配置eslint一鍵格式化代碼的方法詳解

    在項(xiàng)目中我們?yōu)榱舜a書寫更規(guī)范,在項(xiàng)目中安裝ESlint幫助我們檢查語法,這篇文章主要給大家介紹了關(guān)于webstorm配置eslint一鍵格式化代碼的相關(guān)資料,需要的朋友可以參考下
    2024-02-02
  • 程序猿表白妹子的代碼神器

    程序猿表白妹子的代碼神器

    女生眼中的程序員,身上帶著好多標(biāo)簽“直男,宅,不懂浪漫,枯燥…”,但這是因?yàn)槟氵€沒有了解程序猿,程序猿也可以非常浪漫。程序猿用代碼來表白,把你中意的代碼發(fā)給她,看她能不能看懂
    2023-01-01

最新評論

乳山市| 黄陵县| 宁乡县| 汝城县| 乳山市| 大姚县| 蒙山县| 千阳县| 娱乐| 伊春市| 长寿区| 曲靖市| 龙江县| 徐州市| 隆尧县| 平陆县| 河西区| 阳山县| 五华县| 龙陵县| 巴塘县| 上林县| 福清市| 克什克腾旗| 上饶县| 密山市| 赤水市| 余江县| 襄汾县| 白河县| 左贡县| 揭阳市| 贺兰县| 新泰市| 兴和县| 云阳县| 公安县| 汽车| 苏州市| 南召县| 高台县|