HarmonyOS 鸿蒙Next下载的音乐获取媒体资源图片显示不全问题

发布于 1周前 作者 yibo5220 来自 鸿蒙OS

HarmonyOS 鸿蒙Next下载的音乐获取媒体资源图片显示不全问题 1、播放音乐的过程中会下载音乐到本地沙盒
2、取沙盒里音乐的元信息获取音乐封面并显示到页面上
代码; this.currentMetadataPath = path;
let artInfo: Map<string, string|image.PixelMap> = new Map() // 通过UIAbilityContext获取沙箱地址filesDir(以Stage模型为例)
let fd: number = fs.openSync(path, 0o0).fd;
let fileSize: number = fs.statSync(path).size;
// 设置dataSrc描述符,通过callback从文件中获取资源,写入buffer中
let dataSrc: media.AVDataSrcDescriptor = {
fileSize: fileSize,
callback: (buffer, len, pos) => {
if (buffer == undefined || len == undefined || pos == undefined) {
console.error(dataSrc callback param invalid)
return -1
}
class Option {
offset: number | undefined = 0;
length: number | undefined = len;
position: number | undefined = pos;
}

let options = new Option();  
let num = fs.readSync(fd, buffer, options)  
// console.info('readAt end, num: ' + num)  
if (num > 0 && fileSize >= pos) {  
  return num;  
}  
return -1;  

}
}

// 创建AVMetadataExtractor对象
let avMetadataExtractor = await media.createAVMetadataExtractor()
// 设置dataSrc
avMetadataExtractor.dataSrc = dataSrc;

// 获取元信息(promise模式)
let metadata = await avMetadataExtractor.fetchMetadata()
console.info(get meta data, mimeType: ${metadata.mimeType})
if(metadata.title != null &&metadata.title?.length>0){
artInfo.set(‘title’,metadata.title??’’)
}
if(metadata.artist != null &&metadata.artist?.length>0){
artInfo.set(‘artist’,metadata.artist??’’)
}
if(metadata.album != null &&metadata.album?.length>0){
artInfo.set(‘album’,metadata.album??’’)
}

// 获取专辑封面(promise模式)
this.currentPlayingInfo.pixelMap = await avMetadataExtractor.fetchAlbumCover()
if(this.currentPlayingInfo.pixelMap != undefined && this.currentPlayingInfo.pixelMap){
artInfo.set(‘image’,this.currentPlayingInfo.pixelMap)
}
this.currentMetadata = artInfo;
// 释放资源(promise模式)
avMetadataExtractor.release()

Image(this.currentPlayingInfo?.pixelMap)
.width(MusicConstant.COVER_WIDTH)
.height(MusicConstant.COVER_WIDTH)
.objectFit(ImageFit.Cover)
.borderRadius(MusicConstant.COVER_WIDTH / 2)

通过代码获取封面await avMetadataExtractor.fetchAlbumCover()
附件中心的音乐唱片是加载获取的音乐封面显示不全


更多关于HarmonyOS 鸿蒙Next下载的音乐获取媒体资源图片显示不全问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html

2 回复

image组件设置为.objectFit(ImageFit.Contain)试试呢,Contain 保持宽高比进行缩小或者放大,使得图片完全显示在显示边界内。

用以下demo试下:

demo:

import media from '@ohos.multimedia.media'
import hiLog from '@ohos.hilog'
import common from '@ohos.app.ability.common';
import hilog from '@ohos.hilog';
import image from '@ohos.multimedia.image';
import fs from '@ohos.file.fs';
import { fileUri } from '@kit.CoreFileKit';
import { BusinessError } from '@kit.BasicServicesKit';

const TAG = 'MetadataDemo'

@Entry
@Component
struct Index {
@State message: string = 'Hello World'
private domain: number = 0xFF00
private prefix: string = TAG
private format: string = "%s, %s"

// pixelMap对象声明,用于图片显示
@State pixelMap: image.PixelMap | undefined = undefined;

filePath: string = '';

aboutToAppear(): void {
this.copyFile();
}

build() {
Row() {
Column() {
Text(this.message).fontSize(50).fontWeight(FontWeight.Bold)
Button() {
Text('TestButton')
.fontSize(30)
.fontWeight(FontWeight.Bold)
}
.type(ButtonType.Capsule)
.margin({
top: 20
})
.backgroundColor('#0D9FFB')
.width('60%')
.height('5%')
.onClick(async () => {
await this.testFetchMetadataFromDataSrc()
})
Image(this.pixelMap).width(300).height(300)
.margin({
top: 20
})
}
.width('100%')
}
.height('100%')
}

copyFile() {
console.log("开发复制文件")
let context = getContext(this) as common.UIAbilityContext;
let srcFileDescriptor = context.resourceManager.getRawFdSync('cover.mp3'); //这里填rawfile文件夹下的文件名(包括后缀)
let stat = fs.statSync(srcFileDescriptor.fd)
console.log(`stat isFile:${stat.isFile()}`);
// 通过UIAbilityContext获取沙箱地址filesDir,以Stage模型为例
let pathDir = context.filesDir;
console.log("沙箱文件目录路径:", pathDir)
let dstPath = pathDir + "/cover.mp3";
this.filePath = fileUri.getUriFromPath(dstPath)
console.log("沙箱文件URI" + this.filePath);
let dest = fs.openSync(dstPath, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE)
let bufsize = 4096
let buf = new ArrayBuffer(bufsize)
let off = 0, len = 0, readedLen = 0
while (len = fs.readSync(srcFileDescriptor.fd, buf, { offset: srcFileDescriptor.offset + off, length: bufsize })) {
readedLen += len
fs.writeSync(dest.fd, buf, { offset: off, length: len })
off = off + len
if ((srcFileDescriptor.length - readedLen) < bufsize) {
bufsize = srcFileDescriptor.length - readedLen
}
}
fs.close(dest.fd)
}

// 在以下demo中,使用资源管理接口获取打包在HAP内的媒体资源文件,通过设置fdSrc属性,获取音频元信息并打印,
// 获取音频专辑封面并通过Image控件显示在屏幕上。该demo以Callback形式进行异步接口调用
async testFetchMetadataFromFdSrcByCallback() {
// 创建AVMetadataExtractor对象
let avMetadataExtractor: media.AVMetadataExtractor = await media.createAVMetadataExtractor()
media.createAVMetadataExtractor().then((extractor: media.AVMetadataExtractor) => {
if (extractor != null) {
avMetadataExtractor = extractor;
console.info('createAVMetadataExtractor success');
} else {
console.error('createAVMetadataExtractor fail');
}
});

// 设置fdSrc
avMetadataExtractor.fdSrc = await globalThis.getContext().resourceManager.getRawFd('cover.mp3');

// 获取元信息(callback模式)
avMetadataExtractor.fetchMetadata((error, metadata) => {
if (error) {
this.error(`${TAG} fetchMetadata callback failed, err = ${JSON.stringify(error)}`)
return
}
this.info(`${TAG} fetchMetadata callback success, genre: ${metadata.genre}`)
})

//获取专辑封面(callback模式)
avMetadataExtractor.fetchAlbumCover((err, pixelMap) => {
if (err) {
this.error(`${TAG} fetchAlbumCover callback failed, err = ${JSON.stringify(err)}`)
return
}
this.pixelMap = pixelMap
// 释放资源(callback模式)
avMetadataExtractor.release((error) => {
if (error) {
this.error(`${TAG} release failed, err = ${JSON.stringify(error)}`)
return
}
this.info(`${TAG} release success.`)
})
})
}

// 在以下demo中,使用资源管理接口获取打包在HAP内的媒体资源文件,通过设置fdSrc属性,获取音频元信息并打印,
// 获取音频专辑封面并通过Image控件显示在屏幕上。该demo以Promise形式进行异步接口调用
async testFetchMetadataFromFdSrcByPromise() {
// 创建AVMetadataExtractor对象
let avMetadataExtractor: media.AVMetadataExtractor = await media.createAVMetadataExtractor()

// 设置fdSrc
avMetadataExtractor.fdSrc = await globalThis.getContext().resourceManager.getRawFd('cover.mp3');

// 获取元信息(promise模式)
let metadata = await avMetadataExtractor.fetchMetadata()
for (let key of Object.keys(metadata)) {
this.info(`${TAG} get metadata key ${key} value ${metadata[key]}`)
}

// 获取专辑封面(promise模式)
hilog.info(0x0000, TAG, "DoFetchArtPicture")
this.pixelMap = await avMetadataExtractor.fetchAlbumCover()
this.info(`${TAG} pixelMap = ${JSON.stringify(this.pixelMap)}`)

// 释放资源(promise模式)
avMetadataExtractor.release()
this.info(`${TAG} release success.`)
}

// 在以下demo中,使用资源管理接口获取打包在HAP内的媒体资源文件,通过设置fdSrc属性,获取音频元信息并打印,
// 获取音频专辑封面并通过Image控件显示在屏幕上。该demo以Promise形式进行异步接口调用
async testFetchFrameByTimeByPromise() {
// 创建AVMetadataExtractor对象
let avMetadataExtractor: media.AVMetadataExtractor = await media.createAVMetadataExtractor()

// 设置fdSrc
avMetadataExtractor.fdSrc = await getContext(this).resourceManager.getRawFd('cover.mp3');

// 获取元信息(callback模式)
avMetadataExtractor.fetchMetadata((error, metadata) => {
if (error) {
console.error(`${TAG} fetchMetadata callback failed, err = ${JSON.stringify(error)}`)
return
}
console.info(`${TAG} fetchMetadata callback success, genre: ${metadata.genre}`)
})

//获取专辑封面(callback模式)
avMetadataExtractor.fetchAlbumCover((err, pixelMap) => {
if (err) {
console.error(`${TAG} fetchAlbumCover callback failed, err = ${JSON.stringify(err)}`)
return
}
this.pixelMap = pixelMap
// 释放资源(callback模式)
avMetadataExtractor.release((error) => {
if (error) {
console.error(`${TAG} release failed, err = ${JSON.stringify(error)}`)
return
}
console.info(`${TAG} release success.`)
})
})
}

// 在以下demo中,使用fileIo文件系统打开沙箱地址获取媒体文件地址,设置dataSrc属性,获取音频元信息并打印,
// 获取音频专辑封面并通过Image控件显示在屏幕上。
async testFetchMetadataFromDataSrc() {
// 创建AVMetadataExtractor对象
let context = getContext(this) as common.UIAbilityContext
// 通过UIAbilityContext获取沙箱地址filesDir(以Stage模型为例)
let filePath: string = context.filesDir + '/cover.mp3';
let fd: number = fs.openSync(filePath, 0o0).fd;
let fileSize: number = fs.statSync(filePath).size;

// 设置dataSrc描述符,通过callback从文件中获取资源,写入buffer中
let dataSrc: media.AVDataSrcDescriptor = {
fileSize: -1,
callback: (buf: ArrayBuffer, length: number) => {
let num = 0;
if (buf == undefined || length == undefined) {
return -1;
}
num = fs.readSync(fd, buf);
if (num > 0) {
return num;
}
return -1;
}
}

// 创建AVMetadataExtractor对象
let avMetadataExtractor = await media.createAVMetadataExtractor()
// 设置dataSrc
avMetadataExtractor.dataSrc = dataSrc;

// 获取元信息(promise模式)
let metadata = await avMetadataExtractor.fetchMetadata()
console.info(`${TAG} get meta data, mimeType: ${metadata.mimeType}`)

// 获取专辑封面(promise模式)
avMetadataExtractor.fetchAlbumCover((error: BusinessError, pixelMap: image.PixelMap) => {
if (error) {
console.error(`Failed to fetch AlbumCover, error = ${JSON.stringify(error)}`);
return;
}
this.pixelMap = pixelMap;
});

// 释放资源(promise模式)
avMetadataExtractor.release()
console.info(`${TAG} release data source success.`)
}

info(...args: ESObject[]) {
hiLog.info(this.domain, this.prefix, this.format, args)
}

error(...args: ESObject[]) {
hiLog.error(this.domain, this.prefix, this.format, args)
}
}

更多关于HarmonyOS 鸿蒙Next下载的音乐获取媒体资源图片显示不全问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


针对HarmonyOS鸿蒙Next下载的音乐获取媒体资源图片显示不全的问题,可能的原因及解决方案如下:

  1. 缓存问题:系统或应用缓存可能导致图片加载不完全。尝试清除应用缓存或重启设备,看是否能解决问题。

  2. 图片格式或大小限制:如果媒体资源图片格式不兼容或文件过大,可能导致显示不全。检查图片格式是否为系统支持的类型,并尝试调整图片大小。

  3. 系统或应用BUG:鸿蒙系统或音乐应用本身可能存在BUG,导致图片显示异常。关注华为官方发布的系统更新,及时更新系统或应用至最新版本。

  4. 权限设置:检查应用是否获得了访问存储和媒体文件的权限。如果没有,请在系统设置中授予相应权限。

  5. 第三方应用干扰:某些第三方应用可能影响图片的正常显示。尝试在安全模式下启动设备,看问题是否依旧存在,以排除第三方应用干扰的可能性。

如果上述方法均无法解决问题,可能是系统或应用深层次的兼容性问题。此时,建议联系华为官方客服获取更专业的技术支持。官网客服地址:https://www.itying.com/category-93-b0.html 如果问题依旧没法解决请联系官网客服。

回到顶部