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