1/* 2 * Copyright (C) 2024 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 16import router from '@ohos.router' 17import audio from '@ohos.multimedia.audio' 18import backgroundTaskManager from '@ohos.resourceschedule.backgroundTaskManager' 19import { BusinessError } from '@ohos.base' 20import fs from '@ohos.file.fs'; 21import wantAgent from '@ohos.app.ability.wantAgent' 22import ohosWantAgent from '@ohos.wantAgent' 23import AVSessionManager from '@ohos.multimedia.avsession'; 24import common from '@ohos.app.ability.common' 25import Want from '@ohos.app.ability.Want' 26 27let mXComponentController: XComponentController = new XComponentController() 28 29@Entry 30@Component 31struct Index { 32 @State message: string = 'Next Page' 33 @State imageLoadSuccess: string = "LoadFalse" 34 abilityContext: common.UIAbilityContext = AppStorage.get<common.UIAbilityContext>('EntryAbilityContext') as common.UIAbilityContext 35 audioRenderer: audio.AudioRenderer = {} as audio.AudioRenderer 36 @State audioStateText: string = 'Error' 37 38 async aboutToAppear() { 39 this.audioRenderer = await this.getAudioRenderer() 40 } 41 42 async onPageShow() { 43 this.audioStateText = this.audioRenderer ? this.audioRenderer.state.toString() : 'Error' 44 } 45 46 build() { 47 Row() { 48 Column() { 49 Button(this.message) 50 .id('firstButton') 51 .fontSize(50) 52 .fontWeight(FontWeight.Bold) 53 .onClick(() => { 54 router.pushUrl({ url: "pages/SecondPage" }) 55 }) 56 Text($r('app.string.Multilingual_Text')) 57 .id('multilingualText') 58 .fontSize(50) 59 .fontWeight(FontWeight.Bold) 60 Image($rawfile('test.png')) 61 .id('image') 62 .height('20%') 63 .onComplete((event) => { 64 this.imageLoadSuccess = "LoadSuccess" 65 }) 66 Text(this.imageLoadSuccess.toString()) 67 .id('imageLoadSuccess') 68 .fontSize(50) 69 .fontWeight(FontWeight.Bold) 70 XComponent({ 71 id: '', 72 type: 'surface', 73 libraryname: '', 74 controller: mXComponentController 75 }).onLoad(() => { 76 mXComponentController.setXComponentSurfaceSize({ surfaceWidth: 500, surfaceHeight: 500 }) 77 }) 78 .width('30%') 79 .height('30%') 80 81 Text(mXComponentController.getXComponentSurfaceId()) 82 .id("surfaceId") 83 84 Button('StartAudio') 85 .id('StartAudio') 86 .fontSize(20) 87 .onClick(async () => { 88 let res = await this.startAudio(this.audioRenderer, this.abilityContext) 89 this.audioStateText = this.audioRenderer ? this.audioRenderer.state.toString() : 'Error' 90 }) 91 Button('StopAudio') 92 .id('StopAudio') 93 .fontSize(20) 94 .onClick(async () => { 95 let res = await this.stopAudio(this.audioRenderer, this.abilityContext) 96 this.audioStateText = this.audioRenderer ? this.audioRenderer.state.toString() : 'Error' 97 }) 98 Text(this.audioStateText) 99 .id('AudioStateText') 100 } 101 .width('100%') 102 } 103 .height('100%') 104 } 105 106 async startAudio(audioRenderer: audio.AudioRenderer, abilityContext: common.UIAbilityContext) { 107 if (!audioRenderer) { 108 return false 109 } 110 try { 111 await audioRenderer.start() 112 let type: AVSessionManager.AVSessionType = 'audio'; 113 let session = await AVSessionManager.createAVSession(abilityContext, 'AVSession', type); 114 await session.activate() 115 } catch (error) { 116 let err: BusinessError = error as BusinessError 117 console.error(`Start audioRenderer Fail. Code: ${err.code}, message: ${err.message}`) 118 return false 119 } 120 let wantAgentInfo: wantAgent.WantAgentInfo = { 121 wants: [ 122 { 123 bundleName: 'com.acts.pcs.arktstest', 124 abilityName: 'EntryAbility' 125 } as Want 126 ], 127 requestCode: 0, 128 operationType: ohosWantAgent.OperationType.START_ABILITIES, 129 wantAgentFlags: [wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG] 130 } 131 try { 132 let wantAgentObj = await wantAgent.getWantAgent(wantAgentInfo) 133 await backgroundTaskManager.startBackgroundRunning(abilityContext, 134 backgroundTaskManager.BackgroundMode.AUDIO_PLAYBACK, wantAgentObj) 135 } catch (error) { 136 let err: BusinessError = error as BusinessError 137 console.error(`Start BackgroundRunning Fail. Code: ${err.code}, message: ${err.message}`) 138 return false 139 } 140 return true 141 } 142 143 async stopAudio(audioRenderer: audio.AudioRenderer, abilityContext: common.UIAbilityContext) { 144 if (!audioRenderer) { 145 return false 146 } 147 try { 148 audioRenderer.stop() 149 audioRenderer.release() 150 } catch (error) { 151 let err: BusinessError = error as BusinessError 152 console.error(`Stop audioRenderer Fail. Code: ${err.code}, message: ${err.message}`) 153 return false 154 } 155 try { 156 await backgroundTaskManager.stopBackgroundRunning(abilityContext) 157 } catch (error) { 158 let err: BusinessError = error as BusinessError 159 console.error(`Stop BackgroundRunning Fail. Code: ${err.code}, message: ${err.message}`) 160 return false 161 } 162 return true 163 } 164 165 async getAudioRenderer() { 166 try { 167 let audioStreamInfo: audio.AudioStreamInfo = { 168 samplingRate: audio.AudioSamplingRate.SAMPLE_RATE_48000, 169 channels: audio.AudioChannel.CHANNEL_2, 170 sampleFormat: audio.AudioSampleFormat.SAMPLE_FORMAT_S16LE, 171 encodingType: audio.AudioEncodingType.ENCODING_TYPE_RAW 172 } 173 let audioRendererInfo: audio.AudioRendererInfo = { 174 usage: audio.StreamUsage.STREAM_USAGE_MUSIC, 175 rendererFlags: 0 176 } 177 let audioRendererOptions: audio.AudioRendererOptions = { 178 streamInfo: audioStreamInfo, 179 rendererInfo: audioRendererInfo 180 } 181 let audioRenderer: audio.AudioRenderer = await audio.createAudioRenderer(audioRendererOptions) 182 let bufferSize: number = 0 183 class Options { 184 offset?: number 185 length?: number 186 } 187 let writeDataCallback = (buffer: ArrayBuffer) => { 188 let path = '/data/storage/el2/base/haps/entry/files/' 189 let filePath = path + '/Believer.wav' 190 let file: fs.File = fs.openSync(filePath, fs.OpenMode.READ_ONLY) 191 let options: Options = { 192 offset: bufferSize, 193 length: buffer.byteLength 194 } 195 fs.readSync(file.fd, buffer, options) 196 bufferSize += buffer.byteLength 197 } 198 audioRenderer.on('writeData', writeDataCallback) 199 return audioRenderer 200 } catch (error) { 201 let err: BusinessError = error as BusinessError 202 console.error(`Create audioRenderer Fail. Code: ${err.code}, message: ${err.message}`) 203 return {} as audio.AudioRenderer 204 } 205 } 206}