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