1# 通话设备切换 2 3### 介绍 4 5本示例主要展示了通话设备切换的相关功能,使用[@ohos.multimedia.avCastPicker](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-avsession-kit/ohos-multimedia-avcastpicker.md)和[@ohos.multimedia.avCastPickerParam](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-avsession-kit/js-apis-avCastPickerParam.md)等接口实现通话设备切换功能。 6 7> 注意: 8> 通话设备切换按钮可显示默认样式或者自定义样式,默认样式由系统提供,自定义组件由应用提供。还可参考相关的[开发指南](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/media/avsession/using-switch-call-devices.md)。 9 10### 效果预览 11 12| 主页 | 默认样式页面 | 自定义样式页面 | 13|-------------------------------- | -------------------------------- | -------------------------------- | 14|  |  |  | 15 16### 使用说明 17 181. 点击进入主页,可以选择点击按钮默认样式组件和自定义样式组件,如果点击默认样式组件,跳转到显示默认样式的页面;点击自定义样式组件,跳转到显示自定义样式的页面; 192. 进入页面后,有三个按钮,分别是start,stop和设备切换按钮,点击start按钮,可播放音频,点击stop,可暂停音频, 点击设备切换按钮,可选择当前输出设备并显示设备对应的样式。 20 21### 工程目录 22 23项目中关键的目录结构如下: 24 25``` 26entry/src/main/ets/ 27|---pages 28|---|---Index.ets //初始界面实现 29|---|---DefaultPicker.ets //默认样式实现 30|---|---CustomPicker.ets //自定义样式实现 31 32``` 33 34### 具体实现 35 36#### 初始界面实现 37 38 初始界面相关的实现都封装在pages/Index.ets下,源码参考:[pages/Index.ets](./entry/src/main/ets/pages/Index.ets)。 39 40 * 界面显示两个按钮分别为默认样式组件和自定义样式组件,可分别跳转到系统默认样式实现界面和自定义样式实现界面,相关代码如下: 41 42 ```ets 43 Button() { 44 // 按钮的内容 45 } 46 .onClick(async() => { 47 await router.pushUrl({ url:'pages/DefaultPicker' });//系统默认样式实现 48 }) 49 50 Button() { 51 // 按钮的内容 52 } 53 .onClick(async() => { 54 await router.pushUrl({ url:'pages/CustomPicker' });//自定义样式实现 55 }) 56 ``` 57#### 默认系统样式 58 59 默认系统样式的相关内容封装在pages/DefaultPicker.ets下,源码参考:[pages/DefaultPicker.ets](./entry/src/main/ets/pages/DefaultPicker.ets)。 60 61 * 在需要切换设备的通话界面创建AVCastPicker组件。 62 63 ```ets 64 import { AVCastPicker } from '@kit.AVSessionKit'; 65 66 AVCastPicker({ 67 normalColor: this.avCastPickerColor, 68 activeColor: this.avCastPickerColor, 69 }) 70 .size({ width: 45, height: 45 }) 71 ``` 72 73 * 拉起组件前需创建voice_call类型的AVSession,AVSession在构造方法中支持不同的类型参数,由AVSessionType定义,voice_call表示通话类型。 74 75 ```ets 76 import { avSession } from '@kit.AVSessionKit'; 77 78 init() { 79 //... 80 this.session = await avSession.createAVSession(this.appContext, 'voiptest', 'voice_call'); 81 } 82 ``` 83 84 * 创建VOICE_COMMUNICATION类型的AudioRenderer,并播放,可模拟通话场景: 85 86 * 创建如下三个变量。 87 88 ```ets 89 private audioRendererInfo: audio.AudioRendererInfo = { 90 usage: audio.StreamUsage.STREAM_USAGE_VOICE_COMMUNICATION, 91 rendererFlags: 0 92 } 93 private audioStreamInfo: audio.AudioStreamInfo = { 94 samplingRate: audio.AudioSamplingRate.SAMPLE_RATE_48000, // 采样率 95 channels: audio.AudioChannel.CHANNEL_2, // 通道 96 sampleFormat: audio.AudioSampleFormat.SAMPLE_FORMAT_S16LE, // 采样格式 97 encodingType: audio.AudioEncodingType.ENCODING_TYPE_RAW // 编码格式 98 } 99 private audioRendererOption: audio.AudioRendererOptions = { 100 streamInfo: this.audioStreamInfo, 101 rendererInfo: this.audioRendererInfo 102 } 103 ``` 104 105 * 调用 startRenderer() 播放音频。 106 107 * 调用 stopRenderer() 暂停播放音频。 108 109#### 自定义样式 110 111 自定义样式的相关内容封装在pages/CustomPicker.ets下,源码参考:[pages/CustomPicker.ets](./entry/src/main/ets/pages/CustomPicker.ets)。 112 113 * 在需要切换设备的通话界面创建AVCastPicker组件。 114 115 ```ets 116 117 import { AVCastPicker } from '@kit.AVSessionKit'; 118 119 @State pickerImage: ResourceStr = $r('app.media.ic_earpiece'); 120 121 @Builder 122 ImangeBuilder(): void { 123 Image(this.pickerImage) 124 .size({ width: '100%', height: '100%' }) 125 .backgroundColor('#00000000') 126 .fillColor(Color.Black) 127 } 128 129 Column() { 130 Button() { 131 AVCastPicker({ 132 normalColor: this.avCastPickerColor, 133 activeColor: this.avCastPickerColor, 134 customPicker: (): void => this.ImangeBuilder(), 135 onStateChange: (state: AVCastPickerState) => { 136 console.error(`change avcastpicker: ${state}`); 137 } 138 }) 139 .size({ width: 45, height: 45 }) 140 } 141 .size({ width: 64, height: 64 }) 142 .type(ButtonType.Circle) 143 .backgroundColor(Color.Orange) 144 } 145 .size({ width: '33%', height: 64 }) 146 147 ``` 148 149 * 拉起组件前也需创建voice_call类型的AVSession。为了保证能够正常更新样式,需要监听当前设备切换,如果当前设备切换,将刷新显示样式 150 151 ```ets 152 153 import { avSession } from '@kit.AVSessionKit'; 154 import { audio } from '@kit.AudioKit'; 155 156 init(){ 157 this.session = await avSession.createAVSession(this.appContext, 'voiptest', 'voice_call'); 158 this.observerDevices(); 159 } 160 161 async observerDevices() { 162 if(!this.audioRoutingManager) { 163 return; 164 } 165 let desc: audio.AudioDeviceDescriptors = this.audioRoutingManager.getPreferredOutputDeviceForRendererInfoSync(this.audioRendererInfo); 166 this.changePickerShow(desc); 167 audioRoutingManager.on('preferOutputDeviceChangeForRendererInfo', this.audioRendererInfo, (desc: audio.AudioDeviceDescriptors) => { 168 if(!this.audioRoutingManager) { 169 return; 170 } 171 console.log(`device change to: ${desc[0].deviceType}`); 172 let devices: audio.AudioDeviceDescriptors = this.audioRoutingManager.getPreferredOutputDeviceForRendererInfoSync(this.audioRendererInfo); 173 this.changePickerShow(devices); 174 }); 175 } 176 177 private changePickerShow(desc: audio.AudioDeviceDescriptors) { 178 if (desc[0].deviceType === 2) { 179 this.pickerImage = $r('app.media.ic_public_sound'); 180 } else if (desc[0].deviceType === 7) { 181 this.pickerImage = $r('app.media.ic_bluetooth'); 182 } else { 183 this.pickerImage = $r('app.media.ic_earpiece'); 184 } 185 } 186 187 ``` 188 189 * 创建VOICE_COMMUNICATION类型的AudioRenderer,并播放,可模拟通话场景,具体实现如默认样式。 190 191### 相关权限 192 193不涉及 194 195### 依赖 196 197不涉及 198 199### 约束与限制 200 2011. 本示例仅支持标准系统上运行。 202 2032. 本示例为Stage模型,支持API12版本SDK,SDK版本号(API Version 12 Release),镜像版本号(5.0 Release)。 204 2053. 本示例需要使用DevEco Studio 版本号(5.0 Release)及以上版本才可编译运行。 206 2074. 本示例手机设备支持,RK暂不支持。 208 209### 下载 210 211如需单独下载本工程,执行如下命令: 212 213``` 214git init 215git config core.sparsecheckout true 216echo code/BasicFeature/Media/AVSession/AvCastPickerForCall > .git/info/sparse-checkout 217git remote add origin https://gitee.com/openharmony/applications_app_samples.git 218git pull origin master 219``` 220