Эх сурвалжийг харах

Merge remote-tracking branch 'origin/master' into feature/cdb/微信登录+用户中心

# Conflicts:
#	build-profile.json5
#	entry/src/main/ets/pages/NewIndex.ets
chendeben 1 жил өмнө
parent
commit
52364a7b22

+ 42 - 1
entry/src/main/ets/common/util/MediaTable.ets

@@ -164,6 +164,15 @@ export default class MediaTable {
       obj.album  = resultSet.getString(resultSet.getColumnIndex('album'));
       obj.isFav  = resultSet.getDouble(resultSet.getColumnIndex('isFav'));
       obj.pixelMapPath = resultSet.getString(resultSet.getColumnIndex('pixelMapPath'));
+
+      obj.duration  = resultSet.getString(resultSet.getColumnIndex('duration'));
+      obj.mimeType  = resultSet.getString(resultSet.getColumnIndex('mimeType'));
+      obj.trackCount  = resultSet.getString(resultSet.getColumnIndex('trackCount'));
+      obj.sampleRate  = resultSet.getString(resultSet.getColumnIndex('sampleRate'));
+      obj.lastPlayedStr  = resultSet.getString(resultSet.getColumnIndex('lastPlayedStr'));
+      obj.playCount  = resultSet.getDouble(resultSet.getColumnIndex('playCount'));
+      obj.lyricContent  = resultSet.getString(resultSet.getColumnIndex('lyricContent'));
+
       const valueBucket: relationalStore.ValuesBucket = obj
       // Step 4: 执行更新
       const updatePredicates = new relationalStore.RdbPredicates(RdbUtils.MEDIA_TABLE.tableName);
@@ -388,7 +397,13 @@ export default class MediaTable {
     );
     item.isFav = rs.getDouble(rs.getColumnIndex('isFav'));
 
-
+    item.duration = safeGet('duration');
+    item.mimeType = safeGet('mimeType');
+    item.trackCount =  safeGet('trackCount');
+    item.sampleRate = safeGet('sampleRate');
+    item.lastPlayedStr =safeGet('lastPlayedStr');
+    // item.playCount = rs.getDouble(rs.getColumnIndex('playCount'));
+    item.lyricContent =  safeGet('lyricContent')
 
     return item
   }
@@ -426,5 +441,31 @@ function generateBucket(item: VideoItem): relationalStore.ValuesBucket {
   if(item.pixelMapPath){
     obj.pixelMapPath = item.pixelMapPath;
   }
+
+
+  if(item.duration){
+    obj.duration = item.duration;
+  }
+  if(item.mimeType){
+    obj.mimeType = item.mimeType;
+  }
+  if(item.trackCount){
+    obj.trackCount = item.trackCount;
+  }
+
+  if(item.sampleRate){
+    obj.sampleRate = item.sampleRate;
+  }
+
+  if(item.lastPlayedStr){
+    obj.lastPlayedStr = item.lastPlayedStr;
+  }
+  if(item.playCount){
+    obj.playCount = item.playCount;
+  }
+  if(item.lyricContent){
+    obj.lyricContent = item.lyricContent;
+  }
+
   return obj;
 }

+ 28 - 1
entry/src/main/ets/common/util/RdbUtils.ets

@@ -1,6 +1,6 @@
 
 import relationalStore from '@ohos.data.relationalStore';
-import { StrUtil } from '@pura/harmony-utils';
+import { LogUtil, StrUtil } from '@pura/harmony-utils';
 import Logger from './Logger';
 import NetAxiosUtil from './NetAxiosUtil';
 
@@ -85,6 +85,33 @@ export default class RdbUtils {
       }
       this.rdbStore = rdb;
       this.rdbStore.executeSql(this.sqlCreateTable);
+      if (this.rdbStore.version  == 0) {
+          // 升级到版本1,添加列
+          // ✅ SQLite要求每列单独执行ALTER TABLE
+          const alterColumns = [
+            "ALTER TABLE mediaTable ADD COLUMN duration TEXT",
+            "ALTER TABLE mediaTable ADD COLUMN sampleRate TEXT",
+            "ALTER TABLE mediaTable ADD COLUMN playCount INTEGER DEFAULT 0",
+            "ALTER TABLE mediaTable ADD COLUMN lastPlayedStr TEXT",
+            "ALTER TABLE mediaTable ADD COLUMN trackCount TEXT",
+            "ALTER TABLE mediaTable ADD COLUMN lyricContent TEXT",
+            "ALTER TABLE mediaTable ADD COLUMN mimeType TEXT"
+          ];
+        try {
+          // 逐列执行添加
+          alterColumns.forEach(sql  => {
+            if(this.rdbStore)
+              this.rdbStore.executeSql(sql);
+          });
+          this.rdbStore.version = 1
+          LogUtil.info('onecold Upgrade  database from version 0 to 1 success.');
+        } catch (e) {
+          Logger.error(RdbUtils.RDB_TAG,  `Upgrade database failed: ${e}`);
+          // 注意:升级失败,可能需要处理,这里我们记录错误,但继续执行回调
+        }
+      }
+
+
       // Logger.info(RdbUtils.RDB_TAG, 'getRdbStore() finished.');
       callback();
     });

+ 32 - 0
entry/src/main/ets/common/util/Utility.ets

@@ -123,6 +123,15 @@ export class Utility {
     result.setDate(result.getDate() + days);
     return result;
   }
+
+  static convertToKHz(sampleRateHz: string|undefined): string {
+    if(StrUtil.isEmpty(sampleRateHz)||sampleRateHz ===undefined)
+      return '0KHz'
+
+    const sampleRateKHz = Number(sampleRateHz) / 1000;
+    return `${sampleRateKHz} KHz`;
+  }
+
   //根据字节获取大小
   static  formatFileSize(bytes:number) {
     const units = ['Bytes', 'Kbps', 'Mbps'];
@@ -627,6 +636,11 @@ export class Utility {
         let pixelMap:image.PixelMap|undefined|null = undefined
         let imagePath = ''
 
+        let duration:string | undefined = ''
+        let mimeType:string | undefined = ''
+        let trackCount:string | undefined = ''//轨道数量
+        let sampleRate:string | undefined = ''//音频的采样率单位为Hz
+
         if (canIUse("SystemCapability.Multimedia.Media.AVMetadataExtractor")) {
           try {
             // 创建AVMetadataExtractor对象
@@ -653,6 +667,19 @@ export class Utility {
               album = metadata.album
             }
 
+            if(StrUtil.isNotEmpty(metadata.duration)){
+              duration = DateUtil.getFormatDateStr(metadata.duration,'HH:mm:ss')
+            }
+            if(StrUtil.isNotEmpty(metadata.mimeType)){
+              mimeType = metadata.mimeType
+            }
+            if(StrUtil.isNotEmpty(metadata.trackCount)){
+              trackCount = metadata.trackCount
+            }
+            if(StrUtil.isNotEmpty(metadata.sampleRate)){
+              sampleRate = metadata.sampleRate
+            }
+
             let name = await MD5.digestSync(uri)
 
             if(isLoadPixelMap){
@@ -695,7 +722,12 @@ export class Utility {
 
         item = new VideoItem(musicName,uri ,uri,type,videoSize,addTime,undefined,fileSize,
           imagePath,artist,album,file.name)
+        item.duration = duration+'';
+        item.mimeType = mimeType;
+        item.trackCount = trackCount;
+        item.sampleRate = sampleRate;
         item.isFav = 0;
+        item.playCount = 0;
 
       })
     } catch (error) {

+ 20 - 18
entry/src/main/ets/pages/NewIndex.ets

@@ -289,8 +289,9 @@ struct NewIndex{
     List({space: 0, scroller: this.scroller}){
       ForEach(this.isShowSponsorship?mainViewModel.getDrawerData2():mainViewModel.getDrawerData(),(item: ItemData)=>{
         ListItem(){
-          Row() {
-            // 菜单图标
+          Button({ type: ButtonType.Capsule, stateEffect: true }) {
+            Row() {
+              // 菜单图标
             if (typeof item.img === 'object' && item.img !== null && (item.img as sysResource).type === 'symbol') {
               SymbolGlyph((item.img as sysResource).value as Resource)
                 // .size({ width: 22, height: 22 })
@@ -313,23 +314,24 @@ struct NewIndex{
                 .margin({ left: 2 })
             }
 
-            // 菜单标题
-            Text(item.title)
-              .margin({ left: 10, right: 20 })
-              .fontSize(15)
-              .fontColor($r('app.color.index_tab_font_color'))
-              .fontWeight(480)
-            Blank()
-            // 右侧箭头
-            Image($r('app.media.arrow_right'))
-              .width(22)
-              .height(22)
-              .margin({ left: 20, right: 0 })
-              .align(Alignment.Center)
+              // 菜单标题
+              Text(item.title)
+                .margin({ left: 10, right: 20 })
+                .fontSize(15)
+                .fontColor($r('app.color.index_tab_font_color'))
+                .fontWeight(480)
+              Blank()
+              // 右侧箭头
+              Image($r('app.media.arrow_right'))
+                .width(22)
+                .height(22)
+                .margin({ left: 20, right: 0 })
+                .align(Alignment.Center)
+            }
+            .width('100%')
+            .height(55)
           }
-          .width('100%')
-          .height(55)
-          .useEffect(true)
+          .backgroundColor(Color.Transparent)
           .onClick(async () => {
             // 根据 item.id 跳转或切换功能
             switch (item.id) {

+ 475 - 364
entry/src/main/ets/view/LocalMusic.ets

@@ -87,6 +87,7 @@ import { DEBUG } from 'BuildProfile';
 import { LrcParser } from '@sgaolei/lrc_parser';
 import { IBestIcon } from "@ibestservices/ibest-ui";
 import app, { AppResponse } from '@system.app';
+import { Log } from '@tencent/wechat_open_sdk';
 
 const TAG = 'LocalMusic';
 
@@ -454,6 +455,24 @@ export struct LocalMusic {
     this.themeMode = PreferencesUtil.getNumberSync(SettingPage.THEME_MODE, 0)
     this.applyThemeMode(this.themeMode)
 
+    this.windowClass.on('windowSizeChange', (size) => {
+      LogUtil.info('onecold  windowSizeChange')
+      if(!this.isPhoneLan()){
+        LogUtil.info('onecold  windowSizeChange11')
+        this.startAutoHide()
+      }else{
+        LogUtil.info('onecold  windowSizeChange13')
+        this.isAutoHide = false
+      }
+
+    });
+
+  }
+
+  startAutoHide(){
+    setTimeout(() => {
+      this.isAutoHide = true
+    }, 4000)
   }
 
   applyThemeMode(mode: number) {
@@ -2907,7 +2926,7 @@ export struct LocalMusic {
     .layoutWeight(1)
     .scrollBar(BarState.Off)
     .supportAnimation(true)
-    // .cachedCount(5)
+    .cachedCount(10)
     .columnsTemplate('1fr '.repeat(this.currentWidthBreakpoint === WidthBreakpoint.WIDTH_SM ? 2 : 4))
     .rowsGap(12)
     .visibility(this.isGridMusic?Visibility.Visible:Visibility.None)
@@ -4117,6 +4136,51 @@ export struct LocalMusic {
         .margin({ top: 10, bottom: 10 })
         .justifyContent(FlexAlign.Start)
 
+        Row() {
+          Text('时长:')
+            .fontSize(14)
+            .fontColor(Color.White)
+            .margin({ left: 22 })
+          Text(this.totalTime)
+            .fontSize(14)
+            .margin({ left: 10 })
+            .fontColor(Color.White)
+            .layoutWeight(1)
+        }
+        .width('100%')
+        .margin({ top: 10, bottom: 10 })
+        .justifyContent(FlexAlign.Start)
+
+        Row() {
+          Text('采样率:')
+            .fontSize(14)
+            .fontColor(Color.White)
+            .margin({ left: 22 })
+          Text(Utility.convertToKHz(this.currentSong.sampleRate))
+            .fontSize(14)
+            .margin({ left: 10 })
+            .fontColor(Color.White)
+            .layoutWeight(1)
+        }
+        .width('100%')
+        .margin({ top: 10, bottom: 10 })
+        .justifyContent(FlexAlign.Start)
+
+        Row() {
+          Text('格式:')
+            .fontSize(14)
+            .fontColor(Color.White)
+            .margin({ left: 22 })
+          Text(this.currentSong.mimeType)
+            .fontSize(14)
+            .margin({ left: 10 })
+            .fontColor(Color.White)
+            .layoutWeight(1)
+        }
+        .width('100%')
+        .margin({ top: 10, bottom: 10 })
+        .justifyContent(FlexAlign.Start)
+
         Row() {
           Text('文件大小:')
             .fontSize(14)
@@ -4838,7 +4902,12 @@ export struct LocalMusic {
     })
     .backgroundBlurStyle(this.isPuraWP()&&this.currentSwiperIndex===0?BlurStyle.NONE:BlurStyle.BACKGROUND_ULTRA_THICK)
     .hitTestBehavior(HitTestMode.Transparent)
+    .backgroundBrightness({rate:this.isPuraWP()?0.1:0,lightUpDegree:-0.1})
     .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])
+    .onClick( ()=>{
+      this.isAutoHide = false
+      this.startAutoHide()
+    })
   }
 
   @State progressValue: number = 0;
@@ -5464,12 +5533,15 @@ export struct LocalMusic {
           seekLineColor: "#80ffffff", // 滑动定位线颜色
           seekUIStyle: "listItem", // 滑动定位样式(seekLine传统样式,listItem类似抖音汽水音乐样式)
           onSeekAction: (position: number) => { // 滑动歌词触发seek定位回调
-            this.isSeekTo = true;
-            this.mDestroyPage = false;
-            this.showLoadIng();
-            // LogUtils.getInstance().LOGI("onecold-->seekValue start:" + position);
-            this.seekTo(position + "");
-            this.isSeekTo = false;
+            if(!this.isPlaying){
+              this.startPlayOrResumePlay()
+            }else{
+              this.isSeekTo = true;
+              this.mDestroyPage = false;
+              this.showLoadIng();
+              this.seekTo(position + "");
+              this.isSeekTo = false;
+            }
             return true
           }
         })
@@ -5498,76 +5570,95 @@ export struct LocalMusic {
         Row({ space: 33 }) {
 
 
-          //更多功能
-          Image($r('app.media.menu'))
-            .width(24)
-            .bindSheet($$this.isShowMoreView, this.PlayMoreSheet(), {
-              height: this.isCoverOpacity() ? '95%' : '93%',
-              preferType: this.currentBreakpoint!==BreakpointTypeEnum.SM?SheetType.CENTER:SheetType.BOTTOM,
-              dragBar: true,
-              showClose: true,
-              blurStyle: BlurStyle.Thin,
-              backgroundColor: Color.Transparent,
-            })
-            .onClick(() => {
-              this.isShowMoreView = !this.isShowMoreView;
-            })
-
-          Image($r('app.media.ic_previous'))
-            .width(33)
-
-            .aspectRatio(CommonConstants.ASPECT_RATIO)
-            .onClick(async () => {
+          Button({type:ButtonType.Circle,stateEffect:true}){
+            //更多功能
+            Image($r('app.media.menu'))
+              .width(24)
+              .bindSheet($$this.isShowMoreView, this.PlayMoreSheet(), {
+                height: this.isCoverOpacity() ? '95%' : '93%',
+                preferType: this.currentBreakpoint!==BreakpointTypeEnum.SM?SheetType.CENTER:SheetType.BOTTOM,
+                dragBar: true,
+                showClose: true,
+                blurStyle: BlurStyle.Thin,
+                backgroundColor: Color.Transparent,
+              })
+          }
+          .backgroundColor(Color.Transparent)
+          .onClick(() => {
+            this.isShowMoreView = !this.isShowMoreView;
+          })
 
-              this.playPrevious()
+          Button({type:ButtonType.Circle,stateEffect:true}){
+            Image($r('app.media.ic_previous'))
+              .width(33)
+              .aspectRatio(CommonConstants.ASPECT_RATIO)
+              .onClick(async () => {
+                this.playPrevious()
+              })
+          }
+          .backgroundColor(Color.Transparent)
 
-            })
         }
         .margin({ left: 33 })
 
-        Column() {
-          Image(this.CONTROL_PlayStatus === PlayStatus.PLAY ?
-          $r('app.media.ic_public_play') : $r('app.media.ic_public_pause'))
-            .width(this.isPhoneLan()?48:60)
-            .aspectRatio(CommonConstants.ASPECT_RATIO)
-            .onClick(async () => {
-              this.playOrPause()
+        Button({type:ButtonType.Circle,stateEffect:true}){
+          Column() {
+            Image(this.CONTROL_PlayStatus === PlayStatus.PLAY ?
+            $r('app.media.ic_public_play') : $r('app.media.ic_public_pause'))
+              .width(this.isPhoneLan()?48:60)
+              .aspectRatio(CommonConstants.ASPECT_RATIO)
+              .onClick(async () => {
+                this.playOrPause()
 
 
-            })
+              })
+          }
+
         }
+        .backgroundColor(Color.Transparent)
         .layoutWeight(1)
-        .margin({ left: 20, right: 20 })
+        .margin({ left: 33, right: 33 })
+
 
         Row({ space: 33 }) {
-          Image($r('app.media.ic_next'))
-            .width(33)
-            .aspectRatio(CommonConstants.ASPECT_RATIO)
-            .onClick(() => {
+          Button({ type: ButtonType.Capsule, stateEffect: true }) {
+            Image($r('app.media.ic_next'))
+              .width(33)
+              .aspectRatio(CommonConstants.ASPECT_RATIO)
+              .onClick(() => {
 
-              this.playNext();
+                this.playNext();
+
+              })
+          }
+          .backgroundColor(Color.Transparent)
+          .width(33)
+
+          Button({type:ButtonType.Circle,stateEffect:true}){
+            //添加或取消收藏
+            Image(Utility.getIsFav(this.favList,this.currentSong)?
+            $r('app.media.add_fac_light'):$r('app.media.add_fac'))
+              .width(24)
+              .aspectRatio(CommonConstants.ASPECT_RATIO)
+              .onClick(async () => {
+                if(this.currentSong){
+                  this.doFav(this.currentSong)
+                }
+              })
+          }
+          .backgroundColor(Color.Transparent)
+          .width(24)
 
-            })
-          //添加或取消收藏
-          Image(Utility.getIsFav(this.favList,this.currentSong)?$r('app.media.add_fac_light'):$r('app.media.add_fac'))
-            .width(24)
-            .aspectRatio(CommonConstants.ASPECT_RATIO)
-            .onClick(async () => {
-              if(this.currentSong){
-                this.doFav(this.currentSong)
-              }
-            })
         }
         .margin({ right: 33 })
 
       }
       .width('100%')
       .margin(10)
-
+      .justifyContent(FlexAlign.Center)
       //播放进度条
       this.playProgressView()
 
-      // .visibility(this.isHide?Visibility.Hidden:Visibility.Visible)
 
     }
     .position({ bottom:this.isCoverOpacity()?55: 80 }) // 将  固定在底部
@@ -5578,30 +5669,29 @@ export struct LocalMusic {
   @Builder
   playProgressView(){
     Row() {
-
-      Column() {
-        if (this.playType === 0) {
-          Image($r('app.media.loop'))
-            .width($r('app.float.control_image_width'))
-            .margin(10)
-            .aspectRatio(CommonConstants.ASPECT_RATIO)
-        } else if (this.playType === 1) {
-          Image($r('app.media.single'))
-            .width($r('app.float.control_image_width'))
-            .margin(10)
-            .aspectRatio(CommonConstants.ASPECT_RATIO)
-        } else if (this.playType === 2) {
-          Image($r('app.media.normal_play'))
-            .width($r('app.float.control_image_width'))
-            .margin(10)
-            .aspectRatio(CommonConstants.ASPECT_RATIO)
-        } else if (this.playType === 3) {
-          Image($r('app.media.random'))
-            .width($r('app.float.control_image_width'))
-            .margin(10)
-            .aspectRatio(CommonConstants.ASPECT_RATIO)
+      Button({type:ButtonType.Circle,stateEffect:true}){
+        Column() {
+          if (this.playType === 0) {
+            Image($r('app.media.loop'))
+              .width($r('app.float.control_image_width'))
+              .aspectRatio(CommonConstants.ASPECT_RATIO)
+          } else if (this.playType === 1) {
+            Image($r('app.media.single'))
+              .width($r('app.float.control_image_width'))
+              .aspectRatio(CommonConstants.ASPECT_RATIO)
+          } else if (this.playType === 2) {
+            Image($r('app.media.normal_play'))
+              .width($r('app.float.control_image_width'))
+              .aspectRatio(CommonConstants.ASPECT_RATIO)
+          } else if (this.playType === 3) {
+            Image($r('app.media.random'))
+              .width($r('app.float.control_image_width'))
+              .aspectRatio(CommonConstants.ASPECT_RATIO)
+          }
         }
       }
+      .backgroundColor(Color.Transparent)
+      .margin({ left:10,right:10 })
       .onClick(async () => {
         this.setLoopMode()
 
@@ -5651,22 +5741,26 @@ export struct LocalMusic {
 
 
       //播放列表
-      Image($r('app.media.playlist'))
-        .width($r('app.float.control_image_width'))
+      Button({type:ButtonType.Circle,stateEffect:true}){
+        Image($r('app.media.playlist'))
+          .width($r('app.float.control_image_width'))
+
+          .aspectRatio(CommonConstants.ASPECT_RATIO)
+          .bindSheet($$this.isShowSheetView, this.PlayListSheet(), {
+            height: '95%',
+            dragBar: true,
+            showClose: true,
+            preferType: this.currentBreakpoint !== BreakpointTypeEnum.SM ? SheetType.CENTER : SheetType.BOTTOM,
+            blurStyle: BlurStyle.Thin,
+            backgroundColor: Color.Transparent,
+            title: {
+              title: Utility.resourceToString(this.context, $r('app.string.current_play_list'))
+                + `(${this.songList.length}首)`
+            }
+          })
+      }
+        .backgroundColor(Color.Transparent)
         .margin({ right: 10, left: 20 })
-        .aspectRatio(CommonConstants.ASPECT_RATIO)
-        .bindSheet($$this.isShowSheetView, this.PlayListSheet(), {
-          height: '95%',
-          dragBar: true,
-          showClose: true,
-          preferType: this.currentBreakpoint !== BreakpointTypeEnum.SM ? SheetType.CENTER : SheetType.BOTTOM,
-          blurStyle: BlurStyle.Thin,
-          backgroundColor: Color.Transparent,
-          title: {
-            title: Utility.resourceToString(this.context, $r('app.string.current_play_list'))
-              + `(${this.songList.length}首)`
-          }
-        })
         .onClick(() => {
           this.isShowSheetView = !this.isShowSheetView;
           this.isFrontWhite = true
@@ -5674,9 +5768,14 @@ export struct LocalMusic {
 
     }
     .width(PlayConstants.PROGRESS_ROW_WIDTH)
-    .visibility(this.isPhoneLan()?Visibility.None:Visibility.Visible)
+    .height(this.isPhoneLan()?25:33)
+    .visibility(this.isPhoneLan()&&this.isAutoHide?Visibility.None:Visibility.Visible)
+    .animation({
+      duration: 666,
+      curve: 'ease-in-out' // 可选动画曲线
+    })
   }
-
+  @State isAutoHide: boolean = true//手机横屏自动隐藏播放进退条,点击屏幕可以显示,倒计时4秒后又自动隐藏
   @State isCoverRectangle: boolean = false
 
   @Builder
@@ -5774,7 +5873,7 @@ export struct LocalMusic {
       }
 
       .margin({
-        bottom: this.isCoverOpacity() || this.isCoverRectangle ? 110 : 0,
+        bottom: this.isCoverOpacity() || this.isCoverRectangle ? 120 : 0,
         top: this.isCoverOpacity() ? 0 : this.isCoverRectangle ? 40 : 30
       })
 
@@ -5911,11 +6010,11 @@ export struct LocalMusic {
               .width(60)
               .height(28)
               .fontSize(12)
-              .fontColor(this.currentLyricAlignMode === index ? '#FFFFFF' : '#007DFF')
-              .backgroundColor(this.currentLyricAlignMode === index ? '#007DFF' : '#FFFFFF')
+              .fontColor('#FFFFFF')
+              .backgroundColor(this.currentLyricAlignMode === index ? $r('app.color.title_bar_bg') :Color.Transparent)
               .border({
                 color: this.currentLyricAlignMode === index ? '#007DFF' : '#DDDDDD',
-                width: 1
+                width: 1.8
               })
               .onClick(() => {
                 this.setLyricAlignMode(index)
@@ -6516,284 +6615,287 @@ export struct LocalMusic {
       Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Start }) {
 
         ForEach(this.moreItems, (more: MoreItem) => {
-          Row() {
-            if (more.id === 3) {
-              Image(more.image)
-                .width(24)
-                .height(24)
-                .margin({ left: 10, right: 10 })
-                .onClick(() => {
-                  this.isShowDetailMore = !this.isShowDetailMore;
-                })
-              Text(more.title)
-                .fontSize(16)
-                .fontColor(Color.White)
-                .onClick(() => {
-                  this.doMore(more.id)
-                })
-                .bindSheet($$this.isShowDetailMore, this.detailSheet(), {
-                  height: this.isCoverOpacity() ? '95%' : '65%',
-                  dragBar: true,
-                  preferType: this.currentBreakpoint!==BreakpointTypeEnum.SM?SheetType.CENTER:SheetType.BOTTOM,
-                  showClose: true,
-                  blurStyle: BlurStyle.Thin,
-                  backgroundColor: Color.Transparent,
-                  title: { title: '歌曲信息' }
-                })
-                .onClick(() => {
-                  this.isShowDetailMore = !this.isShowDetailMore;
-                })
-            } else if (more.id === 15&&this.currentSong) { //编辑信息
-              Image(more.image)
-                .width(24)
-                .height(24)
-                .margin({ left: 10, right: 10 })
-                .onClick(() => {
-                  this.isShowEdit = !this.isShowEdit;
-                })
-              Text(more.title)
-                .fontSize(16)
-                .fontColor(Color.White)
-                .bindSheet($$this.isShowEdit, this.editSheet(this.currentSong), {
-                  height: this.isCoverOpacity() ? '95%' : '93%',
-                  dragBar: true,
-                  showClose: true,
-                  preferType: this.currentBreakpoint!==BreakpointTypeEnum.SM?SheetType.CENTER:SheetType.BOTTOM,
-                  // blurStyle:BlurStyle.Thin,
-                  // backgroundColor:Color.Transparent,
-                  title: { title: '编辑信息' }
-                })
-                .onClick(() => {
-                  this.isShowEdit = !this.isShowEdit;
-                })
-            } else if (more.id === 5) { //定时关闭
-              Image(more.image)
-                .width(24)
-                .height(24)
-                .margin({ left: 10, right: 10 })
-                .onClick(() => {
-                  this.isShowTimeCloseMore = !this.isShowTimeCloseMore;
-                })
-              Text(more.title)
-                .fontSize(16)
-                .fontColor(Color.White)
-                .onClick(() => {
-                  this.doMore(more.id)
-                })
-                .bindSheet($$this.isShowTimeCloseMore, this.TimeCloseSheet(), {
-                  height: this.isCoverOpacity() ? '95%' : '78%',
-                  preferType: this.currentBreakpoint!==BreakpointTypeEnum.SM?SheetType.CENTER:SheetType.BOTTOM,
-                  dragBar: true,
-                  showClose: true,
-                  title: { title: $r('app.string.time_close') }
-                })
-                .onClick(() => {
-                  this.isShowTimeCloseMore = !this.isShowTimeCloseMore;
-                })
-            } else if (more.id === 2) { //歌词设置
-              Image(more.image)
-                .width(24)
-                .height(24)
-                .margin({ left: 10, right: 10 })
-                .onClick(() => {
-                  this.isLyricSetting = !this.isLyricSetting;
-                  this.isShowMoreView = false
-                })
-              Text(more.title)
-                .fontSize(16)
-                .fontColor(Color.White)
-                .onClick(() => {
-                  this.isLyricSetting = !this.isLyricSetting;
-                  this.isShowMoreView = false
-                })
-            } else if (more.id === 11) { //跳过头尾
-              Image(more.image)
-                .width(24)
-                .height(24)
-                .margin({ left: 10, right: 10 })
-                .onClick(() => {
-                  this.isJumpSetting = !this.isJumpSetting;
-                })
-              Text(more.title)
-                .fontSize(16)
-                .fontColor(Color.White)
-                .bindSheet($$this.isJumpSetting, this.JumpTopEndSheet(), {
-                  height: this.isCoverOpacity() ? '95%' : '60%',
-                  dragBar: true,
-                  preferType: this.currentBreakpoint!==BreakpointTypeEnum.SM?SheetType.CENTER:SheetType.BOTTOM,
-                  showClose: true,
-                  blurStyle: BlurStyle.Thin,
-                  backgroundColor: Color.Transparent,
-                  title: { title: '跳过头尾' }
-                })
-                .onClick(() => {
-                  this.isJumpSetting = !this.isJumpSetting;
-                })
-            } else if (more.id === 12) { //投播
-              AVCastPicker({
-                customPicker: (): void => this.TPImageBuilder(more),
-                onStateChange: (state) => {
-                  if (state == AVCastPickerState.STATE_APPEARING) {
-                    console.log(' The picker starts showing.');
-                  } else if (state == AVCastPickerState.STATE_DISAPPEARING) {
-                    console.log(' The picker finishes presenting.');
-                  }
-                },
-                pickerStyle: AVCastPickerStyle.STYLE_PANEL,
-                sessionType: 'video'
-              })
-                .id('AVCastPicker')
-                .width(46)
-            } else {
-              Image(more.image)
-                .width(24)
-                .height(24)
-                .margin({ left: 10, right: 10 })
-                .onClick(() => {
-
-                  this.doMore(more.id)
-                })
-              Text(more.title)
-                .fontSize(16)
-
-                .fontColor(Color.White)
-                .onClick(() => {
-                  this.doMore(more.id)
-                })
-              Select([//倍速
-                { value: '0.25x' },
-                { value: '0.5x' },
-                { value: '0.75x' },
-                { value: '1x' },
-                { value: '1.25x' },
-                { value: '1.5x' },
-                { value: '1.75x' },
-                { value: '2x' },
-                { value: '3x' }])
-                .font({ size: 16, weight: FontWeight.Medium })
-                .fontColor($r('sys.color.white'))
-                .margin({ left: 25 })
-                .visibility(more.id === 1 ? Visibility.Visible : Visibility.None)
-                .selected(CommonConstants.video_speed_list.indexOf(this.playSpeed))
-                .value(Utility.optimizedFormat(this.playSpeed))
-                .onSelect(async (_index: number, text?: string | undefined) => {
-                  let speed = parseFloat(text?.replace('x', '') || '1');
-                  if (!CommonConstants.video_speed_list.includes(speed)) {
-                    speed = 1;
-                  }
-                  this.playSpeed = speed
-                  this.mIjkMediaPlayer.setSpeed(this.playSpeed + 'f');
+          Button({ type: ButtonType.Capsule, stateEffect: true }) {
+            Row() {
+              if (more.id === 3) {
+                Image(more.image)
+                  .width(24)
+                  .height(24)
+                  .margin({ left: 10, right: 10 })
+                  .onClick(() => {
+                    this.isShowDetailMore = !this.isShowDetailMore;
+                  })
+                Text(more.title)
+                  .fontSize(16)
+                  .fontColor(Color.White)
+                  .onClick(() => {
+                    this.doMore(more.id)
+                  })
+                  .bindSheet($$this.isShowDetailMore, this.detailSheet(), {
+                    height: this.isCoverOpacity() ? '95%' : '65%',
+                    dragBar: true,
+                    preferType: this.currentBreakpoint!==BreakpointTypeEnum.SM?SheetType.CENTER:SheetType.BOTTOM,
+                    showClose: true,
+                    blurStyle: BlurStyle.Thin,
+                    backgroundColor: Color.Transparent,
+                    title: { title: '歌曲信息' }
+                  })
+                  .onClick(() => {
+                    this.isShowDetailMore = !this.isShowDetailMore;
+                  })
+              } else if (more.id === 15&&this.currentSong) { //编辑信息
+                Image(more.image)
+                  .width(24)
+                  .height(24)
+                  .margin({ left: 10, right: 10 })
+                  .onClick(() => {
+                    this.isShowEdit = !this.isShowEdit;
+                  })
+                Text(more.title)
+                  .fontSize(16)
+                  .fontColor(Color.White)
+                  .bindSheet($$this.isShowEdit, this.editSheet(this.currentSong), {
+                    height: this.isCoverOpacity() ? '95%' : '93%',
+                    dragBar: true,
+                    showClose: true,
+                    preferType: this.currentBreakpoint!==BreakpointTypeEnum.SM?SheetType.CENTER:SheetType.BOTTOM,
+                    // blurStyle:BlurStyle.Thin,
+                    // backgroundColor:Color.Transparent,
+                    title: { title: '编辑信息' }
+                  })
+                  .onClick(() => {
+                    this.isShowEdit = !this.isShowEdit;
+                  })
+              } else if (more.id === 5) { //定时关闭
+                Image(more.image)
+                  .width(24)
+                  .height(24)
+                  .margin({ left: 10, right: 10 })
+                  .onClick(() => {
+                    this.isShowTimeCloseMore = !this.isShowTimeCloseMore;
+                  })
+                Text(more.title)
+                  .fontSize(16)
+                  .fontColor(Color.White)
+                  .onClick(() => {
+                    this.doMore(more.id)
+                  })
+                  .bindSheet($$this.isShowTimeCloseMore, this.TimeCloseSheet(), {
+                    height: this.isCoverOpacity() ? '95%' : '78%',
+                    preferType: this.currentBreakpoint!==BreakpointTypeEnum.SM?SheetType.CENTER:SheetType.BOTTOM,
+                    dragBar: true,
+                    showClose: true,
+                    title: { title: $r('app.string.time_close') }
+                  })
+                  .onClick(() => {
+                    this.isShowTimeCloseMore = !this.isShowTimeCloseMore;
+                  })
+              } else if (more.id === 2) { //歌词设置
+                Image(more.image)
+                  .width(24)
+                  .height(24)
+                  .margin({ left: 10, right: 10 })
+                  .onClick(() => {
+                    this.isLyricSetting = !this.isLyricSetting;
+                    this.isShowMoreView = false
+                  })
+                Text(more.title)
+                  .fontSize(16)
+                  .fontColor(Color.White)
+                  .onClick(() => {
+                    this.isLyricSetting = !this.isLyricSetting;
+                    this.isShowMoreView = false
+                  })
+              } else if (more.id === 11) { //跳过头尾
+                Image(more.image)
+                  .width(24)
+                  .height(24)
+                  .margin({ left: 10, right: 10 })
+                  .onClick(() => {
+                    this.isJumpSetting = !this.isJumpSetting;
+                  })
+                Text(more.title)
+                  .fontSize(16)
+                  .fontColor(Color.White)
+                  .bindSheet($$this.isJumpSetting, this.JumpTopEndSheet(), {
+                    height: this.isCoverOpacity() ? '95%' : '60%',
+                    dragBar: true,
+                    preferType: this.currentBreakpoint!==BreakpointTypeEnum.SM?SheetType.CENTER:SheetType.BOTTOM,
+                    showClose: true,
+                    blurStyle: BlurStyle.Thin,
+                    backgroundColor: Color.Transparent,
+                    title: { title: '跳过头尾' }
+                  })
+                  .onClick(() => {
+                    this.isJumpSetting = !this.isJumpSetting;
+                  })
+              } else if (more.id === 12) { //投播
+                AVCastPicker({
+                  customPicker: (): void => this.TPImageBuilder(more),
+                  onStateChange: (state) => {
+                    if (state == AVCastPickerState.STATE_APPEARING) {
+                      console.log(' The picker starts showing.');
+                    } else if (state == AVCastPickerState.STATE_DISAPPEARING) {
+                      console.log(' The picker finishes presenting.');
+                    }
+                  },
+                  pickerStyle: AVCastPickerStyle.STYLE_PANEL,
+                  sessionType: 'video'
                 })
-              Slider({
-                value: this.volume,
-                min: 0,
-                max: 1,
-                step: 0.1,
-                style: SliderStyle.OutSet
-              })
-                .margin({ left: 18, right: 8 })
-                .blockColor(Color.Red)
-                .trackColor($r('app.color.speed_text_color'))
-                .selectedColor(Color.White)
-                .trackThickness(9)
-                .visibility(more.id === 9 ? Visibility.Visible : Visibility.None)
-                .onChange((value: number) => {
-                  this.volume = value;
-                  this.mIjkMediaPlayer.setVolume(this.volume.toString(), this.volume.toString());
+                  .id('AVCastPicker')
+                  .width(46)
+              } else {
+                Image(more.image)
+                  .width(24)
+                  .height(24)
+                  .margin({ left: 10, right: 10 })
+                  .onClick(() => {
+
+                    this.doMore(more.id)
+                  })
+                Text(more.title)
+                  .fontSize(16)
+
+                  .fontColor(Color.White)
+                  .onClick(() => {
+                    this.doMore(more.id)
+                  })
+                Select([//倍速
+                  { value: '0.25x' },
+                  { value: '0.5x' },
+                  { value: '0.75x' },
+                  { value: '1x' },
+                  { value: '1.25x' },
+                  { value: '1.5x' },
+                  { value: '1.75x' },
+                  { value: '2x' },
+                  { value: '3x' }])
+                  .font({ size: 16, weight: FontWeight.Medium })
+                  .fontColor($r('sys.color.white'))
+                  .margin({ left: 25 })
+                  .visibility(more.id === 1 ? Visibility.Visible : Visibility.None)
+                  .selected(CommonConstants.video_speed_list.indexOf(this.playSpeed))
+                  .value(Utility.optimizedFormat(this.playSpeed))
+                  .onSelect(async (_index: number, text?: string | undefined) => {
+                    let speed = parseFloat(text?.replace('x', '') || '1');
+                    if (!CommonConstants.video_speed_list.includes(speed)) {
+                      speed = 1;
+                    }
+                    this.playSpeed = speed
+                    this.mIjkMediaPlayer.setSpeed(this.playSpeed + 'f');
+                  })
+                Slider({
+                  value: this.volume,
+                  min: 0,
+                  max: 1,
+                  step: 0.1,
+                  style: SliderStyle.OutSet
                 })
-                .layoutWeight(1)
-              Blank()
-              Toggle({ type: ToggleType.Switch, isOn: this.isMusicMemoryPlay })
-                .selectedColor($r('app.color.title_bar_bg'))
-                .switchPointColor(Color.White)
-                .margin({ right: 15 })
-                .visibility(more.id == 6 ? Visibility.Visible : Visibility.None)
-                .onChange((checked: boolean) => { // 选择开关状态变化时触发事件
-                  if (more.id == 6) {
-                    this.isMusicMemoryPlay = checked;
-                    PreferencesUtil.put(SettingPage.iS_MUSIC_MEMORY_PLAY, this.isMusicMemoryPlay)
-                    if (this.isMusicMemoryPlay) {
-                      ToastUtil.showToast('记忆播放已开启')
-                    } else {
-                      ToastUtil.showToast('记忆播放已关闭')
+                  .margin({ left: 18, right: 8 })
+                  .blockColor(Color.Red)
+                  .trackColor($r('app.color.speed_text_color'))
+                  .selectedColor(Color.White)
+                  .trackThickness(9)
+                  .visibility(more.id === 9 ? Visibility.Visible : Visibility.None)
+                  .onChange((value: number) => {
+                    this.volume = value;
+                    this.mIjkMediaPlayer.setVolume(this.volume.toString(), this.volume.toString());
+                  })
+                  .layoutWeight(1)
+                Blank()
+                Toggle({ type: ToggleType.Switch, isOn: this.isMusicMemoryPlay })
+                  .selectedColor($r('app.color.title_bar_bg'))
+                  .switchPointColor(Color.White)
+                  .margin({ right: 15 })
+                  .visibility(more.id == 6 ? Visibility.Visible : Visibility.None)
+                  .onChange((checked: boolean) => { // 选择开关状态变化时触发事件
+                    if (more.id == 6) {
+                      this.isMusicMemoryPlay = checked;
+                      PreferencesUtil.put(SettingPage.iS_MUSIC_MEMORY_PLAY, this.isMusicMemoryPlay)
+                      if (this.isMusicMemoryPlay) {
+                        ToastUtil.showToast('记忆播放已开启')
+                      } else {
+                        ToastUtil.showToast('记忆播放已关闭')
+                      }
                     }
-                  }
 
-                })
-                .width(48)
-                .height(24);
-              Toggle({ type: ToggleType.Switch, isOn: this.isMusicBGCover })
-                .selectedColor($r('app.color.title_bar_bg'))
-                .switchPointColor(Color.White)
-                .margin({ right: 15 })
-                .visibility(more.id == 7 ? Visibility.Visible : Visibility.None)
-                .onChange((checked: boolean) => { // 选择开关状态变化时触发事件
-                  if (more.id == 7) {
-                    this.isMusicBGCover = checked;
-
-                    PreferencesUtil.put(SettingPage.iS_MUSIC_BG_COVER, this.isMusicBGCover)
-                    if (this.isMusicBGCover) {
-                      ToastUtil.showToast('播放背景随音乐封面已开启')
-                    } else {
-                      ToastUtil.showToast('播放背景随音乐封面已关闭')
+                  })
+                  .width(48)
+                  .height(24);
+                Toggle({ type: ToggleType.Switch, isOn: this.isMusicBGCover })
+                  .selectedColor($r('app.color.title_bar_bg'))
+                  .switchPointColor(Color.White)
+                  .margin({ right: 15 })
+                  .visibility(more.id == 7 ? Visibility.Visible : Visibility.None)
+                  .onChange((checked: boolean) => { // 选择开关状态变化时触发事件
+                    if (more.id == 7) {
+                      this.isMusicBGCover = checked;
+
+                      PreferencesUtil.put(SettingPage.iS_MUSIC_BG_COVER, this.isMusicBGCover)
+                      if (this.isMusicBGCover) {
+                        ToastUtil.showToast('播放背景随音乐封面已开启')
+                      } else {
+                        ToastUtil.showToast('播放背景随音乐封面已关闭')
+                      }
                     }
-                  }
 
-                })
-                .width(48)
-                .height(24);
-              Toggle({ type: ToggleType.Switch, isOn: this.isSavePlayMode })
-                .selectedColor($r('app.color.title_bar_bg'))
-                .switchPointColor(Color.White)
-                .margin({ right: 15 })
-                .visibility(more.id == 8 ? Visibility.Visible : Visibility.None)
-                .onChange((checked: boolean) => { // 选择开关状态变化时触发事件
-                  if (more.id == 8) {
-                    this.isSavePlayMode = checked;
-                    PreferencesUtil.put(SettingPage.iS_SAVE_PLAY_MODE, this.isSavePlayMode)
-                    if (this.isSavePlayMode) {
-                      ToastUtil.showToast('保存播放模式已开启')
-                    } else {
-                      ToastUtil.showToast('保存播放模式已关闭')
+                  })
+                  .width(48)
+                  .height(24);
+                Toggle({ type: ToggleType.Switch, isOn: this.isSavePlayMode })
+                  .selectedColor($r('app.color.title_bar_bg'))
+                  .switchPointColor(Color.White)
+                  .margin({ right: 15 })
+                  .visibility(more.id == 8 ? Visibility.Visible : Visibility.None)
+                  .onChange((checked: boolean) => { // 选择开关状态变化时触发事件
+                    if (more.id == 8) {
+                      this.isSavePlayMode = checked;
+                      PreferencesUtil.put(SettingPage.iS_SAVE_PLAY_MODE, this.isSavePlayMode)
+                      if (this.isSavePlayMode) {
+                        ToastUtil.showToast('保存播放模式已开启')
+                      } else {
+                        ToastUtil.showToast('保存播放模式已关闭')
+                      }
                     }
-                  }
 
-                })
-                .width(48)
-                .height(24);
-
-              Toggle({ type: ToggleType.Switch, isOn: this.isCoverRectangle })
-                .selectedColor($r('app.color.title_bar_bg'))
-                .switchPointColor(Color.White)
-                .margin({ right: 15 })
-                .visibility(more.id == 13 ? Visibility.Visible : Visibility.None)
-                .onChange((checked: boolean) => { // 选择开关状态变化时触发事件
-                  if (more.id == 13) {
-                    this.isCoverRectangle = checked;
-                    PreferencesUtil.put(SettingPage.IS_COVER_RECTANGLE, this.isCoverRectangle)
-                    if (this.isCoverRectangle) {
-                      ToastUtil.showToast('封面方形已开启')
-                      this.animationRoFun()
-                    } else {
-                      ToastUtil.showToast('封面圆形已开启')
-                      this.animationRoFun()
+                  })
+                  .width(48)
+                  .height(24);
+
+                Toggle({ type: ToggleType.Switch, isOn: this.isCoverRectangle })
+                  .selectedColor($r('app.color.title_bar_bg'))
+                  .switchPointColor(Color.White)
+                  .margin({ right: 15 })
+                  .visibility(more.id == 13 ? Visibility.Visible : Visibility.None)
+                  .onChange((checked: boolean) => { // 选择开关状态变化时触发事件
+                    if (more.id == 13) {
+                      this.isCoverRectangle = checked;
+                      PreferencesUtil.put(SettingPage.IS_COVER_RECTANGLE, this.isCoverRectangle)
+                      if (this.isCoverRectangle) {
+                        ToastUtil.showToast('封面方形已开启')
+                        this.animationRoFun()
+                      } else {
+                        ToastUtil.showToast('封面圆形已开启')
+                        this.animationRoFun()
+                      }
                     }
-                  }
 
-                })
-                .width(48)
-                .height(24);
+                  })
+                  .width(48)
+                  .height(24);
 
-            }
+              }
 
 
+            }
+            .width('100%')
+            .height(45)
+            .padding(15)
+            .backgroundColor(Color.Transparent)
+            .borderRadius(12)
+            .margin({ bottom: 6 })
           }
-          .width('100%')
-          .height(45)
-          .padding(15)
-          .backgroundColor(Color.Transparent) // 选中背景高亮
-          .borderRadius(12)
-          .margin({ bottom: 6 })
+          .backgroundColor(Color.Transparent)
 
         });
       }
@@ -8278,9 +8380,18 @@ export struct LocalMusic {
 
         // 随机选择一个未播放的歌曲索引
         let newIndex: number;
+        // 添加超时机制防止无限循环
+        let attempt = 0;
+        const maxAttempts = 100; // 根据需求调整
         do {
-          newIndex = RandomUtil.getRandomNumber(0, this.songList.length - 1);
-        } while (this.playedIndices.has(newIndex));
+          newIndex = RandomUtil.getRandomNumber(0,  this.songList.length  - 1);
+          attempt++;
+        } while (this.playedIndices.has(newIndex)  && attempt < maxAttempts);
+
+        if (attempt >= maxAttempts) {
+          // 处理无法找到新索引的情况(如随机选择或按顺序播放)
+          newIndex = Math.floor(Math.random()  * this.songList.length);
+        }
 
         this.curIndex = newIndex;
         this.playedIndices.add(newIndex);

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

@@ -37,6 +37,15 @@ export class VideoItem  {
   fileName?: string;//音乐文件的真实文件名称
   lastPlayed?:Date;
 
+  duration?:string//时长
+  mimeType?:string//类型
+  sampleRate?:string//音频的采样率单位为Hz
+  trackCount?:string//轨道数量
+  lastPlayedStr?:string;//最后播放时间
+  playCount?:number//播放次数
+  lyricContent?: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) {
@@ -60,7 +69,7 @@ export class VideoItem  {
     this.album = album;
     this.fileName = fileName;
     this.lastPlayed = lastPlayed;
-
+    this.playCount = 0
 
   }
 }

+ 4 - 2
lib/src/main/ets/view/LyricView2.ets

@@ -264,13 +264,14 @@ export struct LyricView2 {
             }
         })
     }
-
+    // 普通歌词渲染(原有逻辑)
     @Builder
     NormalLyricLine(item: LyricLine, index: number) {
         Text(item.text)
             .fontSize(this.textSize)
             .opacity(this.calculateOpacityFactor(index, this.currentIndex))
             .blur(this.calculateBlurFactor(index, this.currentIndex))
+            .copyOption(CopyOptions.InApp)
             .textAlign(this.alignMode == 'center' ? TextAlign.Center : TextAlign.Start)
             .scale({
                 x: index == this.currentIndex ? this.controller.getHighlightScale() : 1,
@@ -282,7 +283,7 @@ export struct LyricView2 {
             .animation({ duration: this.animDuration, curve: Curve.FastOutSlowIn })
             .width(this.alignMode == 'center' ? '100%' : '76%')
     }
-
+    // 逐字歌词渲染
     @Builder
     WordByWordLyric(item: LyricLine, index: number) {
         Row({ space: 0 }) {
@@ -298,6 +299,7 @@ export struct LyricView2 {
                     .margin(0)
                     .opacity(this.calculateOpacityFactor(index, this.currentIndex))
                     .blur(this.calculateBlurFactor(index, this.currentIndex))
+                    .copyOption(CopyOptions.InApp)
                     .animation({
                         // 动画播放速度
                         tempo: 0.8,