• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2023 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 */
15// @ts-nocheck
16import media from '@ohos.multimedia.media'
17import fs from '@ohos.file.fs'
18import Logger from './Logger'
19
20const TAG = 'qlw play'
21
22export class mediaPlay {
23  private avPlay: media.AVPlayer = undefined;
24  private surfaceId: number = -1;
25  public totalDuration: number;
26  private handleVideoPlayback: (isVideoPlayback: boolean) => void = false;
27
28  async getFileFd(name) {
29    let filesDir = globalThis.abilityContext.filesDir;
30    let path = filesDir + '/' + name;
31    let file = fs.openSync(path);
32    return file.fd;
33  }
34
35  async getRawfileFd(name) {
36    let file = await globalThis.abilityContext.resourceManager.getRawFd(name);
37    return file.fd;
38  }
39
40  getCurrentTime() {
41    return 0
42  }
43
44  seek() {
45
46  }
47
48  async init(surfaceId?) {
49    let fd
50    if (surfaceId) {
51      this.surfaceId = surfaceId
52      fd = await this.getFileFd('test.mp4')
53    } else {
54      fd = await this.getFileFd('test.wav')
55    }
56    Logger.info(TAG, ` fd success : ${fd}`)
57    this.avPlay = await media.createAVPlayer()
58    this.setCallBack(this.avPlay)
59    this.avPlay.url = 'fd://' + fd
60  }
61
62  async initVideo(surfaceId) {
63    this.surfaceId = surfaceId
64    let fd = await this.getRawfileFd('video.mp4')
65    Logger.info(TAG, ` fd success : ${fd}`)
66    this.avPlay = await media.createAVPlayer()
67    this.setCallBack(this.avPlay)
68    this.avPlay.url = 'fd://' + fd
69  }
70
71  async Play() {
72    await this.avPlay.play()
73  }
74
75  setCallBack(AVPlayer) {
76    AVPlayer.on('stateChange', async (state, reason) => {
77      switch (state) {
78        case 'idle':
79          Logger.info(TAG, 'state idle start')
80          break;
81        case 'initialized':
82          Logger.info(TAG + 'state initialized start ')
83          if (this.surfaceId != -1) {
84            AVPlayer.surfaceId = String(this.surfaceId)
85          }
86          await AVPlayer.prepare()
87          Logger.info(TAG, 'state initialized end')
88          break;
89        case 'prepared':
90          Logger.info(TAG, 'state prepared start')
91          await AVPlayer.play()
92          Logger.info(TAG, 'state prepared end')
93          break;
94        case 'playing':
95          Logger.info(TAG, 'state playing callback')
96          break;
97        case 'paused':
98          Logger.info(TAG, 'state paused callback')
99          break;
100        case 'completed':
101          if (this.handleVideoPlayback) {
102            this.handleVideoPlayback(true)
103          }
104          await AVPlayer.stop()
105          await AVPlayer.release()
106        case 'error':
107          Logger.info(TAG, 'state error callback')
108          break;
109      }
110    })
111    AVPlayer.on('error', (err) => {
112      Logger.info(TAG, `state error callback err:${err},code:${err.code},message:${err.message}}`)
113    })
114  }
115
116  setVideoPlaybackCallback(callback) {
117    this.handleVideoPlayback = callback
118  }
119
120  async release() {
121    if (this.avPlay) {
122      await this.avPlay.release()
123      Logger.info(TAG, 'avplay release success')
124    }
125  }
126
127  encodeWAV(sampleRateValue, sampleBitsValue, channelCountValue) {
128    let sampleRate = sampleRateValue;
129    let dataLen = sampleRate * 1000;
130    let sampleBits = sampleBitsValue * 8 + 8 // 采样格式
131    let channelCount = channelCountValue; // 单声道
132    let offset = 0;
133    let buffer = new ArrayBuffer(44);
134    let data = new DataView(buffer);
135    // 资源交换文件标识符
136    this.writeString(data, offset, 'RIFF');
137    offset += 4;
138    // 下个地址开始到文件尾总字节数,即文件大小-8
139    data.setUint32(offset, 36 + dataLen, true);
140    offset += 4;
141    // WAV文件标志
142    this.writeString(data, offset, 'WAVE');
143    offset += 4;
144    // 波形格式标志
145    this.writeString(data, offset, 'fmt ');
146    offset += 4;
147    // 过滤字节,一般为 0x10 = 16
148    data.setUint32(offset, 16, true);
149    offset += 4;
150    // 格式类别 (PCM形式采样数据)
151    data.setUint16(offset, 1, true);
152    offset += 2;
153    // 通道数
154    data.setUint16(offset, channelCount, true);
155    offset += 2;
156    // 采样率,每秒样本数,表示每个通道的播放速度
157    data.setUint32(offset, sampleRate, true);
158    offset += 4;
159    // 波形数据传输率 (每秒平均字节数) 单声道×每秒数据位数×每样本数据位/8
160    data.setUint32(offset, channelCount * sampleRate * (sampleBits / 8), true);
161    offset += 4;
162    // 快数据调整数 采样一次占用字节数 单声道×每样本的数据位数/8
163    data.setUint16(offset, channelCount * (sampleBits / 8), true);
164    offset += 2;
165    // 每样本数据位数
166    data.setUint16(offset, sampleBits, true);
167    offset += 2;
168    // 数据标识符
169    this.writeString(data, offset, 'data');
170    offset += 4;
171    // 采样数据总数,即数据总大小-44
172    data.setUint32(offset, dataLen, true);
173    offset += 4;
174    return data;
175  }
176
177  writeString(data, offset, str) {
178    for (let i = 0; i < str.length; i++) {
179      data.setUint8(offset + i, str.charCodeAt(i));
180    }
181  }
182}
183
184export default new mediaPlay()
185
186