1/* 2 * Copyright (c) 2023 Shenzhen Kaihong Digital Industry Development Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import common from '@ohos.app.ability.common'; 17import fs from '@ohos.file.fs'; // 实现应用文件访问能力 18import router from '@ohos.router'; 19import picker from '@ohos.file.picker'; 20import mediaLibrary from '@ohos.multimedia.mediaLibrary'; 21import { BusinessError } from '@ohos.base'; 22import MediaFileUri from '../media/MediaFileUri'; 23import Logger from '../common/Logger'; 24 25const TAG = 'ViewMedia'; 26 27interface myParams extends Object { 28 uris: string[] 29} 30 31@Entry 32@Component 33struct ViewMedia { 34 @State myContext: Context = getContext(this) as common.UIAbilityContext; 35 @State myFileSizes: number[] = []; 36 @State myFileNames: string[] = []; 37 @State myFileTypes: number[] = []; 38 @StorageLink('myFileName') myFileName: string = ''; 39 @StorageLink('myFileSize') myFileSize: number = 0; 40 @State myUris: string[] = (router.getParams() as myParams).uris; 41 @State uri: string = 'Hello World'; 42 @StorageLink('showPauses') showPauses: Array<number> = []; 43 mediaFileUri: MediaFileUri = new MediaFileUri(); 44 scroller: Scroller = new Scroller(); 45 currentUri: string = ''; 46 controllers: Array<VideoController> = []; 47 48 /** 49 * 拉起picker保存图片/视频 50 */ 51 async callFilePickerSaveImageVideo(): Promise<void> { 52 try { 53 let PhotoSaveOptions = new picker.PhotoSaveOptions(); 54 PhotoSaveOptions.newFileNames = ['PhotoViewPicker01.jpg', 'PhotoViewPicker01.mp4']; 55 let photoPicker = new picker.PhotoViewPicker(); 56 photoPicker.save(PhotoSaveOptions).then((PhotoSaveResult) => { 57 Logger.info(TAG, 'PhotoViewPicker.save successfully, PhotoSaveResult uri: ' + JSON.stringify(PhotoSaveResult)); 58 if (PhotoSaveResult !== null && PhotoSaveResult !== undefined) { 59 PhotoSaveResult.forEach((value: string) => { 60 this.uri = value; 61 Logger.info(TAG, `save image/video uri: ${this.uri}`); 62 }) 63 } 64 }).catch((err: BusinessError) => { 65 Logger.error(TAG, 'PhotoViewPicker.save failed with err: ' + JSON.stringify(err)); 66 }); 67 } catch (err) { 68 Logger.error(TAG, 'PhotoViewPicker failed with err: ' + err); 69 } 70 } 71 72 onPageShow() { 73 this.getImagesInfo(); 74 this.myFileName = this.myFileNames[0]; 75 this.myFileSize = this.myFileSizes[0]; 76 77 Logger.info(TAG, 'onPageShow getFilenameByUriForMedia this.myFileName ' + this.myFileName); 78 Logger.info(TAG, 'onPageShow getFilenameByUriForMedia begin' + this.myFileSize); 79 80 AppStorage.SetOrCreate('myFileName', this.myFileName); 81 AppStorage.SetOrCreate('myFileSize', this.myFileSize); 82 } 83 84 getMediaNameByUri(myUri: string, index: number) { 85 Logger.info(TAG, 'getMediaNameByUri getFilenameByUriForMedia begin'); 86 // 创建文件获取选项,此处参数为获取image类型的文件资源 87 let imagesFetchOp: mediaLibrary.MediaFetchOptions = { 88 selections: mediaLibrary.FileKey.MEDIA_TYPE + '= ? OR ' + mediaLibrary.FileKey.MEDIA_TYPE + '= ?', 89 selectionArgs: [mediaLibrary.MediaType.IMAGE.toString(), mediaLibrary.MediaType.VIDEO.toString()], 90 uri: myUri 91 }; 92 let media = mediaLibrary.getMediaLibrary(getContext(this)); 93 // 获取文件资源,使用callback方式返回异步结果 94 media.getFileAssets(imagesFetchOp, async (error, fetchFileResult) => { 95 // 判断获取的文件资源的检索结果集是否为undefined,若为undefined则接口调用失败 96 Logger.info(TAG, 'getFilenameByUriForMedia getMediaLibrary is ok'); 97 98 if (fetchFileResult === undefined) { 99 Logger.error(TAG, 'get fetchFileResult failed with error: ' + error); 100 return; 101 } 102 // 获取文件检索结果集中的总数 103 const count = fetchFileResult.getCount(); 104 Logger.info(TAG, 'getFilenameByUriForMedia count is: ' + count); 105 106 // 判断结果集中的数量是否小于0,小于0时表示接口调用失败 107 if (count < 0) { 108 Logger.error(TAG, 'get count from fetchFileResult failed, count: ' + count); 109 return; 110 } 111 // 判断结果集中的数量是否等于0,等于0时表示接口调用成功,但是检索结果集为空,请检查文件获取选项参数配置是否有误和设备中是否存在相应文件 112 if (count === 0) { 113 Logger.info(TAG, 'The count of fetchFileResult is zero'); 114 return; 115 } 116 Logger.info(TAG, 'Get fetchFileResult successfully, count: ' + count); 117 // 获取文件检索结果集中的第一个资源,使用callback方式返回异步结果,文件数量较多时请使用getAllObject接口 118 fetchFileResult.getFirstObject(async (error, fileAsset) => { 119 // 检查获取的第一个资源是否为undefined,若为undefined则接口调用失败 120 if (fileAsset === undefined) { 121 Logger.error(TAG, 'get first object failed with error: ' + error); 122 return; 123 } 124 Logger.info(TAG, 'fileAsset.displayName ' + '0 : ' + fileAsset.displayName); 125 Logger.info(TAG, 'fileAsset.uri 0:' + fileAsset.uri); 126 Logger.info(TAG, 'myUri: ' + myUri); 127 128 this.myFileTypes[index] = fileAsset.mediaType 129 this.myFileName = fileAsset.displayName; 130 this.myFileNames[index] = this.myFileName; 131 132 133 AppStorage.SetOrCreate('myFileName', this.myFileName); 134 AppStorage.SetOrCreate('myFileTypes', this.myFileTypes); 135 136 if (this.myFileTypes[index] === mediaLibrary.MediaType.VIDEO) { 137 Logger.info(TAG, 'getMediaNameByUri set showPauses for VIDEO'); 138 this.showPauses[index] = 1; 139 } 140 141 Logger.info(TAG, 'getFilenameByUriForMedia getImagesInfo this.myFileName ' + this.myFileName); 142 Logger.info(TAG, 'getFilenameByUriForMedia getImagesInfo index ' + index); 143 Logger.info(TAG, 'getFilenameByUriForMedia getImagesInfo this.myFileTypes[index] ' + this.myFileTypes[index]); 144 Logger.info(TAG, 'getFilenameByUriForMedia getImagesInfo this.myFileNames[index] ' + this.myFileNames[index]); 145 fetchFileResult.close(); 146 }); 147 }); 148 } 149 150 getImagesInfo() { 151 for (let index = 0; index < this.myUris.length; index++) { 152 Logger.info(TAG, 'getFilenameByUriForMedia getImagesInfo index: ' + index); 153 this.controllers[index] = new VideoController(); 154 this.getMediaNameByUri(this.myUris[index], index); 155 this.myFileSizes[index] = this.mediaFileUri.myGetFileSize(this.myUris[index], fs.OpenMode.READ_ONLY); 156 Logger.info(TAG, 'getFilenameByUriForMedia getVideosInfo this.myFileNames[index]: ' + this.myFileNames[index] + ' index ' + index); 157 Logger.info(TAG, 'getFilenameByUriForMedia getVideosInfo this.myFileSizes[index]' + this.myFileSizes[index]); 158 Logger.info(TAG, 'getFilenameByUriForMedia getVideosInfo this.myFileTypes[index] cc' + this.myFileTypes[index]); 159 } 160 } 161 162 build() { 163 Column() { 164 // 顶部的行容器 165 Row() { 166 // 后退箭头 167 Row() { 168 Image($r('app.media.ic_back')) 169 .focusable(true) 170 .focusOnTouch(true) 171 .width(25) 172 .height(25) 173 .align(Alignment.Start) 174 .id('back2Index') 175 .onClick(() => { 176 router.back(); 177 }) 178 } 179 .width('12.8%') 180 .padding({ left: '7.2%' }) 181 182 // 文件名及信息 183 Column() { 184 Row() { 185 Text(this.myFileName) 186 .focusable(true) 187 .focusOnTouch(true) 188 .fontSize(20) 189 .fontFamily('HarmonyHeiTi-Bold') 190 .fontColor('#182431') 191 .textAlign(TextAlign.Start) 192 .fontWeight(700) 193 .lineHeight(28) 194 .maxLines(1) 195 .textOverflow({ overflow: TextOverflow.Ellipsis }) 196 } 197 .width('100%') 198 .align(Alignment.Start) 199 .margin({ top: '0.4%', bottom: '0.3%' }) 200 201 Row() { 202 Text('size: ' + JSON.stringify(this.myFileSize) + 'B') 203 .focusable(true) 204 .focusOnTouch(true) 205 .opacity(0.6) 206 .fontFamily('HarmonyHeiTi') 207 .fontSize(14) 208 .fontColor('#182431') 209 .textAlign(TextAlign.Start) 210 .lineHeight(19) 211 .fontWeight(400) 212 } 213 .width('100%') 214 .margin({ top: '0.3%', bottom: '0.5%' }) 215 .align(Alignment.Start) 216 } 217 .width('45%') 218 .margin({ left: '5%' }) 219 220 // 右边一个图标,另存为 221 Row() { 222 Image($r('app.media.ic_saveas')) 223 .focusable(true) 224 .focusOnTouch(true) 225 .width(25) 226 .height(25) 227 .visibility(Visibility.Hidden) 228 } 229 .height('100%') 230 .width('37.2%') 231 .padding({ right: '7.2%' }) 232 .justifyContent(FlexAlign.End) 233 } 234 .height('7.4%') 235 .width('100%') 236 237 Scroll(this.scroller) { 238 // 显示媒体文件的容器 239 Column() { 240 List({ space: 20, initialIndex: 0 }) { 241 ForEach(this.myUris, (uri: string, index?: number) => { 242 ListItem() { 243 Column() { 244 Image(uri) 245 .borderRadius(24) 246 .visibility(index !== undefined && this.myFileTypes[index] === mediaLibrary.MediaType.IMAGE ? Visibility.Visible : Visibility.Hidden) 247 .onClick(() => { 248 if (index !== undefined) { 249 this.myFileSize = this.myFileSizes[index]; 250 this.myFileName = this.myFileNames[index]; 251 } 252 AppStorage.SetOrCreate('myFileName', this.myFileName); 253 AppStorage.SetOrCreate('myFileSize', this.myFileSize); 254 Logger.info(TAG, 'Image onClick myFileName is ' + this.myFileName); 255 Logger.info(TAG, 'Image onClick myFileName is ' + this.myFileSize); 256 }) 257 if (index !== undefined) { 258 Stack({ alignContent: Alignment.Center }) { 259 Video({ 260 src: uri, 261 controller: this.controllers[index] 262 }) 263 .autoPlay(false) 264 .controls(true) 265 .borderRadius(24) 266 .visibility(this.myFileTypes[index] === mediaLibrary.MediaType.VIDEO ? Visibility.Visible : Visibility.Hidden) 267 268 Image($r('app.media.ic_PAUSE')) 269 .width(25) 270 .height(25) 271 .onClick(() => { 272 this.controllers[index].start(); 273 this.showPauses[index] = 0; 274 }) 275 .visibility(this.showPauses[index] === 0 ? Visibility.Hidden : Visibility.Visible) 276 } 277 .onClick(() => { 278 this.myFileSize = this.myFileSizes[index]; 279 this.myFileName = this.myFileNames[index]; 280 281 AppStorage.SetOrCreate('myFileName', this.myFileName); 282 AppStorage.SetOrCreate('myFileSize', this.myFileSize); 283 }) 284 } 285 } 286 .height('100%') 287 } 288 .height('25%') 289 }, (item: string) => item) 290 } 291 .id('picScroller') 292 .scrollBar(BarState.Auto) 293 } 294 } 295 .padding({ top: '1.5%', left: '6.7%', right: '6.7%' }) 296 } 297 .backgroundColor('#f1f3f5') 298 .height('100%') 299 } 300} 301