Browse Source

修复cue最后一首歌曲的时长显示问题

onecold 10 tháng trước cách đây
mục cha
commit
de03e313b9

+ 39 - 1
entry/src/main/ets/common/util/CueUtils.ets

@@ -1,6 +1,9 @@
 import { fileIo } from '@kit.CoreFileKit';
 import { util } from '@kit.ArkTS';
 import { UniversalDetector } from '@ohos/juniversalchardet';
+import { Utility } from './Utility';
+import { media } from '@kit.MediaKit';
+import { BusinessError } from '@kit.BasicServicesKit';
 
 
 // 类型定义
@@ -26,7 +29,7 @@ export interface CueInfo {
 }
 
 // 主解析函数(同步totalDuration参数)
-export async function parseCueFile(cuePath: string, totalDuration?: number): Promise<CueInfo> {
+export async function parseCueFile(cuePath: string): Promise<CueInfo> {
   const file = fileIo.openSync(cuePath,  fileIo.OpenMode.READ_ONLY);
   try {
     // 读取文件内容
@@ -49,6 +52,7 @@ export async function parseCueFile(cuePath: string, totalDuration?: number): Pro
       result.filePath = parentPath + '/' + result.filePath;
     }
     console.log('onecold   result.filePath =',  result.filePath);
+    const totalDuration = await getHwMediaDuration(result.filePath)
     // 计算时间信息
     return calculateTrackTimes(result, totalDuration);
   } finally {
@@ -114,6 +118,7 @@ function parseCueContent(content: string): CueInfo {
 function calculateTrackTimes(cueInfo: CueInfo, totalDuration?: number): CueInfo {
   const tracks = cueInfo.tracks;  // ✅ 标准属性访问
   if (totalDuration) cueInfo.totalDuration  = totalDuration;
+  console.info('onecold  totalDuration =', totalDuration)
 
   tracks.forEach((track,  index) => {
     // 普通音轨
@@ -216,4 +221,37 @@ function detect(data: ArrayBuffer): string {
   detector.reset();
 
   return detected;
+}
+
+/**
+ * 提取华为设备上媒体文件的时长信息
+ * @param filePath 文件路径(如:/data/storage/el1/base/test.mp3 )
+ * @returns Promise<number> 返回媒体文件时长(毫秒),失败时返回0
+ */
+export async function getHwMediaDuration(filePath: string): Promise<number> {
+  if (!canIUse("SystemCapability.Multimedia.Media.AVMetadataExtractor")) {
+    console.warn("Duration  extraction not supported on this device");
+    return 0;
+  }
+
+  try {
+    const avMetadataExtractor: media.AVMetadataExtractor = await media.createAVMetadataExtractor();
+    const fd = await fileIo.open(filePath,  fileIo.OpenMode.READ_ONLY);
+
+    // 设置文件描述符并提取元数据
+    avMetadataExtractor.fdSrc  = fd;
+    const metadata = await avMetadataExtractor.fetchMetadata();
+
+    // 关闭文件描述符
+    await fileIo.close(fd);
+
+    // 从元数据中提取时长(单位:毫秒)
+    // 增加非负数校验
+    const duration = Number(metadata?.duration ?? 0);
+    return Math.max(0,  duration);
+  } catch (error) {
+    const err = error as BusinessError;
+    console.error(`Duration  extraction failed: ${err.code},  ${err.message}`);
+    return 0;
+  }
 }

+ 1 - 1
entry/src/main/ets/view/LocalMusic.ets

@@ -5108,7 +5108,7 @@ export struct LocalMusic {
         break;
       case CommonConstants.TYPE_LOCAL:
         if(item&&item.filePath.toLowerCase().endsWith('.cue')){
-          const cueinfo:CueInfo = await parseCueFile(item.filePath,Number(item.duration))
+          const cueinfo:CueInfo = await parseCueFile(item.filePath)
           const cueTracks:CueTrack[] = cueinfo.tracks
           console.log('onecold  cue cueTracks =', JSON.stringify(cueTracks));
           if(ArrayUtil.isNotEmpty(cueTracks)){