Просмотр исходного кода

暂时不能开启监听文件删除的,会影响到内嵌标签。优化批量内嵌标签

onecold 9 месяцев назад
Родитель
Сommit
df35a64c68

+ 1 - 7
entry/src/main/ets/common/util/MusicTagUtils.ets

@@ -157,13 +157,7 @@ export async function repairAudioMetadata(
     }
 
   } catch (error) {
-    let errorMsg: string = '';
-    if (error instanceof Error) {
-      errorMsg = error.message;
-    } else {
-      errorMsg = String(error);
-    }
-    console.error(`onecold元数据修复失败 ${errorMsg}`);
+    console.error(`onecold元数据修复失败 ${JSON.stringify(error)}`);
 
     // 清理临时文件(如果存在)
     if (useTempFile) {

+ 133 - 32
entry/src/main/ets/view/LocalMusic.ets

@@ -1809,7 +1809,7 @@ export struct LocalMusic {
       FileUtil.mkdirSync(this.historyPath)
     }
 
-    await this.startFileDeletionWatcher();
+    // await this.startFileDeletionWatcher();
 
     this.getSortedFiles(this.rootPath).then(async () => {
       this.isFavMusic = false
@@ -3663,13 +3663,18 @@ export struct LocalMusic {
             selectedFiles:this.selectedFiles,
             isOneKeyTags:this.isOneKeyTags,
             table:this.table,
-            onTagsResult:(result: boolean)=>{
+            onTagsResult:(result: boolean,deleteCache_path?:string)=>{
               this.isMultiSelect = false
               if(result){//如果嵌入成功,更新数据
                 setTimeout(()=>{
                   this.doUpdateData()
                 },500)
               }
+              console.info('onecold onTagsResult deleteCache_path =' +deleteCache_path)
+              if(deleteCache_path){
+                this.deleteCache(deleteCache_path)
+              }
+
 
             }
           }
@@ -7191,40 +7196,136 @@ export struct LocalMusic {
       ToastUtil.showToast('标题不能为空')
       return
     }
-
-    // 保存当前编辑的项目
-    this.editingItem = item;
-
+    //内嵌音乐标签不能开启监听
+    // this.deletionWatcher?.stop();
     DialogHelper.showLoadingDialog()
     await PermissionUtil.activatePermission(item.filePath)
-
-    // 发送到worker执行编辑操作
-    const editPayload: LocalEditMusicPayload = {
-      context: this.context,
-      item: item,
-      titleStr: this.titleStr,
-      artistStr: this.artistStr,
-      ablumStr: this.ablumStr,
-      yearStr: this.yearStr,
-      genreStr: this.genreStr,
-      trackStr: this.trackStr,
-      albumArtistStr: this.albumArtistStr,
-      composerStr: this.composerStr,
-      lyricistStr: this.lyricistStr,
-      commentStr: this.commentStr,
-      discStr: this.discStr,
-      lyricConStr: this.lyricConStr,
-      imagePathStr: this.imagePathStr,
-      currentPath: this.currentPath,
-      packName: this.packName,
-      modeType: this.modeType,
-      autoParseMusicName: this.autoParseMusicName
+    let tempOutPath = ''
+    // 如果不是 packName 包下的文件,则直接路径用this.currentPath
+    if(!item.filePath.toLowerCase().includes(this.packName)){
+      tempOutPath  = this.currentPath + '/' + item.fileName
+    }
+    console.info('onecold tempOutPath ='+tempOutPath)
+    //用户更改了封面,那就内嵌下封面
+    if(StrUtil.isNotEmpty(this.imagePathStr)){
+      const resultCover:boolean = await changeMusicCover(this.context,
+        item.filePath,this.imagePathStr,true,tempOutPath);
+      this.imagePathStr = ''
+      if(resultCover){
+        ToastUtil.showToast('内嵌封面成功')
+      }
+
+    }
+
+    const metadata:FFMpegTags = {
+      title: this.titleStr,
+      artist: this.artistStr,
+      album: this.ablumStr,
+      TYER:this.yearStr,
+      genre:this.genreStr,
+      track:this.trackStr,
+      album_artist:this.albumArtistStr,
+      TPE2:this.albumArtistStr,//ID3v2 中通常没有专门的 "专辑艺术家" 字段,但有些软件会使用 TPE2 来表示专辑艺
+      COMPOSER:this.composerStr,
+      lyricist:this.lyricistStr,
+      TEXT:this.lyricistStr,//ID3v2 使用 TEXT 字段来表示作词者
+      comment:this.commentStr,
+      disc:this.discStr,
     };
+    let newInput = item.filePath
+    //内嵌标签歌路径如果不是包含包名,输入newInput要赋值tempOutPath,然后tempOutPath为空
+    if(!item.filePath.toLowerCase().includes(this.packName)&&FileUtil.accessSync(tempOutPath)){
+      newInput = tempOutPath
+      tempOutPath  = ''
+    }
+    //内嵌下标签的值,设置overwrite为true会直接修改原文件
+    const result:boolean = await repairAudioMetadata(
+      newInput,
+      this.lyricConStr,
+      metadata,
+      true,
+      tempOutPath
+    );
+
+    if (result) {
+      if(!item.filePath.includes(this.packName)){
+        //内嵌成功的歌路径如果不是包含包名,则要入库
+        let newItem: VideoItem = await Utility.uriGetMusicAssetsFromFile(this.context, newInput,
+          CommonConstants.TYPE_LOCAL, this.autoParseMusicName);
+        this.table.insert(newItem, (id: number) => {
+          //加入数据库
+          if(this.modeType==0){
+            this.deleteCache(this.currentPath)
+            this.getSortedFiles(this.currentPath)
+          }
+        });
+      }
 
-    workerInstance.postMessage({
-      code: 6,
-      data: editPayload
-    });
+      const task = new taskpool.Task(
+        updateInfoDb,
+        this.context,
+        item.filePath,
+        this.titleStr,
+        this.artistStr,
+        this.ablumStr,
+        this.lyricConStr,
+        this.yearStr,this.genreStr,
+        this.trackStr,this.albumArtistStr,
+        this.composerStr, this.lyricistStr,
+        this.commentStr,this.discStr
+      );
+      taskpool.execute(task, taskpool.Priority.HIGH).then((result) => {
+        if (result) {
+          console.log(" onecold 编辑信息成功,数据库已同步");
+          ToastUtil.showToast('内嵌音乐标签成功')
+          this.isShowMoreView = false
+          this.name = this.titleStr
+          this.syncEditedFields(item)
+          if (item.filePath == this.currentSong?.filePath) {
+            this.currentSong.name = this.titleStr
+            this.artist = this.artistStr
+            this.currentSong.artist = this.artistStr
+            this.currentSong.album = this.ablumStr
+            this.currentSong.year = this.yearStr
+            this.currentSong.genre = this.genreStr
+            this.currentSong.track = this.trackStr
+            this.currentSong.lyricContent = this.lyricConStr
+            this.currentSong.ALBUMARTIST = this.albumArtistStr
+            this.currentSong.COMPOSER = this.composerStr
+            this.currentSong.LYRICIST = this.lyricistStr
+            this.currentSong.COMMENT = this.commentStr
+          }
+
+          this.syncListsAfterEdit(item.filePath)
+          this.doUpateEditedFields(item)
+          //this.doUpdateData()
+        } else {
+          // ToastUtil.showToast('保存失败' + error?.toString())
+          console.error(" onecold  编辑信息数据库失败 ");
+        }
+        // 关闭进度条
+        DialogHelper.closeLoading();
+
+
+
+      }).catch((error: Error) => {
+        // 关闭进度条
+        DialogHelper.closeLoading();
+        console.error('onecold Subtitle sync failed:', error);
+      });
+
+
+      console.log(' onecold 元数据标签更新成功,');
+
+    } else {
+      // 关闭进度条
+      DialogHelper.closeLoading();
+      ToastUtil.showToast('内嵌音乐标签失败')
+      console.log('onecold 内嵌音乐标签失败');
+    }
+    this.longItemFilePath = ''
+    this.tempLyricContent = ''
+    this.isShowEdit = false
   }
 
   // 内嵌标签更新当前内嵌的Item

+ 272 - 176
entry/src/main/ets/view/TagsContentCover.ets

@@ -18,7 +18,7 @@ import MediaTable from '../common/util/MediaTable';
 @Component
 export struct TagsContentCover {
   private listScroller: ListScroller = new ListScroller()
-  onTagsResult = (_result: boolean) => {
+  onTagsResult = (_result: boolean,deleteCache_path?:string) => {
   }
   @State isLyric:boolean = true
   @State isCover:boolean = true
@@ -45,6 +45,9 @@ export struct TagsContentCover {
 
   // 新增状态用于跟踪每个文件的嵌入状态
   @State embedStatusMap: Map<string, boolean> = new Map<string, boolean>();
+  // 分别跟踪歌词和封面嵌入状态
+  @State lyricEmbedStatusMap: Map<string, boolean> = new Map<string, boolean>();
+  @State coverEmbedStatusMap: Map<string, boolean> = new Map<string, boolean>();
 
 
   onColorModeChange() {
@@ -143,7 +146,7 @@ export struct TagsContentCover {
           .fontColor([this.themeColor])
           .alignSelf(ItemAlign.Center)
           .margin({ left: 15 })
-        Text('说明:不是本app路径下的歌曲将在DownLoad/天天静听/内嵌标签文件夹中生成新的内嵌歌曲。')
+        Text('说明:不是本app路径下的歌曲将在[DownLoad/天天静听/批量内嵌]标签文件夹中生成新的内嵌歌曲。如果失败可以多试几次。')
           .margin({ left: 5 ,right: 5})
           .fontSize(14)
           .padding({top:4,bottom:4})
@@ -213,32 +216,61 @@ export struct TagsContentCover {
 
   @Builder
   startButton(){
-    Stack(){
-      Progress({ value: this.currentProgress, total: this.totalFiles,
-        type: ProgressType.Capsule }).height(55)
-        .margin({top:20,right:20,left:20})
-        .backgroundColor($r('app.color.index_background'))
+    Column(){
+
+
       Button({ type: ButtonType.Capsule, stateEffect: true }) {
         Row() {
-          // 菜单图标
-          SymbolGlyph($r('sys.symbol.star_trophy'))// .size({ width: 22, height: 22 })
-            .fontSize(22)
-            .fontColor([this.themeColor])
-            .alignSelf(ItemAlign.Center)
-            .margin({ left: 25 })
+          if(!this.isEmbedding) {
+            // 菜单图标
+            SymbolGlyph($r('sys.symbol.star_trophy'))
+              .fontSize(22)
+              .fontColor([this.themeColor])
+              .alignSelf(ItemAlign.Center)
+              .margin({ left: 25 })
+
+            // 菜单标题
+            Text('开始内嵌')
+              .margin({ left: 10, right: 20 })
+              .fontSize(15)
+              .fontWeight(480)
+              .fontColor($r('app.color.text_color'))
+            Blank()
+            // 右侧箭头
+            Image($r('app.media.arrow_right'))
+              .width(22)
+              .height(22)
+              .margin({ left: 0, right: 20 })
+              .align(Alignment.Center)
+          } else {
+            // 处理中的状态
+            SymbolGlyph($r('sys.symbol.hourglass'))
+              .fontSize(22)
+              .fontColor([this.themeColor])
+              .alignSelf(ItemAlign.Center)
+              .margin({ left: 25 })
+
+            Row(){
+              Text(`正在处理: ${this.currentFileIndex}/${this.totalFiles}`)
+                .fontSize(12)
+                .fontColor($r('app.color.text_color'))
+            }
+            .width('100%')
+            .margin({left:20,right:8})
 
-          // 菜单标题
-          Text('开始内嵌')
-            .margin({ left: 10, right: 20 })
-            .fontSize(15)
-            .fontWeight(480)
-          Blank()
-          // 右侧箭头
-          Image($r('app.media.arrow_right'))
-            .width(22)
-            .height(22)
-            .margin({ left: 0, right: 20 })
-            .align(Alignment.Center)
+            Text(`${this.currentProgress}%`)
+              .margin({ left: 5 })
+              .fontSize(15)
+              .fontWeight(480)
+              .fontColor($r('app.color.text_color'))
+
+            Blank()
+
+            Text(`成功:${this.embedSuccessCount} 失败:${this.embedFailedCount}`)
+              .fontSize(12)
+              .fontColor($r('app.color.text_color'))
+              .margin({ right: 20 })
+          }
         }
         .width('100%')
       }
@@ -248,12 +280,11 @@ export struct TagsContentCover {
       .backgroundColor($r('app.color.start_window_background'))
       .clickEffect({ level: ClickEffectLevel.MIDDLE,scale:0.6 })
       .onClick(()=>{
-        this.startEmbed()
+        if(!this.isEmbedding) {
+          this.startEmbed()
+        }
       })
-
-
     }
-
   }
 
   // 会员功能弹窗
@@ -338,172 +369,194 @@ export struct TagsContentCover {
 
     // 清空之前的嵌入状态
     this.embedStatusMap = new Map<string, boolean>();
+    this.lyricEmbedStatusMap = new Map<string, boolean>();
+    this.coverEmbedStatusMap = new Map<string, boolean>();
 
-    // 创建异步任务数组
-    const embedTasks = this.selectedFiles.map(async (item: VideoItem, index: number) => {
-      try {
-        this.currentFileIndex = index + 1;
-        this.currentFileName = item.name;
-        await PermissionUtil.activatePermission(item.filePath)
-
-        let success = true;
-        let tempOutPath = ''
-        // 1. 处理封面 (如果启用且需要处理)
-        if(this.isCover){
-          let  defaultCover = ''
-          // 先查找同名的png或jpg文件
-          if (StrUtil.isEmpty(item.pixelMapPath) && item.filePath) {
-            defaultCover = findLocalCoverImage(item.filePath);
-
-            // 如果没有找到同名图片文件,则进行在线查询
-            if (StrUtil.isEmpty(defaultCover)) {
-              const imagePath: string | undefined = await searchCover(
-                this.context,
-                item,
-                item.name,
-                item?.artist || ''
-              );
-              defaultCover = imagePath || '';
-            }
-          }else if(item.pixelMapPath&&item.pixelMapPath.startsWith('http')){
-            defaultCover = item.pixelMapPath
-          }
-          if (StrUtil.isNotEmpty(defaultCover)) {
-            // 确保 filePath 存在
-            if (item.filePath) {
-              // 如果不是 packName 包下的文件,则直接路径用this.download_path
-              if(!item.filePath.toLowerCase().includes(this.packName)){
-                tempOutPath  = this.download_path+ item.fileName
+    // 改为顺序执行以正确显示进度
+    try {
+      for (let index = 0; index < this.selectedFiles.length; index++) {
+        const item: VideoItem = this.selectedFiles[index];
+
+        try {
+          this.currentFileIndex = index + 1;
+          this.currentFileName = item.name;
+          await PermissionUtil.activatePermission(item.filePath)
+
+          let success = true;
+          let lyricSuccess = false;
+          let coverSuccess = false;
+          let tempOutPath = ''
+
+          // 1. 处理封面 (如果启用且需要处理)
+          if(this.isCover){
+            let  defaultCover = ''
+            // 先查找同名的png或jpg文件
+            console.log('heanup item.pixelMapPath = ',item.pixelMapPath)
+            if (StrUtil.isEmpty(item.pixelMapPath) && item.filePath) {
+              defaultCover = findLocalCoverImage(item.filePath);
+
+              // 如果没有找到同名图片文件,则进行在线查询
+              if (StrUtil.isEmpty(defaultCover)) {
+                const imagePath: string | undefined = await searchCover(
+                  this.context,
+                  item,
+                  item.name,
+                  item?.artist || ''
+                );
+                defaultCover = imagePath || '';
               }
-              console.info('onecold tempOutPath: ' + tempOutPath)
-
-
-              const result = await changeMusicCover(
-                this.context,
-                item.filePath,
-                defaultCover,
-                true, tempOutPath
-              );
-              if (!result) {
+            }else if(item.pixelMapPath&&item.pixelMapPath.startsWith('http')){
+              defaultCover = item.pixelMapPath
+            }
+            if (StrUtil.isNotEmpty(defaultCover)) {
+              // 确保 filePath 存在
+              if (item.filePath) {
+                // 如果不是 packName 包下的文件,则直接路径用this.download_path
+                if(!item.filePath.toLowerCase().includes(this.packName)){
+                  tempOutPath  = this.download_path+ item.fileName
+                }
+                console.info('onecold tempOutPath: ' + tempOutPath)
+
+                const result = await changeMusicCover(
+                  this.context,
+                  item.filePath,
+                  defaultCover,
+                  true, tempOutPath
+                );
+                coverSuccess = result;
+                console.info(`heanup 封面内嵌结果 - 文件: ${item.name}, 结果: ${result}`);
+                if (!result) {
+                  success = false;
+                }
+              } else {
                 success = false;
+                coverSuccess = false;
               }
             } else {
-              success = false;
+              coverSuccess = true;
             }
+          } else {
+            // 如果没有启用封面嵌入,设置为成功状态(不处理)
+            coverSuccess = true;
           }
-        }
-
 
-        // 2. 处理歌词 (如果启用)
-        if (this.isLyric) {
-          let lyricContent = item.lyricContent || ''; // 默认为空字符串
-
-          // 如果歌词为空,尝试读取同名.lrc文件
-          if (StrUtil.isEmpty(lyricContent) && item.filePath) {
-            const lrcPath = item.filePath.substring(0, item.filePath.lastIndexOf('.')) + '.lrc';
-            try {
-              if (fs.accessSync(lrcPath)) {
-                const file = fs.openSync(lrcPath, fs.OpenMode.READ_ONLY);
-                const buf = new ArrayBuffer(102400); // 100KB缓冲区
-                const len = fs.readSync(file.fd, buf);
-                const textDecoder = new util.TextDecoder('utf-8');
-                // 修复错误3: 使用 Uint8Array 包装 ArrayBuffer
-                lyricContent = textDecoder.decode(new Uint8Array(buf.slice(0, len)));
-                fs.closeSync(file);
+          // 2. 处理歌词 (如果启用)
+          if (this.isLyric) {
+            let lyricContent = item.lyricContent || ''; // 默认为空字符串
+
+            // 如果歌词为空,尝试读取同名.lrc文件
+            if (StrUtil.isEmpty(lyricContent) && item.filePath) {
+              const lrcPath = item.filePath.substring(0, item.filePath.lastIndexOf('.')) + '.lrc';
+              try {
+                if (fs.accessSync(lrcPath)) {
+                  const file = fs.openSync(lrcPath, fs.OpenMode.READ_ONLY);
+                  const buf = new ArrayBuffer(102400); // 100KB缓冲区
+                  const len = fs.readSync(file.fd, buf);
+                  const textDecoder = new util.TextDecoder('utf-8');
+                  // 修复错误3: 使用 Uint8Array 包装 ArrayBuffer
+                  lyricContent = textDecoder.decode(new Uint8Array(buf.slice(0, len)));
+                  fs.closeSync(file);
+                }
+              } catch (error) {
+                console.warn(`读取LRC文件失败: ${JSON.stringify(error)}`);
               }
-            } catch (error) {
-              console.warn(`读取LRC文件失败: ${JSON.stringify(error)}`);
             }
-          }
 
-          // 如果仍然为空,尝试从API获取歌词
-          if (StrUtil.isEmpty(lyricContent) && item.filePath) {
-            try {
-              const apiUrl = PreferencesUtil.getStringSync('LRC_API', '');
-              // 修复错误1: 添加非空检查
-              if (StrUtil.isNotEmpty(apiUrl)) {
-                lyricContent = await getApiLyric(
-                  apiUrl,
-                  item.name || '', // 修复可能为undefined的情况
-                  item.artist || '', // 修复可能为undefined的情况
-                  apiUrl.includes(CommonConstants.LRC_API_2)
-                );
+            // 如果仍然为空,尝试从API获取歌词
+            if (StrUtil.isEmpty(lyricContent) && item.filePath) {
+              try {
+                const apiUrl = PreferencesUtil.getStringSync('LRC_API', '');
+                // 修复错误1: 添加非空检查
+                if (StrUtil.isNotEmpty(apiUrl)) {
+                  lyricContent = await getApiLyric(
+                    apiUrl,
+                    item.name || '', // 修复可能为undefined的情况
+                    item.artist || '', // 修复可能为undefined的情况
+                    apiUrl.includes(CommonConstants.LRC_API_2)
+                  );
+                }
+              } catch (error) {
+                console.warn(`获取API歌词失败: ${JSON.stringify(error)}`);
               }
-            } catch (error) {
-              console.warn(`获取API歌词失败: ${JSON.stringify(error)}`);
             }
-          }
 
-          // 如果有歌词内容,嵌入到音频文件
-          if (StrUtil.isNotEmpty(lyricContent) && item.filePath) {
-            const metadata: FFMpegTags = {};
-            let newInput = item.filePath
-            //内嵌标签歌路径如果不是包含包名,输入newInput要赋值tempOutPath,然后tempOutPath为空
-            if(!item.filePath.toLowerCase().includes(this.packName)&&FileUtil.accessSync(tempOutPath)){
-              newInput = tempOutPath
-              tempOutPath  = ''
-            }
-            // 修复错误2: 添加非空检查
-            const result = await repairAudioMetadata(
-              newInput,
-              lyricContent,
-              metadata,
-              true ,
-              tempOutPath
-            );
-            if (!result) {
-              success = false;
-            }else{
-              if(!item.filePath.includes(this.packName)){
-                //内嵌成功的歌路径如果不是包含包名,则要入库
-                let newItem: VideoItem = await Utility.uriGetMusicAssetsFromFile(this.context, newInput,
-                  CommonConstants.TYPE_LOCAL, true);
-                this.table.insert(newItem, (id: number) => {
-
-
-                });
+            // 如果有歌词内容,嵌入到音频文件
+            if (StrUtil.isNotEmpty(lyricContent) && item.filePath) {
+              const metadata: FFMpegTags = {};
+              let newInput = item.filePath
+              //内嵌标签歌路径如果不是包含包名,输入newInput要赋值tempOutPath,然后tempOutPath为空
+              if(!item.filePath.toLowerCase().includes(this.packName)&&FileUtil.accessSync(tempOutPath)){
+                newInput = tempOutPath
+                tempOutPath  = ''
               }
-              //内嵌成功后同步歌词到数据库
-              syncLyricToDB(this.context,item.filePath,lyricContent)
+              // 修复错误2: 添加非空检查
+              const result = await repairAudioMetadata(
+                newInput,
+                lyricContent,
+                metadata,
+                true ,
+                tempOutPath
+              );
+              lyricSuccess = result;
+              if (!result) {
+                success = false;
+              }else{
+                if(!item.filePath.includes(this.packName)){
+                  //内嵌成功的歌路径如果不是包含包名,则要入库
+                  let newItem: VideoItem = await Utility.uriGetMusicAssetsFromFile(this.context, newInput,
+                    CommonConstants.TYPE_LOCAL, true);
+                  this.table.insert(newItem, (id: number) => {
+
+
+                  });
+                }
+                //内嵌成功后同步歌词到数据库
+                syncLyricToDB(this.context,item.filePath,lyricContent)
+              }
+            } else {
+              lyricSuccess = false;
             }
+          } else {
+            // 如果没有启用歌词嵌入,设置为成功状态(不处理)
+            lyricSuccess = true;
           }
-        }
 
-        // 更新嵌入状态
-        if (item.filePath) {
-          this.embedStatusMap.set(item.filePath, success);
-        }
+          // 更新嵌入状态
+          if (item.filePath) {
+            this.embedStatusMap.set(item.filePath, success);
+            this.lyricEmbedStatusMap.set(item.filePath, lyricSuccess);
+            this.coverEmbedStatusMap.set(item.filePath, coverSuccess);
+            console.info(`heanup 更新状态 - 封面: ${coverSuccess}, 歌词: ${lyricSuccess}, 文件: ${item.name}`);
+          }
+
+          if (success) {
+            this.embedSuccessCount++;
+          } else {
+            this.embedFailedCount++;
+          }
 
-        if (success) {
-          this.embedSuccessCount++;
-        } else {
+          // 更新进度 - 使用 Math.round 避免小数
+          this.currentProgress = Math.round(((index + 1) / this.totalFiles) * 100);
+          console.info(`onecold 进度更新: ${this.currentProgress}% (${index + 1}/${this.totalFiles})`);
+
+        } catch (error) {
+          console.error(`处理文件 ${item.name} 失败: ${JSON.stringify(error)}`);
           this.embedFailedCount++;
         }
-        // 滚动到当前处理的项目位置
-        // this.listScroller.scrollToIndex(index);
-        this.currentProgress = Math.floor(((index + 1) / this.totalFiles) * 100);
-        return success;
-      } catch (error) {
-        console.error(`处理文件 ${item.name} 失败: ${JSON.stringify(error)}`);
-        this.embedFailedCount++;
-        return false;
       }
-    });
 
-    try {
-      // 并发执行所有嵌入任务
-      await Promise.all(embedTasks);
-    } catch (error) {
-      this.onTagsResult(false)
-      console.error(`批量嵌入过程出错: ${JSON.stringify(error)}`);
-    } finally {
+      // 完成处理
       ToastUtil.showToast(`嵌入完成: 成功 ${this.embedSuccessCount}, 失败 ${this.embedFailedCount}`)
       this.isEmbedding = false;
       this.currentProgress = 0;
       this.totalFiles = this.selectedFiles.length;
-      this.onTagsResult(true)
-      // 可以在这里添加完成后的提示或回调
-      console.info(`嵌入完成: 成功 ${this.embedSuccessCount}, 失败 ${this.embedFailedCount}`);
+      this.onTagsResult(true,this.download_path)
+      console.info(`onecold 嵌入完成: 成功 ${this.embedSuccessCount}, 失败 ${this.embedFailedCount}`);
+
+    } catch (error) {
+      this.onTagsResult(false)
+      console.error(`onecold 批量嵌入过程出错: ${JSON.stringify(error)}`);
+      this.isEmbedding = false;
     }
   }
 
@@ -571,17 +624,60 @@ export struct TagsContentCover {
             .fontColor(Color.Gray)
             .margin({ left: 8 })
           Blank()
-          // 根据嵌入状态显示勾选图标
-          SymbolGlyph($r('sys.symbol.checkmark_circle'))
-            .fontSize(20)
-            .fontColor([this.themeColor])
-            .alignSelf(ItemAlign.Center)
-            .padding({ right: 25 })
+          // 歌词嵌入状态
+
+            Row() {
+              Text('歌词')
+                .fontSize(12)
+                .fontColor(this.themeColor)
+              // 只有当状态存在时才显示图标
+                SymbolGlyph(this.lyricEmbedStatusMap.get(item.filePath)?$r('sys.symbol.checkmark_circle'):$r('sys.symbol.xmark_circle'))
+                  .fontSize(16)
+                  .margin({ left: 4 })
+                  .fontColor([this.themeColor])
+                  .alignSelf(ItemAlign.Center)
+                  .visibility(this.lyricEmbedStatusMap.has(item.filePath)?Visibility.Visible:Visibility.Hidden)
+                  .animation({
+                    duration: 666,
+                    curve: 'ease-in-out'
+                  })
+            }
+            .visibility(this.isLyric?Visibility.Visible:Visibility.None)
+            .animation({
+              duration: 666,
+              curve: 'ease-in-out'
+            })
+            .padding({ right:10 })
+
+
+          // 封面嵌入状态
+
+            Row() {
+              Text('封面')
+                .fontSize(12)
+                .fontColor(this.themeColor)
+              // 只有当状态存在时才显示图标
+
+              SymbolGlyph(this.coverEmbedStatusMap.get(item.filePath)?$r('sys.symbol.checkmark_circle'):$r('sys.symbol.xmark_circle'))
+                .fontSize(16)
+                .margin({ left: 4 })
+                .fontColor([this.themeColor])
+                .alignSelf(ItemAlign.Center)
+                .visibility(this.coverEmbedStatusMap.has(item.filePath)?Visibility.Visible:Visibility.Hidden)
+                .animation({
+                  duration: 666,
+                  curve: 'ease-in-out'
+                })
+
+            }
+            .margin({ left: 5 })
+            .visibility(this.isCover?Visibility.Visible:Visibility.None)
             .animation({
               duration: 666,
-              curve: 'ease-in-out' // 可选动画曲线
+              curve: 'ease-in-out'
             })
-            .visibility(this.embedStatusMap.get(item.filePath)?Visibility.Visible:Visibility.None)
+            .padding({ right: 25 })
+
 
         }
         .layoutWeight(1)