Преглед на файлове

实现播放页的快进快退,可在设置开关,自定义快进快退时间

onecold преди 10 месеца
родител
ревизия
22bd5cca8f

+ 4 - 0
entry/src/main/ets/pages/FastForwardSecondInterface.ets

@@ -0,0 +1,4 @@
+export interface FastForwardSecondInterface {
+  label: string;
+  value: string;
+}

+ 35 - 0
entry/src/main/ets/pages/SelectItem.ets

@@ -0,0 +1,35 @@
+
+@Component
+export struct SelectItem {
+  @Prop selected: number = 0
+  @State list: string[] = []
+  @State private select: SelectOption[] = []
+  onChange = (_index: number) => {
+  }
+
+  aboutToAppear(): void {
+    for (let text of this.list) {
+      this.select.push({ value: text })
+    }
+  }
+
+  build() {
+
+
+      Select(this.select)
+        .selected(this.selected)
+        .value(this.list[this.selected])
+        .selectedOptionFont({ weight: FontWeight.Medium })
+        .selectedOptionFontColor($r('app.color.main_color'))
+        .font({ size: 15, weight: FontWeight.Medium })
+        .fontColor(Color.Gray)
+        .margin({ right: 18 })
+        .selectedOptionBgColor($r('sys.color.button_background_color_transparent'))
+        .onSelect((index: number) => {
+          this.selected = index
+          this.onChange(index)
+        })
+        .divider(null)
+
+  }
+}

+ 84 - 1
entry/src/main/ets/pages/SettingPage.ets

@@ -14,11 +14,15 @@ import { HSBColorPicker } from '@keke/color-picker'
 import { DialogHelper } from '@pura/harmony-dialog'
 import { bundleManager } from '@kit.AbilityKit'
 import { hilog } from '@kit.PerformanceAnalysisKit'
+import { SelectItem } from './SelectItem'
+import { FastForwardSecondInterface } from './FastForwardSecondInterface'
 
 @Preview
 // @Entry
 @Component
 export struct SettingPage {
+  @State fastForwardSeconds: string = '10'
+  @State isShowBackFast: boolean = true//快进快退按钮
   @Consume isShowDrawer: boolean;
   @Consume offsetX: number;
   @Consume mType: number;
@@ -59,6 +63,15 @@ export struct SettingPage {
   public static OPEN_SKIPSONG_ANIMATE: string = 'openSkipSongAnimate';
   @State autoParseMusicName: boolean = false
   @State idDefaultMediaKu: boolean = false
+  private fastForwardSecond: FastForwardSecondInterface[] = [
+    { label: '5秒', value: '5' },
+    { label: '10秒', value: '10' },
+    { label: '15秒', value: '15' },
+    { label: '20秒', value: '20' },
+    { label: '30秒', value: '30' },
+    { label: '60秒', value: '60' },
+    { label: '90秒', value: '90' },
+  ];
   public static THEME_COLOR_LIST: Array<ThemeColorItem> = [
     { name: '玫瑰粉', color: '#FF4081', isVip: false },
     { name: '经典蓝', color: '#0A59F7', isVip: false },
@@ -246,7 +259,8 @@ export struct SettingPage {
     this.idDefaultMediaKu = PreferencesUtil.getBooleanSync('idDefaultMediaKu', false)
     this.isShowFileName = PreferencesUtil.getBooleanSync('isShowFileName', false)
     this.isLongNameRoLL = PreferencesUtil.getBooleanSync('isLongNameRoLL', true)
-
+    this.isShowBackFast  = PreferencesUtil.getBooleanSync('isShowBackFast', false)
+    this.fastForwardSeconds  = PreferencesUtil.getStringSync('fastForwardSeconds', '10')
     // 只用 themeMode 控制主题
     this.themeMode = PreferencesUtil.getNumberSync(SettingPage.THEME_MODE, 0)
     this.applyThemeMode(this.themeMode)
@@ -1134,6 +1148,75 @@ export struct SettingPage {
 
             Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
 
+
+            //显示快进快退
+            Row() {
+              SymbolGlyph($r('sys.symbol.hand_point_up_tap'))
+                .fontSize(20)
+                .fontColor([this.themeColor])
+                .alignSelf(ItemAlign.Center)
+                .margin({ left: 15 })
+              Text('显示快进快退')
+                .margin({ left: 8 })
+                .fontSize(15)
+                .fontColor(Color.Gray)
+                .fontWeight(480)
+                .layoutWeight(1)
+              Toggle({ type: ToggleType.Switch, isOn: this.isShowBackFast })
+                .selectedColor(this.themeColor)
+                .switchPointColor(Color.White)
+                .margin({ right: 18 })
+                .onChange((checked: boolean) => {
+                  this.isShowBackFast = checked;
+                  PreferencesUtil.put('isShowBackFast', this.isShowBackFast)
+                  this.sendChangeEvent()
+                })
+                .width(50)
+                .height(30);
+            }
+            .height(55)
+            .clickEffect({ level: ClickEffectLevel.HEAVY })
+            Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
+              .opacity(this.isShowBackFast ? 1 : 0)
+              .visibility(this.isShowBackFast ? Visibility.Visible : Visibility.None)
+              .animation({
+                duration: 500,
+                curve: 'ease-in-out' // 可选动画曲线
+              })
+            // 快进快退时长
+            Row() {
+              SymbolGlyph($r('sys.symbol.hand_tap_wave_2'))
+                .fontSize(20)
+                .fontColor([this.themeColor])
+                .alignSelf(ItemAlign.Center)
+                .margin({ left: 15 })
+              Text('快进快退时长')
+                .margin({ left: 8 })
+                .fontSize(15)
+                .fontColor(Color.Gray)
+                .fontWeight(480)
+                .layoutWeight(1)
+              SelectItem({
+                list: this.fastForwardSecond.map(opt => opt.label),
+                selected: this.fastForwardSecond.findIndex(opt => opt.value === this.fastForwardSeconds),
+                onChange: (index: number) => {
+                  this.fastForwardSeconds = this.fastForwardSecond[index].value;
+                  PreferencesUtil.put('fastForwardSeconds', this.fastForwardSeconds)
+                  this.sendChangeEvent()
+                }
+              })
+
+            }
+            .height(55)
+            .opacity(this.isShowBackFast ? 1 : 0)
+            .visibility(this.isShowBackFast ? Visibility.Visible : Visibility.None)
+            .animation({
+              duration: 500,
+              curve: 'ease-in-out' // 可选动画曲线
+            })
+            .clickEffect({ level: ClickEffectLevel.HEAVY })
+            Line().width('100%').height(0.3).backgroundColor($r('app.color.index_tab_unselected_font_color'))
+
             // 长按默认倍数
             Row() {
               SymbolGlyph($r('sys.symbol.timer'))

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

@@ -272,7 +272,7 @@ export struct FixMessyView {
       this.onFixResult(false)
       console.error(`批量嵌入过程出错: ${JSON.stringify(error)}`);
     } finally {
-      ToastUtil.showToast(`嵌入完成: 成功 ${this.embedSuccessCount}, 失败 ${this.embedFailedCount}`)
+      ToastUtil.showToast(`修复完成: 成功 ${this.embedSuccessCount}, 失败 ${this.embedFailedCount}`)
       this.isEmbedding = false;
       this.currentProgress = 0;
       this.totalFiles = this.selectedFiles.length;

+ 87 - 22
entry/src/main/ets/view/LocalMusic.ets

@@ -143,6 +143,8 @@ const ITEM_HEIGHT_BIG: number = 78; // 列表项大高度
 @Preview
 @Component
 export struct LocalMusic {
+  @State fastForwardSeconds: string = '10'
+  @State isShowBackFast: boolean = true//快进快退按钮
   @State isCanAuto:boolean = true
   @State opacityValueImage: number = 1;
   @State tipPopup:boolean = false
@@ -684,6 +686,8 @@ export struct LocalMusic {
     this.autoParseMusicName = PreferencesUtil.getBooleanSync('autoParseMusicName', true)
     this.isShowFileName = PreferencesUtil.getBooleanSync('isShowFileName', false)
     this.isLongNameRoLL = PreferencesUtil.getBooleanSync('isLongNameRoLL', true)
+    this.fastForwardSeconds  = PreferencesUtil.getStringSync('fastForwardSeconds', '10')
+    this.isShowBackFast  = PreferencesUtil.getBooleanSync('isShowBackFast', false)
     if(this.volumeSmall){
       this.volume = 0.5
     }else{
@@ -964,7 +968,7 @@ export struct LocalMusic {
       workerInstance.postMessage({ code: 2, data: this.context,data2:this.packName });
     }
     if (this.modeType !== 0) {
-
+        this.openMusic(isOpen, destPath)
       return
     }
     console.info('onecold getSortedFiles 2')
@@ -1088,25 +1092,8 @@ export struct LocalMusic {
       // }
 
       // this.setButtonStatus()
-      if (isOpen) {
-
-        if (destPath === undefined) {
-          // 处理 destPath 为 undefined 的情况
-          return
-        }
-        if (destPath.endsWith('.lrc')) {
-          ToastUtil.showToast('导入歌词成功!请注意歌词文件和歌曲要同个歌单路径。')
-          if (StrUtil.isNotEmpty(this.videoUrl)) {
-            let lyricPath = this.videoUrl.substring(0, this.videoUrl.lastIndexOf('.')) + '.lrc'
-            this.initLyric(lyricPath);
-          }
+      this.openMusic(isOpen, destPath)
 
-          return
-        }
-        let item2 = new VideoItem(Utility.getMediaNameByUri(destPath), destPath, destPath, 0, 0, '')
-        this.doPlay(item2)
-        this.isShowPlay = true
-      }
 
 
     });
@@ -1114,6 +1101,29 @@ export struct LocalMusic {
 
   }
 
+  //第三方app打开天天静听导入音乐后播放
+  openMusic(isOpen?: boolean, destPath?: string){
+    if (isOpen&&destPath) {
+
+      if (destPath === undefined) {
+        // 处理 destPath 为 undefined 的情况
+        return
+      }
+      if (destPath.endsWith('.lrc')) {
+        ToastUtil.showToast('导入歌词成功!请注意歌词文件和歌曲要同个歌单路径。')
+        if (StrUtil.isNotEmpty(this.videoUrl)) {
+          let lyricPath = this.videoUrl.substring(0, this.videoUrl.lastIndexOf('.')) + '.lrc'
+          this.initLyric(lyricPath);
+        }
+
+        return
+      }
+      let item2 = new VideoItem(Utility.getMediaNameByUri(destPath), destPath, destPath, 0, 0, '')
+      this.doPlay(item2,0,false,true)
+      this.isShowPlay = true
+    }
+  }
+
   //扫描文件夹入库
   async scanDirectory(curPath: string): Promise<VideoItem[]> {
     const files = FileUtil.listFileSync(curPath);
@@ -4855,7 +4865,7 @@ export struct LocalMusic {
     }
   }
 
-  private doPlay(item: VideoItem, index?: number, isFromSonPlayList?: boolean) {
+  private doPlay(item: VideoItem, index?: number, isFromSonPlayList?: boolean,isOpen?:boolean) {
     switch (item.type) {
       case CommonConstants.TYPE_IS_DIR:
         // 进入歌单前安全保存当前滚动偏移量,支持列表和网格
@@ -5055,11 +5065,14 @@ export struct LocalMusic {
           this.stop();
         }
 
-        if (isFromSonPlayList) { //点击来自右下角的播放列表
+        if (isFromSonPlayList||isOpen) { //点击来自右下角的播放列表
           this.currentSong = item
           if (index !== undefined) {
             this.curIndex = index
           }
+          this.songList = []
+          this.songList.push(item)
+          this.sonDataSource.pushArrayData(this.songList)
         } else {
           let globalVideoList = Utility.getGlobalList(this.videoLocalList, CommonConstants.TYPE_LOCAL) as VideoItem[];
           this.curIndex = Utility.getCurIndexFromGlobalList(globalVideoList, item.filePath)
@@ -8373,6 +8386,23 @@ export struct LocalMusic {
     Row() {
       Column(){
         Row(){
+          Stack(){
+            SymbolGlyph($r('sys.symbol.arrow_counterclockwise'))
+              .fontColor([Color.White])
+              .fontSize(21)
+              .effectStrategy(1)
+            Text(this.fastForwardSeconds)
+              .fontColor(Color.White)
+              .fontSize(10)
+              .fontWeight(FontWeight.Bold)
+
+          }
+          .margin({left:12,bottom:6})
+          .visibility(this.isShowBackFast?Visibility.Visible:Visibility.None)
+          .clickEffect({ level: ClickEffectLevel.MIDDLE,scale:0.6 })
+          .onClick(()=>{
+            this.backForward()
+          })
           Slider({
             value: this.progressValue,
             min: 0,
@@ -8403,9 +8433,25 @@ export struct LocalMusic {
               this.isSeekTo = false;
               // }
             })
+          Stack(){
+            SymbolGlyph($r('sys.symbol.arrow_clockwise'))
+              .fontColor([Color.White])
+              .fontSize(21)
+              .effectStrategy(1)
+            Text(this.fastForwardSeconds)
+              .fontColor(Color.White)
+              .fontSize(10)
+              .fontWeight(FontWeight.Bold)
 
+          }
+          .margin({right:10,bottom:6})
+          .visibility(this.isShowBackFast?Visibility.Visible:Visibility.None)
+          .clickEffect({ level: ClickEffectLevel.MIDDLE,scale:0.6 })
+          .onClick(()=>{
+            this.fastForward()
+          })
         }
-        .padding({ right: 7,left:20 })
+        .padding({ right: 7,left:22 })
         Row(){
           Text(this.currentTime)
             .fontSize(10)
@@ -12006,6 +12052,25 @@ export struct LocalMusic {
     ToastUtil.showToast('已添加至下一首播放')
   }
 
+  //后退10s,可再设置设置默认几秒
+  backForward() {
+    if(this.mIjkMediaPlayer){
+      let pos = this.mIjkMediaPlayer.getCurrentPosition();
+      let value = pos - Number(this.fastForwardSeconds) * 1000;
+      this.seekTo(value+"");
+    }
+
+  }
+
+  //快进10s,可再设置设置默认几秒
+  fastForward() {
+    if(this.mIjkMediaPlayer){
+      let pos = this.mIjkMediaPlayer.getCurrentPosition();
+      let value = pos + Number(this.fastForwardSeconds) * 1000;
+      this.seekTo(value+"");
+    }
+  }
+
   //下一个
   private playNext() {
     if (!this.debounce()) {

+ 4 - 0
entry/src/main/resources/base/element/color.json

@@ -187,6 +187,10 @@
     {
       "name": "start_window_background_blur",
       "value": "#ffffff"
+    },
+    {
+      "name": "main_color",
+      "value": "#103fb6"
     }
   ]
 }