• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2022 Huawei Device 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 */
15import mediaLibrary from '@ohos.multimedia.mediaLibrary'
16import router from '@ohos.router'
17import MediaUtils from '../model/MediaUtils'
18import Logger from '../model/Logger'
19import PlayButton from '../common/PlayButton'
20import PlayTitle from '../common/PlayTitle'
21import PlayAbility from '../PlayAbility/PlayAbility'
22import VideoPlayerUtils from '../model/VideoPlayerUtils'
23import { getTimeString } from '../model/TimeUtils'
24
25const TAG: string = 'Play'
26
27@Entry
28@Component
29struct Play {
30  @StorageLink('fileId') fileId: number = 0
31  private fileAsset: mediaLibrary.FileAsset = undefined
32  private fd: number = undefined
33  private intervalId: number = undefined
34  private mXComponentController: XComponentController = new XComponentController()
35  private videoPlayer: VideoPlayerUtils = new VideoPlayerUtils()
36  private surfaceId: number = 0
37  private mediaUtil: MediaUtils = new MediaUtils(getContext(this) as any)
38  @State currentTime: number = 0
39  @State displayName: string = ''
40  @State isShowMenu: boolean = false
41  @State @Watch('playStateChange') isPlaying: boolean = false
42  @State ratio: number = 1.0
43
44  aboutToAppear() {
45    Logger.info(TAG, `aboutToAppear, fileId =${this.fileId }`)
46    this.surfaceId = this.mXComponentController.getXComponentSurfaceId()
47    this.videoPlayer.setFinishCallBack(() => {
48      this.isPlaying = false
49      this.currentTime = 0
50    })
51    this.intervalId = setInterval(() => {
52      if (this.isPlaying) {
53        this.currentTime = this.videoPlayer.getCurrentTime()
54      }
55    }, 1000)
56  }
57
58  async playVideo() {
59    Logger.info(TAG, 'playVideo')
60    let context = getContext(this) as any
61    await context.requestPermissionsFromUser(['ohos.permission.READ_MEDIA'])
62    this.fileAsset = await this.mediaUtil.queryFile(this.fileId)
63    this.displayName = this.fileAsset.displayName
64    this.ratio = this.fileAsset.width / this.fileAsset.height
65    this.mXComponentController.setXComponentSurfaceSize({
66      surfaceWidth: this.fileAsset.width,
67      surfaceHeight: this.fileAsset.height
68    })
69    this.surfaceId = this.mXComponentController.getXComponentSurfaceId()
70    Logger.info(TAG, `onLoad,surfaceId =${this.surfaceId}`)
71    this.fd = await this.fileAsset.open('Rw')
72    let fdPath = 'fd://' + this.fd
73    await this.videoPlayer.initVideoPlayer(fdPath, this.surfaceId)
74    this.isPlaying = true
75  }
76
77  playStateChange() {
78    if (this.isPlaying) {
79      this.videoPlayer.play()
80      Logger.info(TAG, 'play')
81    } else {
82      this.videoPlayer.pause()
83      Logger.info(TAG, 'pause')
84    }
85  }
86
87  handleBack = () => {
88    router.back()
89    this.clearVideoPlayer()
90  }
91
92  build() {
93    Row() {
94      Stack({ alignContent: Alignment.Center }) {
95        if (this.isShowMenu) {
96          Column() {
97            PlayTitle({ title: this.displayName, handleBack: this.handleBack })
98            Row() {
99              PlayButton({ isPlaying: $isPlaying })
100            }
101            .margin({ top: '40%' })
102
103            Blank()
104            Row() {
105              Text(getTimeString(this.currentTime))
106                .fontSize(25)
107                .fontColor(Color.White)
108              Blank()
109              Text(this.fileAsset ? getTimeString(this.fileAsset.duration) : '00:00')
110                .fontSize(25)
111                .fontColor(Color.White)
112            }
113            .width('95%')
114
115            Slider({ value: this.fileAsset ? this.currentTime / this.fileAsset.duration * 100 : 0 })
116              .width('92%')
117              .selectedColor(Color.White)
118              .onChange((value: number) => {
119                Logger.info(TAG, 'seek time change')
120                this.currentTime = this.fileAsset.duration * value / 100
121                this.videoPlayer.seek(this.currentTime)
122              })
123          }
124          .height('100%')
125          .zIndex(2)
126        }
127        Row() {
128          XComponent({
129            id: 'componentId',
130            type: 'surface',
131            controller: this.mXComponentController
132          })
133            .onLoad(() => {
134              Logger.info(TAG, 'onLoad is called')
135              this.playVideo()
136            })
137            .width('100%')
138            .aspectRatio(this.ratio)
139        }
140        .height('100%')
141        .width('100%')
142        .justifyContent(FlexAlign.Center)
143      }
144      .width('100%')
145      .height('100%')
146      .backgroundColor(Color.Black)
147      .onClick(() => {
148        this.isShowMenu = !this.isShowMenu
149      })
150    }
151    .height('100%')
152  }
153
154  onPageHide() {
155    this.isPlaying = false
156    this.clearVideoPlayer()
157  }
158
159  clearVideoPlayer() {
160    clearInterval(this.intervalId)
161    this.videoPlayer.stop()
162    this.videoPlayer.release()
163    this.fileAsset.close(this.fd)
164  }
165}