Explorar el Código

不需要复制到DownLoad目录也可以播放的工具类导入

onecold hace 9 meses
padre
commit
c99dc39a2d

+ 75 - 0
entry/src/main/ets/common/util/PermissionUtil.ets

@@ -0,0 +1,75 @@
+import { fileShare, fileIo as fs, fileUri } from '@kit.CoreFileKit';
+import { FileUtil } from '@pura/harmony-utils';
+
+
+//权限类
+class PermissionUtil {
+  //激活权限
+  async activatePermission(uri: string | undefined): Promise<boolean> {
+    if (!uri) {
+      return false
+    }
+    try {
+      let fd = fs.openSync(uri);
+      fs.closeSync(fd);
+      console.log("onecold activatePermission 无需激活权限");
+      return true
+    } catch {
+      try {
+        if (canIUse('SystemCapability.FileManagement.AppFileService.FolderAuthorization')) {
+          uri = FileUtil.getUriFromPath(uri)
+          console.log('onecold 激活权限 activatePermission uri = '+uri);
+          let policyInfo: fileShare.PolicyInfo = {
+            uri: uri,
+            operationMode: fileShare.OperationMode.READ_MODE | fileShare.OperationMode.WRITE_MODE,
+          };
+          let policies: Array<fileShare.PolicyInfo> = [policyInfo];
+          let results = await fileShare.checkPersistentPermission(policies);
+          for (let i = 0; i < results.length; i++) {
+            console.log('onecold activatePermission 激活权限成功');
+            if (results[i]) {
+              let info: fileShare.PolicyInfo = {
+                uri: policies[i].uri,
+                operationMode: policies[i].operationMode,
+              };
+              let policy: Array<fileShare.PolicyInfo> = [info];
+              await fileShare.activatePermission(policy);
+            }
+          }
+          let fd = fs.openSync(uri);
+          fs.closeSync(fd);
+        }
+        return true
+      } catch (error) {
+        console.error('onecold activatePermission error = '+JSON.stringify(error));
+        if (error.code == 13900001 ) {
+          await this.persistPermission(uri)
+
+        }
+        return false
+      }
+    }
+  }
+
+  //持久化权限
+  async persistPermission(uri: string): Promise<boolean> {
+    try {
+      if (canIUse('SystemCapability.FileManagement.AppFileService.FolderAuthorization')) {
+        let policyInfo: fileShare.PolicyInfo = {
+          uri: uri,
+          operationMode: fileShare.OperationMode.READ_MODE | fileShare.OperationMode.WRITE_MODE,
+        };
+        let policies: Array<fileShare.PolicyInfo> = [policyInfo];
+        fileShare.persistPermission(policies).then(() => {
+        })
+        let fd = await fs.open(uri);
+        await fs.close(fd);
+      }
+    } catch (error) {
+      return true
+    }
+    return false
+  }
+}
+
+export default new PermissionUtil();

+ 52 - 0
entry/src/main/ets/common/util/ReqPermissionUtil.ets

@@ -0,0 +1,52 @@
+import { abilityAccessCtrl, common, Permissions } from '@kit.AbilityKit';
+import { fileShare, fileIo as fs, fileUri } from '@kit.CoreFileKit';
+import { hilog } from '@kit.PerformanceAnalysisKit';
+import { BusinessError } from '@kit.BasicServicesKit';
+
+// 重新设置权限类,用于每次启动重新设置权限
+class ReqPermission {
+  public permissions: Permissions[] = ['ohos.permission.FILE_ACCESS_PERSIST'];
+
+  // 重新申请权限
+  reqPermissionsFromUser(permissions: Permissions[], context: common.UIAbilityContext): void {
+    let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
+    atManager.requestPermissionsFromUser(context, permissions).then((data) => {
+      let grantStatus: number[] = data.authResults;
+      let length: number = grantStatus.length;
+      for (let i = 0; i < length; i++) {
+        if (grantStatus[i] === 0) {
+        } else {
+          return;
+        }
+      }
+    })
+  }
+  //持久化权限
+  async persistPermission(uri: string): Promise<boolean> {
+    try {
+      if (canIUse('SystemCapability.FileManagement.AppFileService.FolderAuthorization')) {
+        if(uri.startsWith('file://media/Photo')){
+          uri = new fileUri.FileUri(uri).path
+        }
+        console.info('onecold 持久化权限persistPermission uri : ', uri);
+        let policyInfo: fileShare.PolicyInfo = {
+          uri: uri,
+          operationMode: fileShare.OperationMode.READ_MODE | fileShare.OperationMode.WRITE_MODE,
+        };
+        let policies: Array<fileShare.PolicyInfo> = [policyInfo];
+        fileShare.persistPermission(policies).then(() => {
+          console.log("onecold 持久化权限persistPermission success");
+        }).catch((err: BusinessError<Array<fileShare.PolicyErrorResult>>) => {
+          console.log("onecold persistPermission failed   err.message=" + JSON.stringify(err));
+        });
+        let fd = await fs.open(uri);
+        await fs.close(fd);
+      }
+    } catch (error) {
+      return true
+    }
+    return false
+  }
+}
+
+export default new ReqPermission()

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

@@ -24,6 +24,7 @@ import { pinyin4js } from '@ohos/pinyin4js';
 import { VipData } from '../../viewmodel/VipData';
 import { VipPage } from '../../pages/VipPage';
 import { FFmpeg, FFProgressMessageParser } from '@sj/ffmpeg';
+import ReqPermissionUtil from './ReqPermissionUtil';
 
 
 export interface FFMpegTags {
@@ -649,6 +650,7 @@ export class Utility {
 
   //获取音乐资源的属性值,
   static async uriGetMusicAssetsFromFile(context:Context,uri:string,type:number,autoParseMusicName?:boolean): Promise<VideoItem> {
+    await ReqPermissionUtil.persistPermission(uri);
     if(StrUtil.isNotEmpty(uri)&&uri.toLowerCase().endsWith('.cue')){
       return  new VideoItem(FileUtil.getFileName(uri),uri,uri,type,0,'')
     }
@@ -832,6 +834,7 @@ export class Utility {
 
   static async  readMetaInfoFFmpeg(context:Context,inputPath: string,type:number,autoParseMusicName?:boolean): Promise<VideoItem> {
     return new Promise((resolve, reject) => {
+      inputPath = FileUtil.getFilePath(inputPath)
       let commands = ["ffprobe", "-v", "quiet", "-print_format", "json", "-show_format", "-show_streams", inputPath];
       let outputJson = "";
 
@@ -1907,6 +1910,7 @@ async function extractLyricsContent(inputPath: string): Promise<string> {
  */
 async function parseAudioMetadata(inputPath: string): Promise<VideoItem> {
   return new Promise(async (resolve, reject) => {
+    inputPath = FileUtil.getFilePath(inputPath)
     try {
       // 1. 执行FFprobe命令
       const commands: string[] = [

+ 2 - 0
entry/src/main/ets/pages/NewIndex.ets

@@ -48,6 +48,7 @@ import { WebDavMainPage } from './WebDavMainPage';
 import { WebDavAccount } from '../viewmodel/WebDavAccount';
 import { WebdavManager } from '../common/util/WebdavManager';
 import { WebDavAccountDialog } from '../dialog/WebDavAccountDialog';
+import ReqPermissionUtil from '../common/util/ReqPermissionUtil';
 
 // import { FFmpeg, FFProgressMessageParser } from '@sj/ffmpeg';
 
@@ -245,6 +246,7 @@ struct NewIndex {
    */
 
   async aboutToAppear() {
+    ReqPermissionUtil.reqPermissionsFromUser(ReqPermissionUtil.permissions, this.context);
     this.isShowTitleBar = PreferencesUtil.getBooleanSync(SettingPage.IS_SHOW_TITLTBAR, true)
     this.idDefaultMediaKu = PreferencesUtil.getBooleanSync('idDefaultMediaKu', false)
     if(this.idDefaultMediaKu){

+ 72 - 2
entry/src/main/ets/view/LocalMusic.ets

@@ -174,6 +174,7 @@ const ITEM_HEIGHT_BIG: number = 78; // 列表项大高度
 @Preview
 @Component
 export struct LocalMusic {
+  @State isCopyFileToDownLoad: boolean = false
   @State offHeight: number = 75
   @State currentSongList: Array<VideoItem> = []//当前歌单
   @Consume currentSongListName:string //当前歌单名称
@@ -874,6 +875,7 @@ export struct LocalMusic {
     this.isLongNameRoLL = PreferencesUtil.getBooleanSync('isLongNameRoLL', true)
     this.fastForwardSeconds  = PreferencesUtil.getStringSync('fastForwardSeconds', '10')
     this.isShowBackFast  = PreferencesUtil.getBooleanSync('isShowBackFast', false)
+    this.isCopyFileToDownLoad = PreferencesUtil.getBooleanSync(SettingPage.IS_COPYFILE_TO_DOWNLOAD, false)
     if(this.volumeSmall){
       this.volume = 0.5
     }else{
@@ -1816,8 +1818,76 @@ export struct LocalMusic {
   }
 
   @State progress: number = 0;
+  async saveVideoDatas(uris:string[],isOpen?:boolean){
+    if (ArrayUtil.isEmpty(uris))  {
+      return;
+    }
+
+    console.info('onecold this.isCopyFileToDownLoad = ' + this.isCopyFileToDownLoad);
+    if(this.isCopyFileToDownLoad||this.currentPath==this.lockPath){
+      this.saveVideoDatasToDownLoad(uris,isOpen)
+      return
+    }
+
+
+    // 初始化进度条
+    this.progress  = 0;
+    DialogHelper.showLoadingProgress({
+      progress: this.progress,
+      backCancel: false,
+      autoCancel: false,
+      loadColor: $r('app.color.title_bar_bg'),
+      fontColor: $r('app.color.title_bar_bg')
+    });
+
+    // 计算处理总数用于进度计算
+    const totalItems = uris.length;
+    let processedItems = 0;
+
+    for (let i = 0; i < uris.length;  i++) {
+      let filePath = uris[i];
+      try {
+        if (this.currentPath  !== this.lockPath)  { // 判断不是私密音乐,才入库
+          if (!filePath.endsWith('.lrc')  && Utility.isMeidaByExtension(filePath)  && !filePath.endsWith('.srt'))  {
+            let mediaItem: VideoItem = await Utility.uriGetMusicAssetsFromFile(this.context,
+              filePath, CommonConstants.TYPE_LOCAL, this.autoParseMusicName);
+            console.info('onecold  saveVideoDatas filePath = ' + filePath)
+            if (!filePath.includes(this.rootPath))  {
+              console.info('onecold  saveVideoDatas mediaItem.parentPath111  = ' + mediaItem.parentPath)
+              mediaItem.parentPath  = this.currentPath;
+            }
+            console.info('onecold  saveVideoDatas mediaItem.parentPath  = ' + mediaItem.parentPath)
+            this.table.insert(mediaItem,  (id: number) => {
+              // 插入完成回调
+            });
+          }
+        }
+
+        // 更新进度
+        processedItems++;
+        this.progress  = Math.floor((processedItems  / totalItems) * 100);
+        DialogHelper.updateLoading(' 正在处理', this.progress);
+
+      } catch (error) {
+        Logger.error(TAG,  'saveVideoDatas failed with err: ' + JSON.stringify(error));
+        // 即使出错也更新进度
+        processedItems++;
+        this.progress  = Math.floor((processedItems  / totalItems) * 100);
+        DialogHelper.updateLoading(' 正在处理', this.progress);
+      }
+    }
+    // 关闭进度条
+    DialogHelper.closeLoading();
+    this.isZero = false
+    // 删除目标路径缓存
+    setTimeout(() => {
+      this.cache.delete(this.currentPath);
+      this.getSortedFiles(this.currentPath,false,uris[0],isOpen)
+      this.setButtonStatus()
+    }, 500);
 
-  async saveVideoDatas(uris: string[], isOpen?: boolean) {
+  }
+  async saveVideoDatasToDownLoad(uris: string[], isOpen?: boolean) {
     if (ArrayUtil.isEmpty(uris)) {
       return;
     }
@@ -9457,7 +9527,7 @@ export struct LocalMusic {
         .width('99%')
         .textAlign(TextAlign.Center)
         .fontColor(Color.White)
-      Text(this.artist + '  ' + this.currentSong?.album)
+      Text(this.artist + '  ' + this.currentSong?.album||'')
         .fontSize(this.isCoverOpacity() ? 12 : 15)
         .textOverflow({ overflow: TextOverflow.MARQUEE })//超长滚动
         .fontColor(Color.White)