| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318 |
- import TitleBar from '../view/TitleBar'
- import { router } from '@kit.ArkUI'
- import { FileUtil, LogUtil, PreferencesUtil, ToastUtil } from '@pura/harmony-utils'
- import lottie from '@ohos/lottie'
- import { AnimationItem } from '@ohos/lottie'
- import { MessageEvents, taskpool, worker } from '@kit.ArkTS'
- import { fileUri, picker } from '@kit.CoreFileKit'
- import { LocalMusic } from '../view/LocalMusic'
- import { Utility } from '../common/util/Utility'
- import MediaTable from '../common/util/MediaTable'
- import { VideoItem } from '../viewmodel/VideoItem'
- import Logger from '../common/util/Logger'
- import { CommonConstants } from '../common/constants/CommonConstants'
- import { emitter } from '@kit.BasicServicesKit'
- @Preview
- @Entry
- @Component
- export struct ScanFilePage{
- @State rootPath:string = '' //音频根目录
- @State lockPath:string = ''
- @State strText:string = ''
- @State isStart:boolean = false
- @State appName:string = ''
- //lottie动画构建渲染上下文
- private mainRenderingSettings: RenderingContextSettings = new RenderingContextSettings(true)
- private path:string = "common/lottie/leida.json"
- private successpath:string = "common/lottie/success2.json"
- private mainCanvasRenderingContext: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.mainRenderingSettings)
- private animateItem: AnimationItem | null = null;
- initLottie(lpath:string,isLoop:boolean){
- lottie.destroy(); //加载动画前先销毁之前加载的动画
- this.animateItem = lottie.loadAnimation({
- container: this.mainCanvasRenderingContext, // 渲染上下文
- renderer: 'canvas', // 渲染方式
- loop: isLoop, // 是否循环播放,默认true
- autoplay: true, // 是否自动播放,默认true
- name: '2024', // 动画名称
- contentMode: 'Contain', // 填充的模式
- frameRate: 30, //设置animator的刷帧率为30
- imagePath: 'lottie/images/', // 加载读取指定路径下的图片资源
- path: lpath, // json路径
- // initialSegment: [0,70]
- })
- lottie.setSpeed(0.7)
- }
- // 组件生命周期
- async aboutToAppear() {
- Utility.getAppName(getContext(this)).then((appName:string)=>{
- this.appName = appName
- })
- const documentViewPicker = new picker.DocumentViewPicker()
- let documentSaveResult = await documentViewPicker.save({ pickerMode: picker.DocumentPickerMode.DOWNLOAD })
- this.rootPath = new fileUri.FileUri(documentSaveResult[0]).path
- this.lockPath = this.rootPath +'/'+ LocalMusic.STR_LOCK_VIDEO
- LogUtil.info('onecold 文件扫描 aboutToAppear')
- }
- endScan(){
- const eventData: emitter.EventData = {};
- emitter.emit({ eventId: 101 }, eventData); // 发送视频打开广播事件
- ToastUtil.showToast('扫描文件入库成功!')
- this.isStart = false
- this.strText = ''
- //结束动画
- lottie.pause()
- lottie.stop()
- this.initLottie(this.successpath,false)
- lottie.play()
- }
- // 组件生命周期
- aboutToDisappear() {
- lottie.destroy();
- }
- @State titleBarModel: TitleBar.Model = new TitleBar.Model()
- .setTitleTextStyle(FontStyle.Normal)
- .setTitleBarStyle(TitleBar.BarStyle.TRANSPARENT)
- .setLeftIcon($r('app.media.left_back_white'))
- .setTitleName("文件扫描")
- .setTitleFontColor(Color.White)
- .setTitleBarBackground($r('app.color.title_bar_bg'))
- .setLeftTitleBackground($r('app.color.title_bar_bg'))
- .setTitleBarBottomLineColor($r('app.color.title_bar_bg'))
- .setOnLeftClickListener(() => {
- router.back()
- })
- initState(){
- this.initLottie(this.path,true)
- this.isStart = true
- this.strText = Utility.resourceToString(getContext(this),$r('app.string.scaning'))
- lottie.play()
- }
- doOptimize(){
- this.initState()
- const task = new taskpool.Task(scanDirectoryTask, getContext(this), this.rootPath,
- this.lockPath,PreferencesUtil.getStringSync('COVER_API',''));
- taskpool.execute(task, taskpool.Priority.HIGH).then(()=>{
- this.endScan()
- }).catch((e:object)=>{
- console.info("task1 catch e: " + e);
- })
- }
- build() {
- Column() {
- TitleBar({ model: $titleBarModel })
- Scroll(){
- Column() {
- Stack(){
- Image($r('app.media.file_search'))
- .width(80)
- .height(80)
- .alignSelf(ItemAlign.Center)
- //lottie动画
- Canvas(this.mainCanvasRenderingContext)
- .width(160)
- .height(160)
- .onReady(()=>{
- //抗锯齿的设置
- this.mainCanvasRenderingContext.imageSmoothingEnabled = true;
- this.mainCanvasRenderingContext.imageSmoothingQuality = 'medium'
- })
- }
- Text(this.strText)
- .margin({ right: 20,top:20,bottom:20 })
- .fontSize(16)
- .fontColor(Color.Black)
- .fontWeight(480)
- Column() {
- Row() {
- Image($r('app.media.selected'))
- .width(16)
- .height(16)
- .margin({ left:10})
- .alignSelf(ItemAlign.Center)
- Text(Utility.resourceToString(getContext(this),$r('app.string.file_scan_tip_one'))
- +`${this.appName} `+
- Utility.resourceToString(getContext(this),$r('app.string.file_scan_tip_one_1')))
- .margin({ left: 10, right: 20 })
- .fontSize(11)
- .fontColor(Color.Gray)
- .fontWeight(480)
- .layoutWeight(1)
- }
- .width('100%')
- .margin({ left:25,right: 10 ,top:20 })
- Row() {
- Image($r('app.media.selected'))
- .width(16)
- .height(16)
- .margin({ left:10})
- .alignSelf(ItemAlign.Center)
- Text($r('app.string.file_scan_tip_two'))
- .margin({ left: 10, right: 20 })
- .fontSize(11)
- .fontColor(Color.Gray)
- .fontWeight(480)
- .layoutWeight(1)
- }
- .width('100%')
- .margin({ left:25,right: 10 ,top:20 })
- Column() {
- Button($r('app.string.start_scan'), { type: ButtonType.Capsule, stateEffect: false })
- .width('80%')
- .height(55)
- .margin({ top: 50, bottom: 20 })
- .linearGradient({
- direction: GradientDirection.Right,
- colors: [['#ff37a0fc', 0.0], ['#67e667', 0.5], ['#f5856e', 1.0]]
- })
- .visibility(this.isStart ? Visibility.Hidden : Visibility.Visible)
- .onClick(() => {
- this.doOptimize()
- })
- .alignSelf(ItemAlign.Center)
- }
- }
- }
- .height('100%')
- .width('100%')
- .align(Alignment.Top)
- }
- .height(1000)
- }
- }
- }
- // async function scanDirectoryTask(context: Context, curPath: string, lockPath: string) {
- // const table: MediaTable = new MediaTable(context);
- //
- //
- // try {
- // // 使用 Promise 包装数据库操作
- // await new Promise<void>((resolve, reject) => {
- // table.getRdbStore(context, async (err:Error) => {
- // if (err) {
- // reject(err);
- // return;
- // }
- //
- // const files = FileUtil.listFileSync(curPath);
- // const pendingTasks: Promise<void>[] = [];
- //
- // for (const file of files) {
- // const fPath = `${curPath}/${file}`;
- // if (fPath === lockPath) continue;
- //
- // if (FileUtil.isDirectory(fPath)) {
- // // 用立即执行函数处理异步递归
- // pendingTasks.push((async () => {
- // await scanDirectoryTask(context, fPath, lockPath);
- // })());
- // } else {
- // if(!fPath.endsWith('.lrc')&&Utility.isMeidaByExtension(fPath)&&!fPath.endsWith('.srt')){
- // // 用 Promise 包装媒体处理逻辑
- // pendingTasks.push((async () => {
- // let mediaItem:VideoItem = await Utility.uriGetMusicAssetsFromFile(context, fPath, CommonConstants.TYPE_LOCAL, true);
- // ;
- // await new Promise<void>((resolve: (value: void) => void) => {
- // table.insert(mediaItem, (id: number) => {
- // resolve(); // 明确调用 resolve 且无返回值
- // });
- // });
- // })());
- // }
- // }
- // }
- //
- // // 关键点:等待所有异步操作完成
- // await Promise.all(pendingTasks);
- // resolve();
- // });
- // });
- //
- // // Logger.info('onecold scanDirectory 全部扫描完成后执行 = ')
- //
- // } catch (err) {
- // Logger.error(`Scan failed: ${err.code} - ${err.message}`);
- // }
- //
- //
- // }
- @Concurrent
- async function scanDirectoryTask(context: Context, dirPath: string, lockPath: string,cover_api:string) {
- const stack: string[] = [dirPath];
- const table: MediaTable = new MediaTable(context);
- while (stack.length > 0) {
- const currentPath = stack.pop()!;
- const files = FileUtil.listFileSync(currentPath);
- await Promise.all(files.map(async (file) => {
- const fPath = `${currentPath}/${file}`;
- if (fPath === lockPath) return;
- if (FileUtil.isDirectory(fPath)) {
- stack.push(fPath); // 使用栈结构代替递归
- } else {
- if (fPath.endsWith('.lrc') || fPath.endsWith('.srt')) return;
- if (Utility.isMeidaByExtension(fPath)) {
- const mediaItem = await Utility.uriGetMusicAssetsFromFile(
- context, fPath, CommonConstants.TYPE_LOCAL, true
- );
- table.insert(mediaItem, (id: number) => {
- },cover_api);
- }
- }
- }));
- }
- }
|