1# 使用TonePlayer开发音频播放功能(仅对系统应用开放) 2<!--Kit: Audio Kit--> 3<!--Subsystem: Multimedia--> 4<!--Owner: @songshenke--> 5<!--Designer: @caixuejiang; @hao-liangfei; @zhanganxiang--> 6<!--Tester: @Filger--> 7<!--Adviser: @zengyawen--> 8 9TonePlayer<sup>9+</sup>提供播放和管理DTMF(Dual Tone Multi Frequency,双音多频)音调的方法,包括各种系统监听音调、专有音调,如拨号音、通话回铃音等。主要工作是将需要生成音调的[ToneType](../../reference/apis-audio-kit/js-apis-audio-sys.md#tonetype9)类型,通过自带算法生成多个不同频率的正弦波叠加形成声音数据,通过[AudioRenderer](../../reference/apis-audio-kit/arkts-apis-audio-AudioRenderer.md)进行播放,同时对播放任务进行管理。包含加载DTMF音调配置、启动DTMF音调播放、停止当前正在播放的音调、释放与此TonePlayer对象关联的资源等流程。详细API说明请参考[TonePlayer API文档](../../reference/apis-audio-kit/js-apis-audio-sys.md#toneplayer9)。 10 11## 支持的播放音调类型 12 13播放音调类型[ToneType](../../reference/apis-audio-kit/js-apis-audio-sys.md#tonetype9)信息(如下表所示),可通过"audio.ToneType.指定类型" 作为参数调用load()方法加载指定类型的音调资源。 14 15| 播放音调类型 | 值 | 说明 | 16| -------- | -------- | -------- | 17| TONE_TYPE_DIAL_0 | 0 | 键0的DTMF音。 | 18| TONE_TYPE_DIAL_1 | 1 | 键1的DTMF音。 | 19| TONE_TYPE_DIAL_2 | 2 | 键2的DTMF音。 | 20| TONE_TYPE_DIAL_3 | 3 | 键3的DTMF音。 | 21| TONE_TYPE_DIAL_4 | 4 | 键4的DTMF音。 | 22| TONE_TYPE_DIAL_5 | 5 | 键5的DTMF音。 | 23| TONE_TYPE_DIAL_6 | 6 | 键6的DTMF音。 | 24| TONE_TYPE_DIAL_7 | 7 | 键7的DTMF音。 | 25| TONE_TYPE_DIAL_8 | 8 | 键8的DTMF音。 | 26| TONE_TYPE_DIAL_9 | 9 | 键9的DTMF音。 | 27| TONE_TYPE_DIAL_S | 10 | 键\*的DTMF音。 | 28| TONE_TYPE_DIAL_P | 11 | 键\#的DTMF音。 | 29| TONE_TYPE_DIAL_A | 12 | 键A的DTMF音。 | 30| TONE_TYPE_DIAL_B | 13 | 键B的DTMF音。 | 31| TONE_TYPE_DIAL_C | 14 | 键C的DTMF音。 | 32| TONE_TYPE_DIAL_D | 15 | 键D的DTMF音。 | 33| TONE_TYPE_COMMON_SUPERVISORY_DIAL | 100 | 呼叫监管音调,拨号音。 | 34| TONE_TYPE_COMMON_SUPERVISORY_BUSY | 101 | 呼叫监管音调,忙。 | 35| TONE_TYPE_COMMON_SUPERVISORY_CONGESTION | 102 | 呼叫监管音调,拥塞。 | 36| TONE_TYPE_COMMON_SUPERVISORY_RADIO_ACK | 103 | 呼叫监管音调,无线电 ACK。 | 37| TONE_TYPE_COMMON_SUPERVISORY_RADIO_NOT_AVAILABLE | 104 | 呼叫监管音调,无线电不可用。 | 38| TONE_TYPE_COMMON_SUPERVISORY_CALL_WAITING | 106 | 呼叫监管音调,呼叫等待。 | 39| TONE_TYPE_COMMON_SUPERVISORY_RINGTONE | 107 | 呼叫监管音调,铃声。 | 40| TONE_TYPE_COMMON_SUPERVISORY_CALL_HOLDING<sup>18+</sup> | 108 | 呼叫保持音调。 | 41| TONE_TYPE_COMMON_PROPRIETARY_BEEP | 200 | 专有声调,一般蜂鸣声。 | 42| TONE_TYPE_COMMON_PROPRIETARY_ACK | 201 | 专有声调,ACK。 | 43| TONE_TYPE_COMMON_PROPRIETARY_PROMPT | 203 | 专有声调,PROMPT。 | 44| TONE_TYPE_COMMON_PROPRIETARY_DOUBLE_BEEP | 204 | 专有声调,双重蜂鸣声。 | 45 46## 开发步骤及注意事项 47 48以下步骤描述了TonePlayer接口实现播放功能流程: 49 501. 创建DTMF播放器 ,获取tonePlayer实例。 51 52```ts 53import { audio } from '@kit.AudioKit'; 54 55let audioRendererInfo: audio.AudioRendererInfo = { 56 usage: audio.StreamUsage.STREAM_USAGE_DTMF, // 音频流使用类型:拨号音。根据业务场景配置,参考StreamUsage。 57 rendererFlags: 0 // 音频渲染器标志。 58}; 59 60async function createTonePlayer() { 61 let tonePlayerPromise = await audio.createTonePlayer(audioRendererInfo); 62} 63``` 64 652. 加载指定类型DTMF音调配置。 66 67```ts 68async function load() { 69 await tonePlayerPromise.load(audio.ToneType.TONE_TYPE_DIAL_0); 70} 71``` 72 733. 启动DTMF音调播放。 74 75```ts 76async function start() { 77 await tonePlayerPromise.start(); 78} 79``` 80 814. 停止当前正在播放的音调。 82 83```ts 84async function stop() { 85 await tonePlayerPromise.stop(); 86} 87``` 88 895. 释放与此TonePlayer对象关联的资源。 90 91```ts 92async function release() { 93 await tonePlayerPromise.release(); 94} 95``` 96 97在接口未按此正常调用时序调用时,接口会返回错误码6800301 NAPI_ERR_SYSTEM。 98 99## 完整示例 100 101参考以下示例,点击键盘拨号按键,并启动对应的DTMF音调播放。 102 103为保证UI线程不被阻塞,大部分TonePlayer调用都是异步的。对于每个API均提供了callback函数和Promise函数,以下示例均采用Promise函数,更多方式可参考API文档[TonePlayer](../../reference/apis-audio-kit/js-apis-audio-sys.md#toneplayer9)。 104 105```ts 106import { audio } from '@kit.AudioKit'; 107import { BusinessError } from '@kit.BasicServicesKit'; 108 109let timerPro : number; 110// promise调用方式 111async function testTonePlayerPromise(type: audio.ToneType) { 112 console.info('testTonePlayerPromise start'); 113 if (timerPro) clearTimeout(timerPro); 114 let tonePlayerPromise: audio.TonePlayer; 115 let audioRendererInfo: audio.AudioRendererInfo = { 116 usage: audio.StreamUsage.STREAM_USAGE_DTMF, // 音频流使用类型:拨号音。根据业务场景配置,参考StreamUsage。 117 rendererFlags: 0 // 音频渲染器标志。 118 }; 119 timerPro = setTimeout(async () => { 120 try { 121 console.info('testTonePlayerPromise: createTonePlayer'); 122 // 创建DTMF播放器。 123 tonePlayerPromise = await audio.createTonePlayer(audioRendererInfo); 124 console.info('testTonePlayerPromise: createTonePlayer-success'); 125 console.info(`testTonePlayerPromise: load type: ${type}`); 126 // 加载type类型音调。 127 await tonePlayerPromise.load(type); 128 console.info('testTonePlayerPromise: load-success'); 129 console.info(`testTonePlayerPromise: start type: ${type}`); 130 // 启动DTMF音调播放。 131 await tonePlayerPromise.start(); 132 console.info('testTonePlayerPromise: start-success'); 133 console.info(`testTonePlayerPromise: stop type: ${type}`); 134 setTimeout(async()=>{ 135 // 停止当前正在播放的音调。 136 await tonePlayerPromise.stop(); 137 console.info('testTonePlayerPromise: stop-success'); 138 console.info(`testTonePlayerPromise: release type: ${type}`); 139 // 释放与此TonePlayer对象关联的资源。 140 await tonePlayerPromise.release(); 141 console.info('testTonePlayerPromise: release-success'); 142 }, 30) 143 } catch(err) { 144 let error = err as BusinessError; 145 console.error(`testTonePlayerPromise err : ${error}`); 146 } 147 }, 200) 148}; 149 150async function testTonePlayer() { 151 testTonePlayerPromise(audio.ToneType.TONE_TYPE_DIAL_0); 152} 153``` 154