Kaynağa Gözat

内嵌音乐标签功能,歌词内嵌看ffmpeg命令是成功的,但是其他播放器读不了,有待解决

onecold 1 yıl önce
ebeveyn
işleme
05c0e276b9

+ 2 - 2
AppScope/app.json5

@@ -2,8 +2,8 @@
   "app": {
     "bundleName": "com.xgplayer.ttmusic.hm",
     "vendor": "example",
-    "versionCode": 20250810,
-    "versionName": "1.5.1",
+    "versionCode": 20250819,
+    "versionName": "1.5.2",
     "icon": "$media:app_icon",
     "label": "$string:app_name",
     "multiAppMode": {

+ 49 - 2
entry/src/main/ets/common/util/MediaTable.ets

@@ -36,7 +36,7 @@ interface DBColumnsInterface {
  */
 const DB_COLUMNS: DBColumnsInterface = {
   ID: 'id',
-  NAME: 'name', 
+  NAME: 'name',
   FILE_PATH: 'filePath',
   TYPE: 'mtype',
   VIDEO_SIZE: 'videoSize',
@@ -134,7 +134,9 @@ export default class MediaTable {
 
   //编辑歌曲的信息更新数据库
   public updateMediaInfo(filePath: string, title: string, artist: string, album: string,
-    lyricContent:string,year:string,genre:string,track:string,callback: Function) {
+    lyricContent:string,year:string,genre:string,track:string,
+    ALBUMARTIST:string,COMPOSER:string,LYRICIST:string,COMMENT:string,disc:string,
+    callback: Function) {
     if (!callback || typeof callback !== 'function') {
       Logger.info(RdbUtils.RDB_TAG, 'updateMediaInfo() has no valid callback!');
       return;
@@ -183,6 +185,22 @@ export default class MediaTable {
         valuesToUpdate.track = track;
       }
 
+      if (ALBUMARTIST !== '') {
+        valuesToUpdate.ALBUMARTIST = ALBUMARTIST;
+      }
+      if (COMPOSER !== '') {
+        valuesToUpdate.COMPOSER = COMPOSER;
+      }
+      if (LYRICIST !== '') {
+        valuesToUpdate.LYRICIST = LYRICIST;
+      }
+      if (COMMENT !== '') {
+        valuesToUpdate.COMMENT = COMMENT;
+      }
+      if (disc !== '') {
+        valuesToUpdate.disc = disc;
+      }
+
       resultSet.close();
 
       // Step 4: Update the record if there are values to update
@@ -259,6 +277,12 @@ export default class MediaTable {
       obj.channel_layout  = resultSet.getString(resultSet.getColumnIndex('channel_layout'));
       obj.start_time  = resultSet.getString(resultSet.getColumnIndex('start_time'));
 
+      obj.ALBUMARTIST  = resultSet.getString(resultSet.getColumnIndex('ALBUMARTIST'));
+      obj.COMPOSER  = resultSet.getString(resultSet.getColumnIndex('COMPOSER'));
+      obj.LYRICIST  = resultSet.getString(resultSet.getColumnIndex('LYRICIST'));
+      obj.COMMENT  = resultSet.getString(resultSet.getColumnIndex('COMMENT'));
+      obj.disc  = resultSet.getString(resultSet.getColumnIndex('disc'));
+
       const valueBucket: relationalStore.ValuesBucket = obj
       // Step 4: 执行更新
       const updatePredicates = new relationalStore.RdbPredicates(RdbUtils.MEDIA_TABLE.tableName);
@@ -590,6 +614,12 @@ export default class MediaTable {
     item.channel_layout = safeGet('channel_layout');
     item.start_time = safeGet('start_time');
 
+    item.ALBUMARTIST = safeGet('ALBUMARTIST');
+    item.COMPOSER = safeGet('COMPOSER');
+    item.LYRICIST = safeGet('LYRICIST');
+    item.COMMENT = safeGet('COMMENT');
+    item.disc = safeGet('disc');
+
     return item;
   }
 
@@ -697,5 +727,22 @@ function generateBucket(item: VideoItem): relationalStore.ValuesBucket {
     obj.start_time = item.start_time;
   }
 
+  if(item.ALBUMARTIST){
+    obj.ALBUMARTIST = item.ALBUMARTIST;
+  }
+  if(item.COMPOSER){
+    obj.COMPOSER = item.COMPOSER;
+  }
+  if(item.LYRICIST){
+    obj.LYRICIST = item.LYRICIST;
+  }
+  if(item.COMMENT){
+    obj.COMMENT = item.COMMENT;
+  }
+  if(item.disc){
+    obj.disc = item.disc;
+  }
+
+
   return obj;
 }

+ 18 - 0
entry/src/main/ets/common/util/MusicTagUtils.ets

@@ -31,6 +31,7 @@ import { CommonConstants } from "../constants/CommonConstants";
  */
 export async function repairAudioMetadata(
   inputPath: string,
+  lyrics:string,
   metadata: FFMpegTags,
   overwrite: boolean = false,
   outputPath: string = ''
@@ -81,6 +82,23 @@ export async function repairAudioMetadata(
       commands.push(`${key}=${value}`);
     }
   });
+  //额外再次添加下lyrics-XXX的歌词参数,以便其他音乐播放器可以识别歌词
+  // 额外添加歌词自定义标签(修复后的核心代码)
+  if (StrUtil.isNotEmpty(lyrics)) { // 确保歌词内容存在时才添加
+    // 多种歌词标签格式
+    const lyricTags = [
+      `LYRICS=${lyrics}`,
+      `lyrics-XXX=${lyrics}`,
+      `USLT::XXX=${lyrics}`,
+    // `UNSYNCEDLYRICS=${lyrics}`
+    ];
+
+    lyricTags.forEach(tag  => {
+      commands.push("-metadata");
+      commands.push(tag);
+    });
+  }
+
 
   commands.push(
     "-map", "0",

+ 25 - 12
entry/src/main/ets/common/util/RdbUtils.ets

@@ -75,13 +75,21 @@ export default class RdbUtils {
       '        channel_layout TEXT,\n' +
       '        start_time TEXT,\n' +
 
+      '        ALBUMARTIST TEXT,\n' +
+      '        COMPOSER TEXT,\n' +
+      '        LYRICIST TEXT,\n' +
+      '        COMMENT TEXT,\n' +
+      '        disc TEXT,\n' +
+
       '        mimeType TEXT' +
       ')',
     columns: ['id', 'name', 'filePath','mtype', 'videoSize', 'cTime','size', 'artist', 'album',
       'fileName','parentPath','isFav','pixelMapPath','pixelMapToString',
       'duration',   'sampleRate','playCount',  'lastPlayedStr', 'trackCount',
       'lyricContent','md5Str','extra_json','pyStr','bit_rate','probe_score','year','nb_streams','nb_programs',
-      'genre','track',  'bits_per_raw_sample','channels',  'channel_layout','start_time',  'mimeType']
+      'genre','track',  'bits_per_raw_sample','channels',  'channel_layout','start_time',
+      'ALBUMARTIST',  'COMPOSER','LYRICIST','COMMENT','COMMENT','disc',
+      'mimeType']
   };
 
   constructor(tableName: string, sqlCreateTable: string, columns: Array<string>) {
@@ -103,22 +111,22 @@ export default class RdbUtils {
       callback();
       return
     }
-    
+
     relationalStore.getRdbStore(context, RdbUtils.STORE_CONFIG, (err, rdb) => {
       if (err) {
         Logger.error(RdbUtils.RDB_TAG, `gerRdbStore() failed, err: ${err}`);
         return;
       }
       this.rdbStore = rdb;
-      
+
       // 先创建表(如果不存在)
       this.rdbStore.executeSql(this.sqlCreateTable);
-      
+
       // 检查数据库版本并更新列
       try {
         // 检查表结构
         this.checkAndUpdateTableColumns();
-        Logger.info(RdbUtils.RDB_TAG, `数据库表结构检查完成`);
+        // Logger.info(RdbUtils.RDB_TAG, `数据库表结构检查完成`);
       } catch (e) {
         Logger.error(RdbUtils.RDB_TAG, `检查表结构时出错: ${e.message}`);
       }
@@ -126,7 +134,7 @@ export default class RdbUtils {
       callback();
     });
   }
-  
+
   /**
    * 检查并更新表列结构
    * 使用表信息查询和ALTER TABLE添加缺失的列
@@ -136,7 +144,7 @@ export default class RdbUtils {
       Logger.error(RdbUtils.RDB_TAG, `数据库连接未初始化`);
       return;
     }
-    
+
     try {
       // 查询表信息获取现有列
       const tableInfoQuery = `PRAGMA table_info(${this.tableName})`;
@@ -169,8 +177,13 @@ export default class RdbUtils {
             'channel_layout': 'TEXT',
             'start_time': 'TEXT',
 
+            'ALBUMARTIST': 'TEXT',
+            'COMPOSER': 'TEXT',
+            'LYRICIST': 'TEXT',
+            'COMMENT': 'TEXT',
+            'disc': 'TEXT',
           };
-          
+
           // 逐个添加列,不依赖于检查结果
           if (this.rdbStore) {
             // 遍历映射
@@ -178,7 +191,7 @@ export default class RdbUtils {
             for (let i = 0; i < columnEntries.length; i++) {
               const column = columnEntries[i];
               const type = requiredColumns[column];
-              
+
               const alterSql = `ALTER TABLE ${this.tableName} ADD COLUMN ${column} ${type}`;
               try {
                 // 对每个列使用Promise模式
@@ -188,17 +201,17 @@ export default class RdbUtils {
                   })
                   .catch((alterErr: Error) => {
                     // 列可能已经存在,这是预期的错误
-                    Logger.info(RdbUtils.RDB_TAG, `列 ${column} 可能已存在: ${alterErr.message}`);
+                    // Logger.info(RdbUtils.RDB_TAG, `列 ${column} 可能已存在: ${alterErr.message}`);
                   });
               } catch (e) {
                 Logger.error(RdbUtils.RDB_TAG, `添加列 ${column} 出错: ${e.message}`);
               }
             }
-            
+
             // 设置数据库版本
             if (this.rdbStore) {
               this.rdbStore.version = 1;
-              Logger.info(RdbUtils.RDB_TAG, `数据库升级完成,版本设置为 1`);
+              // Logger.info(RdbUtils.RDB_TAG, `数据库升级完成,版本设置为 1`);
             }
           }
         })

+ 54 - 14
entry/src/main/ets/common/util/Utility.ets

@@ -45,6 +45,19 @@ export interface FFMpegTags {
   USLT?: string;         // ID3v2同步歌词
   UNSYNCEDLYRICS?: string; // ID3v2非同步歌词
   // Add any other tag properties you expect
+  ALBUMARTIST?:string//专辑艺术家
+  COMPOSER?:string//作曲家
+  LYRICIST?:string//作词家
+  COMMENT?:string//注释
+  albumartist?:string//专辑艺术家
+  TPE2?:string//专辑艺术家
+  composer?:string//作曲家
+  lyricist?:string//作词家
+  TEXT?:string//作词家
+  comment?:string//注释
+  COMM?:string//注释
+  comm?:string//注释
+  disc?:string//音碟号
 }
 
 interface FFprobeFormat {
@@ -898,10 +911,35 @@ export class Utility {
             videoItem.probe_score  = format.probe_score;
             videoItem.nb_streams  = format.nb_streams;
             videoItem.nb_programs  = format.nb_programs;
-            videoItem.year  = tags.TYER || tags.date ||tags.DATE|| Utility.resourceToString(context, $r('app.string.unknown')); // try different tag names for year
+            videoItem.year  = tags.TYER || tags.date ||tags.DATE|| ''; // try different tag names for year
             videoItem.lyricContent  = tags.LYRICS || tags.lyrics  ||  tags.USLT || tags.UNSYNCEDLYRICS || '';
-            videoItem.genre  = tags.genre||tags.GENRE|| Utility.resourceToString(context, $r('app.string.unknown'));
-            videoItem.track  = tags.track||tags.TRACK|| Utility.resourceToString(context, $r('app.string.unknown'));
+            //console.info('readMetaInfoFFmpeg   videoItem.lyricContent: ',  videoItem.lyricContent);
+            // 如果标准字段没有歌词,则尝试解析 `lyrics-` 字段
+            // tags 必须是 Record<string, string | undefined>(或 any)
+            // 如果还是没有歌词内容,尝试查找自定义的lyrics-开头的属性(电脑版音乐标签内嵌歌词就是lyrics-XXX)
+            const tagsRecord = tags as Record<string, string>;
+            const possibleKeys = Object.keys(tagsRecord);
+            for (let i = 0; i < possibleKeys.length;  i++) {
+              const key = possibleKeys[i];
+              if (key && key.toLowerCase().startsWith('lyrics-'))  {
+                //console.info('readMetaInfoFFmpeg  videoItem.key:  ', key);
+                // 通过转换后的 Record 类型安全访问属性
+                videoItem.lyricContent  = tagsRecord[key];
+                //console.info('readMetaInfoFFmpeg  videoItem.lyricContent2:  ', videoItem.lyricContent);
+                if (videoItem.lyricContent)  {
+                  break;
+                }
+              }
+            }
+
+            videoItem.genre  = tags.genre||tags.GENRE|| '';
+            videoItem.track  = tags.track||tags.TRACK|| '';
+
+            videoItem.ALBUMARTIST  = tags.ALBUMARTIST||tags.albumartist||tags.TPE2|| '';
+            videoItem.COMPOSER  = tags.COMPOSER||tags.composer|| '';
+            videoItem.LYRICIST  = tags.LYRICIST||tags.lyricist||tags.TEXT ||'';
+            videoItem.COMMENT  = tags.COMMENT||tags.comment||tags.COMM|| '';
+            videoItem.disc  = tags.disc|| '';
 
             videoItem.bits_per_raw_sample = bits_per_raw_sample ||'1'
             videoItem.channel_layout = channel_layout || ''
@@ -920,14 +958,14 @@ export class Utility {
             // 如果有封面图片,则提取
             try {
               if (hasCover) {
-                  //提取封面
-                  let isSuccess:boolean= await getFFmpegCover(inputPath, imagePath);
-
-                  if(isSuccess){
-                    imagePath = fileUri.getUriFromPath(imagePath)
-                  }else{
-                    imagePath = ''
-                  }
+                //提取封面
+                let isSuccess:boolean= await getFFmpegCover(inputPath, imagePath);
+
+                if(isSuccess){
+                  imagePath = fileUri.getUriFromPath(imagePath)
+                }else{
+                  imagePath = ''
+                }
                 videoItem.pixelMapPath  = imagePath;
               }else if(Utility.isVideoByExtension(inputPath)){
                 pixelMap = await Utility.getFetchFrameByTime(inputPath)
@@ -1077,7 +1115,7 @@ export class Utility {
     for(let i=0;i<localList.length;i++){
       let pix = localList[i].pixelMapPath
       if(pix){
-       return pix
+        return pix
       }
 
     }
@@ -1464,7 +1502,7 @@ function fetchAlbumCover(avMetadataExtractor: media.AVMetadataExtractor): Promis
       } else {
         resolve(pixelMap);
       }
-       avMetadataExtractor.release();
+      avMetadataExtractor.release();
     });
   });
 }
@@ -1950,4 +1988,6 @@ function getFileFormatByPath(filePath: string): string {
 
   // 返回点号后的部分(转换为小写)
   return filePath.substring(lastDotIndex  + 1).toLowerCase();
-}
+}
+
+

+ 247 - 15
entry/src/main/ets/view/LocalMusic.ets

@@ -626,7 +626,7 @@ export struct LocalMusic {
     this.isPlayListBgGrass = PreferencesUtil.getBooleanSync(SettingPage.IS_PLAYLIST_BG_GRASS, true)
     this.isShowHeader = PreferencesUtil.getBooleanSync(SettingPage.IS_SHOW_HEADER, true)
     this.volume = PreferencesUtil.getNumberSync('DefalutVolume', this.volume)
-    this.isSwipe = PreferencesUtil.getBooleanSync(SettingPage.IS_SWIPE, true)
+    this.isSwipe = PreferencesUtil.getBooleanSync(SettingPage.IS_SWIPE, false)
     this.openSkipSongAnimate = PreferencesUtil.getBooleanSync(SettingPage.OPEN_SKIPSONG_ANIMATE, true)
     //如果是hicar连接状态,这些都是false
     if(this.isHiCar()){
@@ -4788,6 +4788,12 @@ export struct LocalMusic {
   @State genreStr: string  = ''
   @State imagePathStr: string  = ''
 
+  @State albumArtistStr: string  = ''
+  @State composerStr: string  = ''
+  @State lyricistStr: string  = ''
+  @State commentStr: string  = ''
+  @State discStr: string  = ''
+
   doUpdateData() {
     setTimeout(() => {
 
@@ -4811,14 +4817,14 @@ export struct LocalMusic {
       return
     }
 
-    let doChangeLyric = false
-    if(item.filePath==this.currentSong?.filePath){
-      if(this.lyricConStr !== this.lyricContent){
-        doChangeLyric = true
-      }
-    }else if(this.lyricConStr !== this.tempLyricContent){
-      doChangeLyric = true
-    }
+    // let doChangeLyric = false
+    // if(item.filePath==this.currentSong?.filePath){
+    //   if(this.lyricConStr !== this.lyricContent){
+    //     doChangeLyric = true
+    //   }
+    // }else if(this.lyricConStr !== this.tempLyricContent){
+    //   doChangeLyric = true
+    // }
 
     //用户更改了封面,那就内嵌下封面
     if(StrUtil.isNotEmpty(this.imagePathStr)){
@@ -4835,22 +4841,32 @@ export struct LocalMusic {
       title: this.titleStr,
       artist: this.artistStr,
       album: this.ablumStr,
-      lyrics:this.lyricConStr,
+      // LYRICS:this.lyricConStr,
+      // USLT:this.lyricConStr,
       TYER:this.yearStr,
       genre:this.genreStr,
       track:this.trackStr,
+      albumartist:this.albumArtistStr,
+      TPE2:this.albumArtistStr,//ID3v2 中通常没有专门的 "专辑艺术家" 字段,但有些软件会使用 TPE2 来表示专辑艺
+      COMPOSER:this.composerStr,
+      lyricist:this.lyricistStr,
+      TEXT:this.lyricistStr,//ID3v2 使用 TEXT 字段来表示作词者
+      comment:this.commentStr,
+      // comm:this.commentStr,//ID3v2:使用 COMM(Comment)字段。
+      disc:this.discStr,
     };
 
     //内嵌下标签的值,设置overwrite为true会直接修改原文件
     const result:boolean = await repairAudioMetadata(
       item.filePath,
+      this.lyricConStr,
       metadata,
       true
     );
 
     if (result) {
       this.table.updateMediaInfo(item.filePath, this.titleStr, this.artistStr, this.ablumStr,this.lyricConStr,
-        this.yearStr,this.genreStr,this.trackStr,
+        this.yearStr,this.genreStr,this.trackStr,this.albumArtistStr,this.composerStr, this.lyricistStr,this.commentStr,this.discStr,
         (success: boolean, error?: string) => {
           // this.isShowEdit = false
           if(this.isGridMusic){
@@ -4871,6 +4887,11 @@ export struct LocalMusic {
               this.currentSong.year = this.yearStr
               this.currentSong.genre = this.genreStr
               this.currentSong.track = this.trackStr
+
+              this.currentSong.ALBUMARTIST = this.albumArtistStr
+              this.currentSong.COMPOSER = this.composerStr
+              this.currentSong.LYRICIST = this.lyricistStr
+              this.currentSong.COMMENT = this.commentStr
             }
 
             this.doUpdateData()
@@ -4885,7 +4906,8 @@ export struct LocalMusic {
 
 
     } else {
-      console.log('onecold 元数据更新失败');
+      ToastUtil.showToast('内嵌音乐标签失败')
+      console.log('onecold 内嵌音乐标签失败');
     }
 
 
@@ -4976,6 +4998,7 @@ export struct LocalMusic {
               .fontSize(12)
               .height(38)
               .width(88)
+              .clickEffect({ level: ClickEffectLevel.MIDDLE,scale:0.6 })
               .backgroundColor(this.themeColor)
               .stateEffect(true)
               .margin({ right: 5, left: 12 })
@@ -5003,6 +5026,7 @@ export struct LocalMusic {
               .fontSize(12)
               .height(38)
               .width(88)
+              .clickEffect({ level: ClickEffectLevel.MIDDLE,scale:0.6 })
               .backgroundColor(this.themeColor)
               .stateEffect(true)
               .margin({ right: 12, left: 5 })
@@ -5114,6 +5138,7 @@ export struct LocalMusic {
             .height(40)
             .maxLines(1)
             .fontSize(14)
+            .type(InputType.Number)
             .layoutWeight(1)
             .fontColor($r('app.color.text_color'))
             .margin({ right: 20, left: 10 })
@@ -5133,6 +5158,7 @@ export struct LocalMusic {
             .height(40)
             .maxLines(1)
             .fontSize(14)
+            .type(InputType.Number)
             .layoutWeight(1)
             .fontColor($r('app.color.text_color'))
             .margin({ right: 20, left: 10 })
@@ -5144,6 +5170,27 @@ export struct LocalMusic {
         .margin({ top: 10, bottom: 10 })
         .justifyContent(FlexAlign.Start)
 
+        Row() {
+          Text('碟号:')
+            .fontSize(14)
+            .fontColor($r('app.color.text_color'))
+            .margin({ left: 22 })
+          TextInput({ text:item.disc })
+            .height(40)
+            .maxLines(1)
+            .fontSize(14)
+            .type(InputType.Number)
+            .layoutWeight(1)
+            .fontColor($r('app.color.text_color'))
+            .margin({ right: 20, left: 10 })
+            .onChange((val: string) => {
+              this.discStr = val
+            })
+        }
+        .width('100%')
+        .margin({ top: 10, bottom: 10 })
+        .justifyContent(FlexAlign.Start)
+
         Row() {
           Text('风格:')
             .fontSize(14)
@@ -5165,14 +5212,114 @@ export struct LocalMusic {
         .justifyContent(FlexAlign.Start)
 
         Row() {
-          Text('歌词:')
+          Text('专辑艺术家:')
+            .fontSize(14)
+            .fontColor($r('app.color.text_color'))
+            .margin({ left: 22 })
+          TextInput({ text: item.ALBUMARTIST })
+            .height(40)
+            .maxLines(1)
+            .fontSize(14)
+            .layoutWeight(1)
+            .fontColor($r('app.color.text_color'))
+            .margin({ right: 20, left: 10 })
+            .onChange((val: string) => {
+              this.albumArtistStr = val
+            })
+        }
+        .width('100%')
+        .margin({ top: 10, bottom: 10 })
+        .justifyContent(FlexAlign.Start)
+
+        Row() {
+          Text('作曲:')
+            .fontSize(14)
+            .fontColor($r('app.color.text_color'))
+            .margin({ left: 22 })
+          TextInput({ text: item.COMPOSER })
+            .height(40)
+            .maxLines(1)
+            .fontSize(14)
+            .layoutWeight(1)
+            .fontColor($r('app.color.text_color'))
+            .margin({ right: 20, left: 10 })
+            .onChange((val: string) => {
+              this.composerStr = val
+            })
+        }
+        .width('100%')
+        .margin({ top: 10, bottom: 10 })
+        .justifyContent(FlexAlign.Start)
+
+        Row() {
+          Text('作词:')
             .fontSize(14)
             .fontColor($r('app.color.text_color'))
             .margin({ left: 22 })
+          TextInput({ text: item.LYRICIST })
+            .height(40)
+            .maxLines(1)
+            .fontSize(14)
+            .layoutWeight(1)
+            .fontColor($r('app.color.text_color'))
+            .margin({ right: 20, left: 10 })
+            .onChange((val: string) => {
+              this.lyricistStr = val
+            })
+        }
+        .width('100%')
+        .margin({ top: 10, bottom: 10 })
+        .justifyContent(FlexAlign.Start)
+
+        Row() {
+          Text('注释:')
+            .fontSize(14)
+            .fontColor($r('app.color.text_color'))
+            .margin({ left: 22 })
+          TextInput({ text: item.COMMENT })
+            .height(40)
+            .maxLines(1)
+            .fontSize(14)
+            .layoutWeight(1)
+            .fontColor($r('app.color.text_color'))
+            .margin({ right: 20, left: 10 })
+            .onChange((val: string) => {
+              this.commentStr = val
+            })
+
+        }
+        .width('100%')
+        .margin({ top: 10, bottom: 10 })
+        .justifyContent(FlexAlign.Start)
+
+        Row() {
+          Column(){
+            Text('歌词:')
+              .fontSize(14)
+              .fontColor($r('app.color.text_color'))
+              .margin({ left: 22 })
+
+            Button({ type: ButtonType.Capsule, stateEffect: true }) {
+              SymbolGlyph($r('sys.symbol.trash_fill'))
+                .fontSize(25)
+                .alignSelf(ItemAlign.Center)
+                .margin({ left: 22,top:15})
+            }
+            .backgroundColor(Color.Transparent)
+            .visibility(StrUtil.isEmpty(this.tempLyricContent)&&StrUtil.isEmpty(this.lyricConStr)?
+            Visibility.None:Visibility.Visible)
+            .clickEffect({ level: ClickEffectLevel.MIDDLE,scale:0.6 })
+            .onClick(()=>{
+              this.lyricConStr = ''
+              this.lyricContent = ''
+              this.tempLyricContent = ''
+            })
+          }
+
           TextArea({ text: StrUtil.isNotEmpty(this.lyricConStr)?this.lyricConStr:
-            item.filePath === this.currentSong?.filePath ? this.lyricContent : this.tempLyricContent })
+          this.tempLyricContent })
             .type(TextAreaType.NORMAL)
-            .height(275)
+            .height('auto')
             .fontSize(14)
             .layoutWeight(1)
             .fontColor($r('app.color.text_color'))
@@ -5193,6 +5340,7 @@ export struct LocalMusic {
             .layoutWeight(1)
             .height(50)
             .width(100)
+            .clickEffect({ level: ClickEffectLevel.MIDDLE,scale:0.6 })
             .backgroundColor(this.themeColor)
             .stateEffect(true)
             .margin({ right: 20, bottom: 20 })
@@ -5206,6 +5354,7 @@ export struct LocalMusic {
             .layoutWeight(1)
             .height(50)
             .width(100)
+            .clickEffect({ level: ClickEffectLevel.MIDDLE,scale:0.6 })
             .backgroundColor(this.themeColor)
             .stateEffect(true)
             .margin({ left: 20, bottom: 20 })
@@ -5216,6 +5365,9 @@ export struct LocalMusic {
                 this.isShowEdit = false
               }
               this.setEditStrEmpty()
+              if(this.isShowPlay){
+                this.isShowEdit = false
+              }
 
             })
         }
@@ -5243,6 +5395,11 @@ export struct LocalMusic {
     this.genreStr = ''
     this.yearStr = ''
     this.trackStr = ''
+    this.albumArtistStr = ''
+    this.composerStr = ''
+    this.lyricistStr = ''
+    this.commentStr = ''
+    this.discStr = ''
   }
 
   @Builder
@@ -5497,6 +5654,80 @@ export struct LocalMusic {
         .width('100%')
         .margin({ top: 10, bottom: 10 })
         .justifyContent(FlexAlign.Start)
+        Row() {
+          Text('碟号:')
+            .fontSize(14)
+            .fontColor($r('app.color.text_color'))
+            .margin({ left: 22 })
+          Text(currentItem.disc)
+            .fontSize(14)
+            .margin({ left: 10 })
+            .fontColor($r('app.color.text_color'))
+            .layoutWeight(1)
+        }
+        .width('100%')
+        .margin({ top: 10, bottom: 10 })
+        .justifyContent(FlexAlign.Start)
+
+        Row() {
+          Text('专辑艺术家:')
+            .fontSize(14)
+            .fontColor($r('app.color.text_color'))
+            .margin({ left: 22 })
+          Text(currentItem.ALBUMARTIST)
+            .fontSize(14)
+            .margin({ left: 10 })
+            .fontColor($r('app.color.text_color'))
+            .layoutWeight(1)
+        }
+        .width('100%')
+        .margin({ top: 10, bottom: 10 })
+        .justifyContent(FlexAlign.Start)
+
+        Row() {
+          Text('作曲家:')
+            .fontSize(14)
+            .fontColor($r('app.color.text_color'))
+            .margin({ left: 22 })
+          Text(currentItem.COMPOSER)
+            .fontSize(14)
+            .margin({ left: 10 })
+            .fontColor($r('app.color.text_color'))
+            .layoutWeight(1)
+        }
+        .width('100%')
+        .margin({ top: 10, bottom: 10 })
+        .justifyContent(FlexAlign.Start)
+
+        Row() {
+          Text('作词家:')
+            .fontSize(14)
+            .fontColor($r('app.color.text_color'))
+            .margin({ left: 22 })
+          Text(currentItem.LYRICIST)
+            .fontSize(14)
+            .margin({ left: 10 })
+            .fontColor($r('app.color.text_color'))
+            .layoutWeight(1)
+        }
+        .width('100%')
+        .margin({ top: 10, bottom: 10 })
+        .justifyContent(FlexAlign.Start)
+
+        Row() {
+          Text('注释:')
+            .fontSize(14)
+            .fontColor($r('app.color.text_color'))
+            .margin({ left: 22 })
+          Text(currentItem.COMMENT)
+            .fontSize(14)
+            .margin({ left: 10 })
+            .fontColor($r('app.color.text_color'))
+            .layoutWeight(1)
+        }
+        .width('100%')
+        .margin({ top: 10, bottom: 10 })
+        .justifyContent(FlexAlign.Start)
 
 
         Row() {
@@ -9391,6 +9622,7 @@ export struct LocalMusic {
         break;
       case 15: //编辑标签
         this.setEditStrEmpty()
+        this.tempLyricContent = this.lyricContent
         this.isShowEdit = !this.isShowEdit;
         break;
       case 16: //悬浮歌词

+ 5 - 1
entry/src/main/ets/viewmodel/VideoItem.ets

@@ -62,7 +62,11 @@ export class VideoItem  {
   channel_layout?:string//声道布局:stereo为标准立体声(左+右)
   start_time?:string//起始时间:
 
-
+  ALBUMARTIST?:string//专辑艺术家
+  COMPOSER?:string//作曲家
+  LYRICIST?:string//作词家
+  COMMENT?:string//注释
+  disc?:string//碟号
 
   constructor(name: string, id: string, filePath: string, type:number,videoSize:number,cTime: string,pixelMap?: image.PixelMap,
     size?: string,pixelMapPath?: string,artist?: string,album?: string,fileName?: string, lastPlayed?:Date) {