ex

Fork of mbed-os-example-mbed5-blinky by mbed-os-examples

Committer:
TMBOY
Date:
Tue Jul 18 16:27:22 2017 +0800
Revision:
44:c1d8923072ba
?

Who changed what in which revision?

UserRevisionLine numberNew contents of line
TMBOY 44:c1d8923072ba 1 # AudioPlayer
TMBOY 44:c1d8923072ba 2
TMBOY 44:c1d8923072ba 3 ## Table of Contents
TMBOY 44:c1d8923072ba 4
TMBOY 44:c1d8923072ba 5
TMBOY 44:c1d8923072ba 6 * [AudioPlayer](#audioplayer)
TMBOY 44:c1d8923072ba 7 * [Table of Contents](#table-of-contents)
TMBOY 44:c1d8923072ba 8 * [AudioPlayer.Play指令](#audioplayerplay指令)
TMBOY 44:c1d8923072ba 9 * [AudioPlayer.Stop指令](#audioplayerstop指令)
TMBOY 44:c1d8923072ba 10 * [PlaybackStarted事件](#playbackstarted事件)
TMBOY 44:c1d8923072ba 11 * [PlaybackStopped事件](#playbackstopped事件)
TMBOY 44:c1d8923072ba 12 * [PlaybackNearlyFinished事件](#playbacknearlyfinished事件)
TMBOY 44:c1d8923072ba 13 * [PlaybackFinished事件](#playbackfinished事件)
TMBOY 44:c1d8923072ba 14 * [ProgressReportIntervalElapsed事件](#progressreportintervalelapsed事件)
TMBOY 44:c1d8923072ba 15 * [上报AudioPlayer状态(在请求中)](#上报audioplayer状态在请求中)
TMBOY 44:c1d8923072ba 16 * [有屏设备接入音乐、有声等音频服务](#有屏设备接入音乐有声等音频服务)
TMBOY 44:c1d8923072ba 17 * [FAQ](#faq)
TMBOY 44:c1d8923072ba 18 * [Changelog](#changelog)
TMBOY 44:c1d8923072ba 19
TMBOY 44:c1d8923072ba 20
TMBOY 44:c1d8923072ba 21 ## AudioPlayer.Play指令
TMBOY 44:c1d8923072ba 22 用户对音箱说“播放周杰伦的歌曲”、“播放郭德纲的相声”、"继续播放"、“下一首”、“上一首”、“下一个专辑”、“上一个专辑”都返回一个Play指令。
TMBOY 44:c1d8923072ba 23 ```json
TMBOY 44:c1d8923072ba 24 {
TMBOY 44:c1d8923072ba 25 "header": {
TMBOY 44:c1d8923072ba 26 "namespace": "AudioPlayer",
TMBOY 44:c1d8923072ba 27 "name": "Play",
TMBOY 44:c1d8923072ba 28 "message_id": "message_id-1344"
TMBOY 44:c1d8923072ba 29 },
TMBOY 44:c1d8923072ba 30 "payload": {
TMBOY 44:c1d8923072ba 31 "play_behavior": "REPLACE_ALL",
TMBOY 44:c1d8923072ba 32 "audio_item": {
TMBOY 44:c1d8923072ba 33 "audio_item_id": "156",
TMBOY 44:c1d8923072ba 34 "stream": {
TMBOY 44:c1d8923072ba 35 "url": "http://yinyueshiting.baidu.com/data2/music/124088643/124088643.mp3?xcode=57462f29cfc176f86a37d80a2c02fc5b",
TMBOY 44:c1d8923072ba 36 "stream_format": "AUDIO_MP3",
TMBOY 44:c1d8923072ba 37 "offset_ms": 0,
TMBOY 44:c1d8923072ba 38 "token": "156",
TMBOY 44:c1d8923072ba 39 "progress_report_interval_ms": 1000
TMBOY 44:c1d8923072ba 40 }
TMBOY 44:c1d8923072ba 41 }
TMBOY 44:c1d8923072ba 42 }
TMBOY 44:c1d8923072ba 43 }
TMBOY 44:c1d8923072ba 44 ```
TMBOY 44:c1d8923072ba 45 参数 | 描述 | 类型 | 必须
TMBOY 44:c1d8923072ba 46 ---- | --- | --- | ---
TMBOY 44:c1d8923072ba 47 play_behavior | REPLACE_ALL:清空播放列表,立即播放指令关联的音频。"播放周杰伦的歌曲"、"播放郭德纲的相声"、"下一首"、"上一首",使用它。ENQUEUE:把指令关联的音频添加到播放列表末尾,当前播放的音频不受影响.下一首预取的时候试用它。REPLACE_ENQUEUED:清空播放列表,同时把指令关联的音频加到播放列表,但当前播放的歌曲不受影响。"这首歌播放完后播放周杰伦的歌曲",使用它;用户说“单曲循环、列表循环、随机播放”的时候,也使用它。| string | 是
TMBOY 44:c1d8923072ba 48 audio_item | 音频对象,包括音频流和元数据 | object | 是
TMBOY 44:c1d8923072ba 49 audio_item.audio_item_id | 音频ID | string | 是
TMBOY 44:c1d8923072ba 50 audio_item.stream | 音频流对象 | object | 是
TMBOY 44:c1d8923072ba 51 audio_item.stream.url | 音频流url | string | 是
TMBOY 44:c1d8923072ba 52 audio_item.stream.stream_format | 音频流格式: AUDIO_MP3、AUDIO_M3U8、AUDIO_M4A | string | 是
TMBOY 44:c1d8923072ba 53 audio_item.stream.offset_ms | 客户端从哪里开始播放音频,如果值等于0,从开头播放。 | long | 是
TMBOY 44:c1d8923072ba 54 audio_item.stream.token | 同音频ID | string | 是
TMBOY 44:c1d8923072ba 55 audio_item.stream.progress_report_interval_ms |客户端每隔多长时间上报一次进度,这个取值必须大于0,如果没有这个字段,则不上报进度 | long | 否
TMBOY 44:c1d8923072ba 56
TMBOY 44:c1d8923072ba 57 ## AudioPlayer.Stop指令
TMBOY 44:c1d8923072ba 58 ```json
TMBOY 44:c1d8923072ba 59 {
TMBOY 44:c1d8923072ba 60 "header": {
TMBOY 44:c1d8923072ba 61 "namespace": "AudioPlayer",
TMBOY 44:c1d8923072ba 62 "name": "Stop",
TMBOY 44:c1d8923072ba 63 "message_id": "message_id-1344"
TMBOY 44:c1d8923072ba 64 },
TMBOY 44:c1d8923072ba 65 "payload": {
TMBOY 44:c1d8923072ba 66 }
TMBOY 44:c1d8923072ba 67 }
TMBOY 44:c1d8923072ba 68 ```
TMBOY 44:c1d8923072ba 69
TMBOY 44:c1d8923072ba 70 ## PlaybackStarted事件
TMBOY 44:c1d8923072ba 71 客户端开始播放的时候,需要上报此事件。
TMBOY 44:c1d8923072ba 72 ```json
TMBOY 44:c1d8923072ba 73 {
TMBOY 44:c1d8923072ba 74 "device_event": {
TMBOY 44:c1d8923072ba 75 "header": {
TMBOY 44:c1d8923072ba 76 "namespace": "AudioPlayer",
TMBOY 44:c1d8923072ba 77 "name": "PlaybackStarted",
TMBOY 44:c1d8923072ba 78 "message_id": "message_id-1344"
TMBOY 44:c1d8923072ba 79 },
TMBOY 44:c1d8923072ba 80 "payload": {
TMBOY 44:c1d8923072ba 81 "token": "156",
TMBOY 44:c1d8923072ba 82 "offset_ms": 10000
TMBOY 44:c1d8923072ba 83 }
TMBOY 44:c1d8923072ba 84 }
TMBOY 44:c1d8923072ba 85 }
TMBOY 44:c1d8923072ba 86 ```
TMBOY 44:c1d8923072ba 87 ## PlaybackStopped事件
TMBOY 44:c1d8923072ba 88 用户说"暂停播放"、 "停止播放"后,会收到Stop指令,客户端执行完Stop指令后,即暂停播放后,需要上报此事件,云端会保存断点,供下一次继续播放使用。
TMBOY 44:c1d8923072ba 89 ```json
TMBOY 44:c1d8923072ba 90 {
TMBOY 44:c1d8923072ba 91 "device_event": {
TMBOY 44:c1d8923072ba 92 "header": {
TMBOY 44:c1d8923072ba 93 "namespace": "AudioPlayer",
TMBOY 44:c1d8923072ba 94 "name": "PlaybackStopped",
TMBOY 44:c1d8923072ba 95 "message_id": "message_id-1344"
TMBOY 44:c1d8923072ba 96 },
TMBOY 44:c1d8923072ba 97 "payload": {
TMBOY 44:c1d8923072ba 98 "token": "156",
TMBOY 44:c1d8923072ba 99 "offset_ms": 10000
TMBOY 44:c1d8923072ba 100 }
TMBOY 44:c1d8923072ba 101 }
TMBOY 44:c1d8923072ba 102 }
TMBOY 44:c1d8923072ba 103 ```
TMBOY 44:c1d8923072ba 104 ## PlaybackNearlyFinished事件
TMBOY 44:c1d8923072ba 105 这个事件用来获取下一首歌曲,云端收到这个事件后,返回下一首歌曲对应的Play指令,play_behavior选项设为ENQUEUE,
TMBOY 44:c1d8923072ba 106 指示客户端加入到本地列表中,利用此事件,客户端可以实现下一首的预取。这个事件的上报时机取决于客户端,
TMBOY 44:c1d8923072ba 107 可以在歌曲播放的中间发送,也可以剩余几秒钟的时候发送。如果不需要预取,也可以在歌曲播放完毕后上报此事件。但必须保证:
TMBOY 44:c1d8923072ba 108
TMBOY 44:c1d8923072ba 109 1 PlaybackNearlyFinished必须在PlaybackStarted事件发送完毕后才上报。
TMBOY 44:c1d8923072ba 110
TMBOY 44:c1d8923072ba 111 2 一首歌曲只发送一次PlaybackNearlyFinished事件。
TMBOY 44:c1d8923072ba 112
TMBOY 44:c1d8923072ba 113 ```json
TMBOY 44:c1d8923072ba 114 {
TMBOY 44:c1d8923072ba 115 "device_event": {
TMBOY 44:c1d8923072ba 116 "header": {
TMBOY 44:c1d8923072ba 117 "namespace": "AudioPlayer",
TMBOY 44:c1d8923072ba 118 "name": "PlaybackNearlyFinished",
TMBOY 44:c1d8923072ba 119 "message_id": "message_id-1344"
TMBOY 44:c1d8923072ba 120 },
TMBOY 44:c1d8923072ba 121 "payload": {
TMBOY 44:c1d8923072ba 122 "token": "156",
TMBOY 44:c1d8923072ba 123 "offset_ms": 10000
TMBOY 44:c1d8923072ba 124 }
TMBOY 44:c1d8923072ba 125 }
TMBOY 44:c1d8923072ba 126 }
TMBOY 44:c1d8923072ba 127 ```
TMBOY 44:c1d8923072ba 128 ## PlaybackFinished事件
TMBOY 44:c1d8923072ba 129 当且仅当歌曲正常播放到末尾后,上报此事件。注意如果被其它指令打断比如“下一首”、“上一首”导致没有播放到末尾的,不上报此事件。
TMBOY 44:c1d8923072ba 130 ```json
TMBOY 44:c1d8923072ba 131 {
TMBOY 44:c1d8923072ba 132 "device_event": {
TMBOY 44:c1d8923072ba 133 "header": {
TMBOY 44:c1d8923072ba 134 "namespace": "AudioPlayer",
TMBOY 44:c1d8923072ba 135 "name": "PlaybackFinished",
TMBOY 44:c1d8923072ba 136 "message_id": "message_id-1344"
TMBOY 44:c1d8923072ba 137 },
TMBOY 44:c1d8923072ba 138 "payload": {
TMBOY 44:c1d8923072ba 139 "token": "156",
TMBOY 44:c1d8923072ba 140 "offset_ms": 10000
TMBOY 44:c1d8923072ba 141 }
TMBOY 44:c1d8923072ba 142 }
TMBOY 44:c1d8923072ba 143 }
TMBOY 44:c1d8923072ba 144 ```
TMBOY 44:c1d8923072ba 145 ## ProgressReportIntervalElapsed事件
TMBOY 44:c1d8923072ba 146 如果Play指令设置了progress_report_interval_ms的值,那么客户端需要周期性的每隔一段时间上报一次当前的播放进度,
TMBOY 44:c1d8923072ba 147 直到歌曲播放结束。注意歌曲开始播放和歌曲结束播放的时候,可以不上报这个事件。
TMBOY 44:c1d8923072ba 148
TMBOY 44:c1d8923072ba 149 情况1:假如progress_report_interval_ms的值为3000,Play指令的offset_ms值为0, 从音频流的0位置算起,如果播放位置到达3000的整数倍,就上报一次事件。
TMBOY 44:c1d8923072ba 150
TMBOY 44:c1d8923072ba 151 情况2:假如progress_report_interval_ms的值为3000,Play指令的offset_ms值为1000, 从音频流的0位置算起,如果播放位置到达3000的整数倍,就上报一次事件。
TMBOY 44:c1d8923072ba 152
TMBOY 44:c1d8923072ba 153 这2种情况,上报事件时所处的播放位置是一样的,跟offset_ms的值没有关系,因为是从音频流的0位置算起。
TMBOY 44:c1d8923072ba 154 云端收到这个事件后,可能会返回给客户端一条指令,需要客户端执行之,比如Stop指令、AdjustVolume指令等。利用这个特性可以实现助眠模式。
TMBOY 44:c1d8923072ba 155
TMBOY 44:c1d8923072ba 156
TMBOY 44:c1d8923072ba 157 ## 上报AudioPlayer状态(在请求中)
TMBOY 44:c1d8923072ba 158
TMBOY 44:c1d8923072ba 159 ```javascript
TMBOY 44:c1d8923072ba 160 "device_status":{
TMBOY 44:c1d8923072ba 161 "AudioPlayer":{
TMBOY 44:c1d8923072ba 162 "token":"xxx",//正在播放的音频流id
TMBOY 44:c1d8923072ba 163 "offset_ms":20000,//播放到多少ms了
TMBOY 44:c1d8923072ba 164 "player_activity":"IDLE PAUSED PLAYING BUFFER_UNDERRUN FINISHED STOPPED"
TMBOY 44:c1d8923072ba 165 },
TMBOY 44:c1d8923072ba 166 },
TMBOY 44:c1d8923072ba 167 ```
TMBOY 44:c1d8923072ba 168
TMBOY 44:c1d8923072ba 169 ## 有屏设备接入音乐、有声等音频服务
TMBOY 44:c1d8923072ba 170 Directive和Event机制非常适合无屏设备使用,对于有屏设备,
TMBOY 44:c1d8923072ba 171 也推荐使用Directive和Event机制接入音频服务,端和云之间的交互的性能和流畅性会更好,带来更好的用户体验。
TMBOY 44:c1d8923072ba 172 但是如果厂商认为接入Directive和Event开发成本高,需要快速出产品效果,也可以通过NLU+Resource的方式接入音频服务,具体流程如下:
TMBOY 44:c1d8923072ba 173
TMBOY 44:c1d8923072ba 174 1. 用户语音说“”播放周杰伦的歌曲”,发起第一次网络请求,DuerOS云端除了返回Play指令外,还会返回resource,里面有一个api
TMBOY 44:c1d8923072ba 175 url,用于从云端获取播放列表,端上发起第二次网络请求获取播放列表在屏幕展现,然后端上拿到列表中第一首歌曲的ID,向度秘云端
TMBOY 44:c1d8923072ba 176 发起第三次网络请求,拿到第一首歌曲的MP3
TMBOY 44:c1d8923072ba 177 URL,开始音频的播放。这里需要三次网络请求才能实现歌曲的播放,链路长,性能不好,如果为了更快的播放,端上可以选择第一次网络请求后,从Play指令中提取MP3
TMBOY 44:c1d8923072ba 178 URL,直接开始第一首歌曲的播放,不用等到第二次和第三次网络请求之后就能播放歌曲了。
TMBOY 44:c1d8923072ba 179
TMBOY 44:c1d8923072ba 180 2. 用户在屏幕GUI上点击一首歌曲的播放,端上发起一次网络请求,根据歌曲ID拿到MP3 URL,开始播放用户点击的歌曲。
TMBOY 44:c1d8923072ba 181
TMBOY 44:c1d8923072ba 182 3. 用户语音说"下一首",发起第一次网络请求,DuerOS云端返回NLU结果,客户端判断NLU结果为换一首,然后本地取得下一首歌曲的歌曲ID,发起第二次网络请求,拿到MP3 URL,开始下一首歌曲的播放。
TMBOY 44:c1d8923072ba 183 其它播放控制也类似,DuerOS NLU支持的播放控制,可以参考[音乐](../bot/audio_music.md) 、[点播](../bot/audio_unicast.md)、[直播](../bot/audio_live.md)。
TMBOY 44:c1d8923072ba 184
TMBOY 44:c1d8923072ba 185 4. 用户语音说“换一批”,发起第一次网络请求,DuerOS云端返回NLU结果,客户端判断NLU结果为换一批,发起第二次网络请求,获取下一页的歌曲列表,将列表中第一首歌曲的ID,发起第三次网络请求,拿到MP3
TMBOY 44:c1d8923072ba 186 URL,开始下一批歌曲的播放。
TMBOY 44:c1d8923072ba 187
TMBOY 44:c1d8923072ba 188 5. 用户在频幕GUI上的上滑翻页操作,请求播放列表的接口,拿到下一页的歌曲列表,追加到GUI的播放列表中。
TMBOY 44:c1d8923072ba 189
TMBOY 44:c1d8923072ba 190 ## FAQ
TMBOY 44:c1d8923072ba 191 * 如何实现暂停、继续
TMBOY 44:c1d8923072ba 192
TMBOY 44:c1d8923072ba 193 暂停和继续只需要实现Play和Stop两个指令,语音说“暂停”,云端返回Stop指令,客户端收到指令后执行暂停,同时立马上报一个PlaybackStopped的事件,
TMBOY 44:c1d8923072ba 194 云端收到事件后把断点位置offset_ms保存下来,接下来语音说“继续”,云端返回Play指令,offset_ms的值为上一次说暂停时上报的位置,客户端收到Play指令后,
TMBOY 44:c1d8923072ba 195 从offset_ms的位置开始播放,从而实现继续播放的功能。
TMBOY 44:c1d8923072ba 196
TMBOY 44:c1d8923072ba 197 * 如何实现循环模式(列表循环、随机播放、单曲循环)
TMBOY 44:c1d8923072ba 198
TMBOY 44:c1d8923072ba 199 循环模式的逻辑由云端实现,客户端不需要实现循环模式的逻辑,客户端只需要维持本地的播放列表,一首一首的播放,以及实现Play指令的play_behavior的REPLACE_ENQUEUED模式,例如单曲循环的实现:
TMBOY 44:c1d8923072ba 200 当前正在播放的音频id为156,语音说“单曲循环”,云端会把播放模式切换为单曲循环,同时返回一个Play指令
TMBOY 44:c1d8923072ba 201 ```json
TMBOY 44:c1d8923072ba 202 {
TMBOY 44:c1d8923072ba 203 "header": {
TMBOY 44:c1d8923072ba 204 "namespace": "AudioPlayer",
TMBOY 44:c1d8923072ba 205 "name": "Play",
TMBOY 44:c1d8923072ba 206 "message_id": "message_id-1344"
TMBOY 44:c1d8923072ba 207 },
TMBOY 44:c1d8923072ba 208 "payload": {
TMBOY 44:c1d8923072ba 209 "play_behavior": "REPLACE_ENQUEUED",
TMBOY 44:c1d8923072ba 210 "audio_item": {
TMBOY 44:c1d8923072ba 211 "audio_item_id": "156",
TMBOY 44:c1d8923072ba 212 "stream": {
TMBOY 44:c1d8923072ba 213 "url": "http://yinyueshiting.baidu.com/data2/music/124088643/124088643.mp3?xcode=57462f29cfc176f86a37d80a2c02fc5b",
TMBOY 44:c1d8923072ba 214 "stream_format": "AUDIO_MP3",
TMBOY 44:c1d8923072ba 215 "offset_ms": 0,
TMBOY 44:c1d8923072ba 216 "token": "156",
TMBOY 44:c1d8923072ba 217 "progress_report_interval_ms": 1000
TMBOY 44:c1d8923072ba 218 }
TMBOY 44:c1d8923072ba 219 }
TMBOY 44:c1d8923072ba 220 }
TMBOY 44:c1d8923072ba 221 }
TMBOY 44:c1d8923072ba 222 ```
TMBOY 44:c1d8923072ba 223 Play指令的play_behavior为REPLACE_ENQUEUED,客户端清空本地之前预取保存的播放列表,同时把音频id为156的歌曲加入到播放列表,当前播放的歌曲不受
TMBOY 44:c1d8923072ba 224 影响,继续播放直到结束,结束后开始播放本地播放列表中的下一首歌曲,即音频id为156的歌曲。这里重点是要清空本地的播放列表,否则下一首歌曲可能不会符合预期。播放到一定位置后,客户端上报PlaybackNearlyFinished事件
TMBOY 44:c1d8923072ba 225 实现预取,云端返回的音频id依然为156,播放模式为ENQUEUED。
TMBOY 44:c1d8923072ba 226 ```json
TMBOY 44:c1d8923072ba 227 {
TMBOY 44:c1d8923072ba 228 "header": {
TMBOY 44:c1d8923072ba 229 "namespace": "AudioPlayer",
TMBOY 44:c1d8923072ba 230 "name": "Play",
TMBOY 44:c1d8923072ba 231 "message_id": "message_id-1344"
TMBOY 44:c1d8923072ba 232 },
TMBOY 44:c1d8923072ba 233 "payload": {
TMBOY 44:c1d8923072ba 234 "play_behavior": "ENQUEUED",
TMBOY 44:c1d8923072ba 235 "audio_item": {
TMBOY 44:c1d8923072ba 236 "audio_item_id": "156",
TMBOY 44:c1d8923072ba 237 "stream": {
TMBOY 44:c1d8923072ba 238 "url": "http://yinyueshiting.baidu.com/data2/music/124088643/124088643.mp3?xcode=57462f29cfc176f86a37d80a2c02fc5b",
TMBOY 44:c1d8923072ba 239 "stream_format": "AUDIO_MP3",
TMBOY 44:c1d8923072ba 240 "offset_ms": 0,
TMBOY 44:c1d8923072ba 241 "token": "156",
TMBOY 44:c1d8923072ba 242 "progress_report_interval_ms": 1000
TMBOY 44:c1d8923072ba 243 }
TMBOY 44:c1d8923072ba 244 }
TMBOY 44:c1d8923072ba 245 }
TMBOY 44:c1d8923072ba 246 }
TMBOY 44:c1d8923072ba 247 ```
TMBOY 44:c1d8923072ba 248 下一次预取依然返回相同的Play指令,依此类推,这样就实现了单曲循环的功能。
TMBOY 44:c1d8923072ba 249
TMBOY 44:c1d8923072ba 250 ## Changelog
TMBOY 44:c1d8923072ba 251 * 2017-4-10 修改有屏设备接入的说明;增加FAQ。