媒体库中的音频文件无法播放分析报告

鸿蒙小绿娃 2023-03-13 19:03:56

1 关键字

MediaLibrary;音频;AudioPlayer;

2 问题描述

开发板:WGR

OH 版本:3.2.3.5

问题现象:通过MediaLibrary的getAllObject方法获取的FileAsset对象的uri地址值设置给AudioPlayer的src属性不能实现播放。

3 问题原因

3.1 正常机制

从MediLibrary中获取的音频文件能通过AudioPlayer进行播放。

3.2 异常机制

将MediaLibrary中获取的音频文件对应的FileAsset对象的uri地址值设置给AudioPlayer的src属性不能实现播放。

4 解决方案

通过FileAsset对象的open方法获取对应音频文件的fd(文件描述符),将获取的fd拼接上fd://组成uri,再将uri设置给AudioPlayer的src属性能够实现播放。

5 定位过程

1.在媒体库中创建音频文件,核心代码如下:

 createAudioFileAsset() {
    let mediaType = mediaLibrary.MediaType.AUDIO;
    let DIR_IMAGE = mediaLibrary.DirectoryType.DIR_AUDIO;
    const path = await this.iMediaLibrary.getPublicDirectory(DIR_IMAGE);
    console.info(`mediaTest:path:${path}`);
    this.iMediaLibrary.createAsset(mediaType, "audiotest.mp3", path)
    .then((result) => {
      console.info(`mediaTest:create fileAsset sucess:${JSON.stringify(result)}`);
    })
    .catch((e) => {
        console.info(`mediaTest:create fileAsset fail`)
    })
  }

这里仅创建了一个空的mp3文件,对应的文件目录:/storage/media/100/local/files/Audios/audiotest.mp3

2.将预先准备好的mp3文件通过命令发送到媒体库中。

hdc_std  file send  D:\audiotest.mp3  /storage/media/100/local/files/Audios/audiotest.mp3

3.获取之前放置的mp3文件并进行播放,核心代码如下:

import mediaLibrary from '@ohos.multimedia.mediaLibrary';
import media from '@ohos.multimedia.media';

class MediaService {
  private iMediaLibrary: mediaLibrary.MediaLibrary;
  private audioPlayer: media.AudioPlayer;
  ...
  ...
  createMediaPlayer() {
    this.audioPlayer = media.createAudioPlayer();
    this.audioPlayer.loop = true; //设置循环播放
    this.registerListenerForAudioPlayer();
    console.info(`mediaTest:create audioPlayer success`);
  }

  registerListenerForAudioPlayer() {
    this.audioPlayer.on("dataLoad", () => {
      console.info(`mediaTest:data load success`);
      this.audioPlayer.play();
    })
    this.audioPlayer.on("play", () => {
      console.info(`mediaTest:play success`);
    })
    this.audioPlayer.on("pause", () => {
      console.info(`mediaTest:pause successs`);
    })
    this.audioPlayer.on("finish", () => {
      console.info(`mediaTest:finish success`)
    })
  }

  async getAudioSource() {
    let fileAssetResult = await this.iMediaLibrary.getFileAssets({
      selections: mediaLibrary.FileKey.MEDIA_TYPE + '= ?',
      selectionArgs: [mediaLibrary.MediaType.AUDIO.toString()],
    });
    console.info(`mediaTest:getfileAssets success:${JSON.stringify(fileAssetResult)}`);
    let fileAssetArray = await fileAssetResult.getAllObject();
    for (let i = 0;i < fileAssetArray.length; i++) {
      console.info(`mediaTest:getAllObject success:${JSON.stringify(fileAssetArray[i].uri)}`);
    }

    let path = fileAssetArray[0].uri; //获取数组中第一个音频文件的uri
    this.audioPlayer.src = path;
  }
  ...
  ...
}

let mediaService: MediaService = new MediaService();

export default mediaService;

在WGR上运行后无法播放之前放置的mp3文件,且没有触发在AudioPlayer注册的回调函数。

打印日志:

08-02 10:04:44.283  9060  9060 I A0fefe/JsApp: mediaTest:getfileAssets success:{}
08-02 10:04:44.284  9060  9060 I A0fefe/JsApp: mediaTest:getAllObject success:"datashare:///media/audio/16"

4.在sdk中查看AudioPlayer的src属性,发现AudioPlayer仅支持播放fd://xx、file://xx、http://xn--xxhttps-if7nh96s//xx%E5%9B%9B%E7%A7%8D%E8%B7%AF%E5%BE%84%E7%B1%BB%E5%9E%8B%E7%9A%84%E9%9F%B3%E9%A2%91%E6%96%87%E4%BB%B6%E3%80%82

5.尝试使用fd://路径类型播放,更改上述部分代码如下:

async getAudioSource(){
   console.info(`mediaTest:getfile uri start:${JSON.stringify(this.iMediaLibrary)}`);
   let fileAssetResult=await this.iMediaLibrary.getFileAssets({
         selections: mediaLibrary.FileKey.MEDIA_TYPE + '= ?',
         selectionArgs: [mediaLibrary.MediaType.AUDIO.toString()],
          });
   console.info(`mediaTest:getfileAssets success:${JSON.stringify(fileAssetResult)}`);
   let fileAssetArray=await fileAssetResult.getAllObject();
   for(let i=0;i<fileAssetArray.length;i++){
     console.info(`mediaTest:getAllObject success:${JSON.stringify(fileAssetArray[i].uri)}`);
   }
   let fd=await fileAssetArray[0].open("rw");////获取数组中第一个音频文件的fd
   let path="fd://"+fd;
   console.info(`mediaTest:fileAsset fdpath:${path}`);
   this.audioPlayer.src=path;
  }

在WGR上再次运行后成功播放媒体库中的mp3文件。

打印日志:

08-01 20:20:10.472  3363  3363 I A0fefe/JsApp: mediaTest:getfileAssets success:{}
08-01 20:20:10.474  3363  3363 I A0fefe/JsApp: mediaTest:getAllObject success:"datashare:///media/audio/16"
08-01 20:20:10.477  3363  3363 I A0fefe/JsApp: mediaTest:fileAsset fdpath:fd://55
08-01 20:20:10.503  3363  3363 I A0fefe/JsApp: mediaTest:data load success
08-01 20:20:10.508  3363  3363 I A0fefe/JsApp: mediaTest:play success
08-01 20:20:13.389  3363  3363 I A0fefe/JsApp: mediaTest:pause successs

6 知识分享

...全文
12 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

515

社区成员

发帖
与我相关
我的任务
社区描述
OpenHarmony开发者社区
其他 企业社区
社区管理员
  • csdnsqst0025
  • shewaliujingli
  • BaoWei
加入社区
  • 近7日
  • 近30日
  • 至今

试试用AI创作助手写篇文章吧