audio-stream-manager.md 10.1 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
# 音频流管理开发指导

## 场景介绍

AudioStreamManager提供了音频流管理的方法。开发者可以通过本指导了解应用如何通过AudioStreamManager管理音频流。

### 工作流程

在进行应用开发的过程中,建议开发者通过on('stateChange')方法订阅AudioCapturer的状态变更。因为针对AudioCapturer的某些操作,仅在音频采集器在固定状态时才能执行。如果应用在音频采集器处于错误状态时执行操作,系统可能会抛出异常或生成其他未定义的行为。

详细API含义可参考:[音频管理API文档AudioStreamManager](../reference/apis/js-apis-audio.md#AudioStreamManager9)

**图1** 音频流管理调用关系图

![](figures/zh-ch_image_audio_stream_manager.png)

## 开发步骤

1. 创建AudioStreamManager实例。

   在使用AudioStreamManager的API前,需要使用getStreamManager()创建一个AudioStreamManager实例。

   ```js
  var audioStreamManager = audio.getStreamManager();
   ```

2. (可选)使用on('audioRendererChange')监听音频渲染器更改事件。
如果音频流监听应用需要在音频播放应用状态变化、设备变化、音频属性变化时获取通知,可以订阅该事件。更多事件请参考[API参考文档](../reference/apis/js-apis-audio.md)

   ```js
audioStreamManager.on('audioRendererChange',  (AudioRendererChangeInfoArray) => {
  for (let i = 0; i < AudioRendererChangeInfoArray.length; i++) {
    AudioRendererChangeInfo = AudioRendererChangeInfoArray[i];
    console.info('## RendererChange on is called for ' + i + ' ##');
    console.info('StreamId for ' + i + ' is:' + AudioRendererChangeInfo.streamId);
    console.info('ClientUid for ' + i + ' is:' + AudioRendererChangeInfo.clientUid);
    console.info('Content for ' + i + ' is:' + AudioRendererChangeInfo.rendererInfo.content);
    console.info('Stream for ' + i + ' is:' + AudioRendererChangeInfo.rendererInfo.usage);
    console.info('Flag ' + i + ' is:' + AudioRendererChangeInfo.rendererInfo.rendererFlags);
    console.info('State for ' + i + ' is:' + AudioRendererChangeInfo.rendererState);  
    var devDescriptor = AudioRendererChangeInfo.deviceDescriptors;
    for (let j = 0; j < AudioRendererChangeInfo.deviceDescriptors.length; j++) {
      console.info('Id:' + i + ':' + AudioRendererChangeInfo.deviceDescriptors[j].id);
      console.info('Type:' + i + ':' + AudioRendererChangeInfo.deviceDescriptors[j].deviceType);
      console.info('Role:' + i + ':' + AudioRendererChangeInfo.deviceDescriptors[j].deviceRole);
      console.info('Name:' + i + ':' + AudioRendererChangeInfo.deviceDescriptors[j].name);
      console.info('Address:' + i + ':' + AudioRendererChangeInfo.deviceDescriptors[j].address);
      console.info('SampleRates:' + i + ':' + AudioRendererChangeInfo.deviceDescriptors[j].sampleRates[0]);
      console.info('ChannelCounts' + i + ':' + AudioRendererChangeInfo.deviceDescriptors[j].channelCounts[0]);
      console.info('ChannelMask:' + i + ':' + AudioRendererChangeInfo.deviceDescriptors[j].channelMasks);
    }
  }
});
   ```

3. (可选)使用off('audioRendererChange')取消监听音频渲染器更改事件。

   ```js
audioStreamManager.off('audioRendererChange');
console.info('[RENDERER-CHANGE-ON-001] ######### RendererChange Off is called #########');
   ```   

4. (可选)使用on('audioCapturerChange')监听音频捕获器更改事件。
如果音频流监听应用需要在音频录制应用状态变化、设备变化、音频属性变化时获取通知,可以订阅该事件。更多事件请参考[API参考文档](../reference/apis/js-apis-audio.md)

   ```js
audioStreamManager.on('audioCapturerChange', (AudioCapturerChangeInfoArray) =>  {
  for (let i = 0; i < AudioCapturerChangeInfoArray.length; i++) {
    console.info(' ## CapChange on is called for element ' + i + ' ##');
    console.info('StreamId for ' + i + 'is:' + AudioCapturerChangeInfoArray[i].streamId);
    console.info('ClientUid for ' + i + 'is:' + AudioCapturerChangeInfoArray[i].clientUid);
    console.info('Source for ' + i + 'is:' + AudioCapturerChangeInfoArray[i].capturerInfo.source);
    console.info('Flag ' + i + 'is:' + AudioCapturerChangeInfoArray[i].capturerInfo.capturerFlags);
    console.info('State for ' + i + 'is:' + AudioCapturerChangeInfoArray[i].capturerState);  
    for (let j = 0; j < AudioCapturerChangeInfoArray[i].deviceDescriptors.length; j++) {
      console.info('Id:' + i + ':' + AudioCapturerChangeInfoArray[i].deviceDescriptors[j].id);
      console.info('Type:' + i + ':' + AudioCapturerChangeInfoArray[i].deviceDescriptors[j].deviceType);
      console.info('Role:' + i + ':' + AudioCapturerChangeInfoArray[i].deviceDescriptors[j].deviceRole);
      console.info('Name:' + i + ':' + AudioCapturerChangeInfoArray[i].deviceDescriptors[j].name);
      console.info('Address:' + i + ':' + AudioCapturerChangeInfoArray[i].deviceDescriptors[j].address);
      console.info('SampleRates:' + i + ':' + AudioCapturerChangeInfoArray[i].deviceDescriptors[j].sampleRates[0]);
      console.info('ChannelCounts' + i + ':' + AudioCapturerChangeInfoArray[i].deviceDescriptors[j].channelCounts[0]);
      console.info('ChannelMask:' + i + ':' + AudioCapturerChangeInfoArray[i].deviceDescriptors[j].channelMasks);
    }
  }
});
   ```  

5. (可选)使用off('audioCapturerChange')取消监听音频捕获器更改事件。

   ```js
audioStreamManager.off('audioCapturerChange');
console.info('[GET_CAPTURER_STATE_2_PROMISE] ######### CapturerChange Off is called #########');
    ```  
6. (可选)使用getCurrentAudioRendererInfoArray()获取当前音频渲染器的信息。
该接口可获取音频流唯一ID,音频播放客户端的UID,音频状态以及音频播放器的其他信息。需注意的是若对第三方音频流监听应用未配置相关权限,则查询到的音频状态为0,音频播放器其他信息为null。
   ```js
await audioStreamManager.getCurrentAudioRendererInfoArray().then( function (AudioRendererChangeInfoArray) {
  console.info('[GET_RENDERER_STATE_3_PROMISE] ######### Get Promise is called ##########');
  if (AudioRendererChangeInfoArray != null) {
    for (let i = 0; i < AudioRendererChangeInfoArray.length; i++) {
      AudioRendererChangeInfo = AudioRendererChangeInfoArray[i];
      console.info('StreamId for ' + i +' is:' + AudioRendererChangeInfo.streamId);
      console.info('ClientUid for ' + i + ' is:' + AudioRendererChangeInfo.clientUid);
      console.info('Content ' + i + ' is:' + AudioRendererChangeInfo.rendererInfo.content);
      console.info('Stream' + i +' is:' + AudioRendererChangeInfo.rendererInfo.usage);
      console.info('Flag' + i + ' is:' + AudioRendererChangeInfo.rendererInfo.rendererFlags); 
      console.info('State for ' + i + ' is:' + AudioRendererChangeInfo.rendererState);  
      var devDescriptor = AudioRendererChangeInfo.deviceDescriptors;
      for (let j = 0; j < AudioRendererChangeInfo.deviceDescriptors.length; j++) {
        console.info('Id:' + i + ':' + AudioRendererChangeInfo.deviceDescriptors[j].id);
        console.info('Type:' + i + ':' + AudioRendererChangeInfo.deviceDescriptors[j].deviceType);
        console.info('Role:' + i + ':' + AudioRendererChangeInfo.deviceDescriptors[j].deviceRole);
        console.info('Name:' + i + ':' + AudioRendererChangeInfo.deviceDescriptors[j].name);
        console.info('Address:' + i + ':' + AudioRendererChangeInfo.deviceDescriptors[j].address);
        console.info('SampleRates:' + i + ':' + AudioRendererChangeInfo.deviceDescriptors[j].sampleRates[0]);
        console.info('ChannelCounts' + i + ':' + AudioRendererChangeInfo.deviceDescriptors[j].channelCounts[0]);
        console.info('ChannnelMask:' + i + ':' + AudioRendererChangeInfo.deviceDescriptors[j].channelMasks);
      }
    }
  }
}).catch((err) => {
  console.log('getCurrentAudioRendererInfoArray :ERROR: ' + err.message);
});
   ``` 

7. (可选)使用getCurrentAudioCapturerInfoArray()获取当前音频捕获器的信息。
该接口可获取音频流唯一ID,音频录制客户端的UID,音频状态以及音频捕获器的其他信息。需注意的是若对第三方音频流监听应用未配置相关权限,则查询到的音频状态为0,音频捕获器其他信息为null。
   ```js
await audioStreamManager.getCurrentAudioCapturerInfoArray().then( function (AudioCapturerChangeInfoArray) {
  console.info('AFCapturerChangeLog: [GET_CAP_STA_1_PR] **** Get Promise Called ****');
  if (AudioCapturerChangeInfoArray != null) {
    for (let i = 0; i < AudioCapturerChangeInfoArray.length; i++) {
      console.info('StreamId for ' + i + 'is:' + AudioCapturerChangeInfoArray[i].streamId);
      console.info('ClientUid for ' + i + 'is:' + AudioCapturerChangeInfoArray[i].clientUid);
      console.info('Source for ' + i + 'is:' + AudioCapturerChangeInfoArray[i].capturerInfo.source);
      console.info('Flag ' + i + 'is:' + AudioCapturerChangeInfoArray[i].capturerInfo.capturerFlags);
      console.info('State for ' + i + 'is:' + AudioCapturerChangeInfoArray[i].capturerState);  
      var devDescriptor = AudioCapturerChangeInfoArray[i].deviceDescriptors;
      for (let j = 0; j < AudioCapturerChangeInfoArray[i].deviceDescriptors.length; j++) {
        console.info('Id:' + i + ':' + AudioCapturerChangeInfoArray[i].deviceDescriptors[j].id);
        console.info('Type:' + i + ':' + AudioCapturerChangeInfoArray[i].deviceDescriptors[j].deviceType);
        console.info('Role:' + i + ':' + AudioCapturerChangeInfoArray[i].deviceDescriptors[j].deviceRole);
        console.info('Name:' + i + ':' + AudioCapturerChangeInfoArray[i].deviceDescriptors[j].name)
        console.info('Address:' + i + ':' + AudioCapturerChangeInfoArray[i].deviceDescriptors[j].address);
        console.info('SampleRates:' + i + ':' + AudioCapturerChangeInfoArray[i].deviceDescriptors[j].sampleRates[0]);
        console.info('ChannelCounts' + i + ':' + AudioCapturerChangeInfoArray[i].deviceDescriptors[j].channelCounts[0]);
        console.info('ChannelMask:' + i + ':' + AudioCapturerChangeInfoArray[i].deviceDescriptors[j].channelMasks);
      }
    }
  }
}).catch((err) => {
  console.log('getCurrentAudioCapturerInfoArray :ERROR: ' + err.message);
});
   ```