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 .fontSize(50) 105 .fontWeight(FontWeight.Bold) 106 } 107 } 108 .margin({ right: 10 }) 109 } 110 .id('scroll') 111 .scrollBar(BarState.Off) 112 .scrollable(ScrollDirection.Vertical) 113 } 114 .width('100%') 115 .height('80%') 116 .padding({ 117 bottom: 20, 118 }) 119 } 120 .height('100%') 121 .alignItems(VerticalAlign.Top) 122 } 123 124 async startAudio(audioRenderer: audio.AudioRenderer, abilityContext: common.UIAbilityContext) { 125 if (!audioRenderer) { 126 return false 127 } 128 try { 129 await audioRenderer.start() 130 let type: AVSessionManager.AVSessionType = 'audio'; 131 let session = await AVSessionManager.createAVSession(abilityContext, 'AVSession', type); 132 await session.activate() 133 } catch (error) { 134 let err: BusinessError = error as BusinessError 135 console.error(`Start audioRenderer Fail. Code: ${err.code}, message: ${err.message}`) 136 return false 137 } 138 let wantAgentInfo: wantAgent.WantAgentInfo = { 139 wants: [ 140 { 141 bundleName: 'com.acts.pcs.arktstest', 142 abilityName: 'EntryAbility' 143 } as Want 144 ], 145 requestCode: 0, 146 operationType: ohosWantAgent.OperationType.START_ABILITIES, 147 wantAgentFlags: [wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG] 148 } 149 try { 150 let wantAgentObj = await wantAgent.getWantAgent(wantAgentInfo) 151 await backgroundTaskManager.startBackgroundRunning(abilityContext, 152 backgroundTaskManager.BackgroundMode.AUDIO_PLAYBACK, wantAgentObj) 153 } catch (error) { 154 let err: BusinessError = error as BusinessError 155 console.error(`Start BackgroundRunning Fail. Code: ${err.code}, message: ${err.message}`) 156 return false 157 } 158 return true 159 } 160 161 async stopAudio(audioRenderer: audio.AudioRenderer, abilityContext: common.UIAbilityContext) { 162 if (!audioRenderer) { 163 return false 164 } 165 try { 166 audioRenderer.stop() 167 audioRenderer.release() 168 } catch (error) { 169 let err: BusinessError = error as BusinessError 170 console.error(`Stop audioRenderer Fail. Code: ${err.code}, message: ${err.message}`) 171 return false 172 } 173 try { 174 await backgroundTaskManager.stopBackgroundRunning(abilityContext) 175 } catch (error) { 176 let err: BusinessError = error as BusinessError 177 console.error(`Stop BackgroundRunning Fail. Code: ${err.code}, message: ${err.message}`) 178 return false 179 } 180 return true 181 } 182 183 async getAudioRenderer() { 184 try { 185 let audioStreamInfo: audio.AudioStreamInfo = { 186 samplingRate: audio.AudioSamplingRate.SAMPLE_RATE_48000, 187 channels: audio.AudioChannel.CHANNEL_2, 188 sampleFormat: audio.AudioSampleFormat.SAMPLE_FORMAT_S16LE, 189 encodingType: audio.AudioEncodingType.ENCODING_TYPE_RAW 190 } 191 let audioRendererInfo: audio.AudioRendererInfo = { 192 usage: audio.StreamUsage.STREAM_USAGE_MUSIC, 193 rendererFlags: 0 194 } 195 let audioRendererOptions: audio.AudioRendererOptions = { 196 streamInfo: audioStreamInfo, 197 rendererInfo: audioRendererInfo 198 } 199 let audioRenderer: audio.AudioRenderer = await audio.createAudioRenderer(audioRendererOptions) 200 let bufferSize: number = 0 201 class Options { 202 offset?: number 203 length?: number 204 } 205 let writeDataCallback = (buffer: ArrayBuffer) => { 206 let path = '/data/storage/el2/base/haps/entry/files/' 207 let filePath = path + '/Believer.wav' 208 let file: fs.File = fs.openSync(filePath, fs.OpenMode.READ_ONLY) 209 let options: Options = { 210 offset: bufferSize, 211 length: buffer.byteLength 212 } 213 fs.readSync(file.fd, buffer, options) 214 bufferSize += buffer.byteLength 215 } 216 audioRenderer.on('writeData', writeDataCallback) 217 return audioRenderer 218 } catch (error) { 219 let err: BusinessError = error as BusinessError 220 console.error(`Create audioRenderer Fail. Code: ${err.code}, message: ${err.message}`) 221 return {} as audio.AudioRenderer 222 } 223 } 224}