ex
Fork of mbed-os-example-mbed5-blinky by
dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/audioplayer/AudioPlayerDeviceModule.java@45:2aa9f933c8d2, 2017-07-18 (annotated)
- Committer:
- TMBOY
- Date:
- Tue Jul 18 16:34:48 2017 +0800
- Revision:
- 45:2aa9f933c8d2
?
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| TMBOY | 45:2aa9f933c8d2 | 1 | /* |
| TMBOY | 45:2aa9f933c8d2 | 2 | * Copyright (c) 2017 Baidu, Inc. All Rights Reserved. |
| TMBOY | 45:2aa9f933c8d2 | 3 | * |
| TMBOY | 45:2aa9f933c8d2 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| TMBOY | 45:2aa9f933c8d2 | 5 | * you may not use this file except in compliance with the License. |
| TMBOY | 45:2aa9f933c8d2 | 6 | * You may obtain a copy of the License at |
| TMBOY | 45:2aa9f933c8d2 | 7 | * |
| TMBOY | 45:2aa9f933c8d2 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| TMBOY | 45:2aa9f933c8d2 | 9 | * |
| TMBOY | 45:2aa9f933c8d2 | 10 | * Unless required by applicable law or agreed to in writing, software |
| TMBOY | 45:2aa9f933c8d2 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| TMBOY | 45:2aa9f933c8d2 | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| TMBOY | 45:2aa9f933c8d2 | 13 | * See the License for the specific language governing permissions and |
| TMBOY | 45:2aa9f933c8d2 | 14 | * limitations under the License. |
| TMBOY | 45:2aa9f933c8d2 | 15 | */ |
| TMBOY | 45:2aa9f933c8d2 | 16 | package com.baidu.duer.dcs.devicemodule.audioplayer; |
| TMBOY | 45:2aa9f933c8d2 | 17 | |
| TMBOY | 45:2aa9f933c8d2 | 18 | import com.baidu.duer.dcs.devicemodule.audioplayer.message.ClearQueuePayload; |
| TMBOY | 45:2aa9f933c8d2 | 19 | import com.baidu.duer.dcs.devicemodule.audioplayer.message.PlayPayload; |
| TMBOY | 45:2aa9f933c8d2 | 20 | import com.baidu.duer.dcs.devicemodule.audioplayer.message.PlaybackStatePayload; |
| TMBOY | 45:2aa9f933c8d2 | 21 | import com.baidu.duer.dcs.devicemodule.audioplayer.message.StopPayload; |
| TMBOY | 45:2aa9f933c8d2 | 22 | import com.baidu.duer.dcs.devicemodule.audioplayer.report.AudioPlayStateReport; |
| TMBOY | 45:2aa9f933c8d2 | 23 | import com.baidu.duer.dcs.devicemodule.audioplayer.report.AudioPlayerProgressReporter; |
| TMBOY | 45:2aa9f933c8d2 | 24 | import com.baidu.duer.dcs.devicemodule.audioplayer.report.AudioPlayerTimer; |
| TMBOY | 45:2aa9f933c8d2 | 25 | import com.baidu.duer.dcs.devicemodule.system.HandleDirectiveException; |
| TMBOY | 45:2aa9f933c8d2 | 26 | import com.baidu.duer.dcs.framework.BaseDeviceModule; |
| TMBOY | 45:2aa9f933c8d2 | 27 | import com.baidu.duer.dcs.framework.IMessageSender; |
| TMBOY | 45:2aa9f933c8d2 | 28 | import com.baidu.duer.dcs.framework.message.ClientContext; |
| TMBOY | 45:2aa9f933c8d2 | 29 | import com.baidu.duer.dcs.framework.message.Directive; |
| TMBOY | 45:2aa9f933c8d2 | 30 | import com.baidu.duer.dcs.framework.message.Header; |
| TMBOY | 45:2aa9f933c8d2 | 31 | import com.baidu.duer.dcs.systeminterface.IMediaPlayer; |
| TMBOY | 45:2aa9f933c8d2 | 32 | import com.baidu.duer.dcs.util.LogUtil; |
| TMBOY | 45:2aa9f933c8d2 | 33 | |
| TMBOY | 45:2aa9f933c8d2 | 34 | import java.util.ArrayList; |
| TMBOY | 45:2aa9f933c8d2 | 35 | import java.util.Collections; |
| TMBOY | 45:2aa9f933c8d2 | 36 | import java.util.LinkedList; |
| TMBOY | 45:2aa9f933c8d2 | 37 | import java.util.List; |
| TMBOY | 45:2aa9f933c8d2 | 38 | |
| TMBOY | 45:2aa9f933c8d2 | 39 | /** |
| TMBOY | 45:2aa9f933c8d2 | 40 | * 音乐播放的端能力实现,处理指令:Play,Stop,ClearQueue |
| TMBOY | 45:2aa9f933c8d2 | 41 | * <p> |
| TMBOY | 45:2aa9f933c8d2 | 42 | * Created by guxiuzhong@baidu.com on 2017/5/31. |
| TMBOY | 45:2aa9f933c8d2 | 43 | */ |
| TMBOY | 45:2aa9f933c8d2 | 44 | public class AudioPlayerDeviceModule extends BaseDeviceModule { |
| TMBOY | 45:2aa9f933c8d2 | 45 | private static final String TAG = AudioPlayerDeviceModule.class.getSimpleName(); |
| TMBOY | 45:2aa9f933c8d2 | 46 | // 播放列表,先进先出 |
| TMBOY | 45:2aa9f933c8d2 | 47 | private LinkedList<PlayPayload.Stream> playQueue = new LinkedList<>(); |
| TMBOY | 45:2aa9f933c8d2 | 48 | // 当前stream的token |
| TMBOY | 45:2aa9f933c8d2 | 49 | private String latestStreamToken = ""; |
| TMBOY | 45:2aa9f933c8d2 | 50 | // 当前manager的播放器 |
| TMBOY | 45:2aa9f933c8d2 | 51 | private IMediaPlayer mediaPlayer; |
| TMBOY | 45:2aa9f933c8d2 | 52 | // 播放上报 |
| TMBOY | 45:2aa9f933c8d2 | 53 | private AudioPlayStateReport audioPlayStateReport; |
| TMBOY | 45:2aa9f933c8d2 | 54 | // 开始时的缓冲时间 |
| TMBOY | 45:2aa9f933c8d2 | 55 | private long bufferingStartMilliseconds; |
| TMBOY | 45:2aa9f933c8d2 | 56 | // 结束时的缓冲时间 |
| TMBOY | 45:2aa9f933c8d2 | 57 | private long bufferingEndMilliseconds; |
| TMBOY | 45:2aa9f933c8d2 | 58 | // 用来统计状态的时间间隔offsetInMilliseconds |
| TMBOY | 45:2aa9f933c8d2 | 59 | private AudioPlayerTimer timer; |
| TMBOY | 45:2aa9f933c8d2 | 60 | // 播放状态的上报eg:暂停,完成等 |
| TMBOY | 45:2aa9f933c8d2 | 61 | private AudioPlayerProgressReporter progressReporter; |
| TMBOY | 45:2aa9f933c8d2 | 62 | // 回调接口 |
| TMBOY | 45:2aa9f933c8d2 | 63 | private List<IMediaPlayer.IMediaPlayerListener> audioPlayerListeners; |
| TMBOY | 45:2aa9f933c8d2 | 64 | |
| TMBOY | 45:2aa9f933c8d2 | 65 | public AudioPlayerDeviceModule(IMediaPlayer mediaPlayer, |
| TMBOY | 45:2aa9f933c8d2 | 66 | IMessageSender messageSender) { |
| TMBOY | 45:2aa9f933c8d2 | 67 | super(ApiConstants.NAMESPACE, messageSender); |
| TMBOY | 45:2aa9f933c8d2 | 68 | this.mediaPlayer = mediaPlayer; |
| TMBOY | 45:2aa9f933c8d2 | 69 | this.mediaPlayer.addMediaPlayerListener(mediaPlayerListener); |
| TMBOY | 45:2aa9f933c8d2 | 70 | this.audioPlayStateReport = new AudioPlayStateReport(getNameSpace(), |
| TMBOY | 45:2aa9f933c8d2 | 71 | messageSender, |
| TMBOY | 45:2aa9f933c8d2 | 72 | audioPlayStateReportListener); |
| TMBOY | 45:2aa9f933c8d2 | 73 | this.timer = new AudioPlayerTimer(); |
| TMBOY | 45:2aa9f933c8d2 | 74 | this.progressReporter = new AudioPlayerProgressReporter( |
| TMBOY | 45:2aa9f933c8d2 | 75 | new ProgressReportDelayEventRunnable(audioPlayStateReport), |
| TMBOY | 45:2aa9f933c8d2 | 76 | new ProgressReportIntervalEventRunnable(audioPlayStateReport), timer); |
| TMBOY | 45:2aa9f933c8d2 | 77 | this.audioPlayerListeners = Collections.synchronizedList( |
| TMBOY | 45:2aa9f933c8d2 | 78 | new ArrayList<IMediaPlayer.IMediaPlayerListener>()); |
| TMBOY | 45:2aa9f933c8d2 | 79 | } |
| TMBOY | 45:2aa9f933c8d2 | 80 | |
| TMBOY | 45:2aa9f933c8d2 | 81 | @Override |
| TMBOY | 45:2aa9f933c8d2 | 82 | public ClientContext clientContext() { |
| TMBOY | 45:2aa9f933c8d2 | 83 | String namespace = ApiConstants.NAMESPACE; |
| TMBOY | 45:2aa9f933c8d2 | 84 | String name = ApiConstants.Events.PlaybackState.NAME; |
| TMBOY | 45:2aa9f933c8d2 | 85 | Header header = new Header(namespace, name); |
| TMBOY | 45:2aa9f933c8d2 | 86 | PlaybackStatePayload payload = new PlaybackStatePayload(latestStreamToken, |
| TMBOY | 45:2aa9f933c8d2 | 87 | mediaPlayer.getCurrentPosition(), |
| TMBOY | 45:2aa9f933c8d2 | 88 | audioPlayStateReport.getState().name()); |
| TMBOY | 45:2aa9f933c8d2 | 89 | return new ClientContext(header, payload); |
| TMBOY | 45:2aa9f933c8d2 | 90 | } |
| TMBOY | 45:2aa9f933c8d2 | 91 | |
| TMBOY | 45:2aa9f933c8d2 | 92 | @Override |
| TMBOY | 45:2aa9f933c8d2 | 93 | public void handleDirective(Directive directive) throws HandleDirectiveException { |
| TMBOY | 45:2aa9f933c8d2 | 94 | LogUtil.d(TAG, "dcs-play-directive:" + directive.rawMessage); |
| TMBOY | 45:2aa9f933c8d2 | 95 | String directiveName = directive.getName(); |
| TMBOY | 45:2aa9f933c8d2 | 96 | LogUtil.d(TAG, "dcs-play-directiveName:" + directiveName); |
| TMBOY | 45:2aa9f933c8d2 | 97 | if (ApiConstants.Directives.Play.NAME.equals(directiveName)) { |
| TMBOY | 45:2aa9f933c8d2 | 98 | handlePlay((PlayPayload) directive.getPayload()); |
| TMBOY | 45:2aa9f933c8d2 | 99 | } else if (ApiConstants.Directives.Stop.NAME.equals(directiveName)) { |
| TMBOY | 45:2aa9f933c8d2 | 100 | handleStop((StopPayload) directive.getPayload()); |
| TMBOY | 45:2aa9f933c8d2 | 101 | } else if (ApiConstants.Directives.ClearQueue.NAME.equals(directiveName)) { |
| TMBOY | 45:2aa9f933c8d2 | 102 | handleClearQueue((ClearQueuePayload) directive.getPayload()); |
| TMBOY | 45:2aa9f933c8d2 | 103 | } else { |
| TMBOY | 45:2aa9f933c8d2 | 104 | String message = "audioPlayer cannot handle the directive"; |
| TMBOY | 45:2aa9f933c8d2 | 105 | throw (new HandleDirectiveException( |
| TMBOY | 45:2aa9f933c8d2 | 106 | HandleDirectiveException.ExceptionType.UNSUPPORTED_OPERATION, message)); |
| TMBOY | 45:2aa9f933c8d2 | 107 | } |
| TMBOY | 45:2aa9f933c8d2 | 108 | } |
| TMBOY | 45:2aa9f933c8d2 | 109 | |
| TMBOY | 45:2aa9f933c8d2 | 110 | /** |
| TMBOY | 45:2aa9f933c8d2 | 111 | * 处理播放指令(Play) |
| TMBOY | 45:2aa9f933c8d2 | 112 | * |
| TMBOY | 45:2aa9f933c8d2 | 113 | * @param payload payload |
| TMBOY | 45:2aa9f933c8d2 | 114 | */ |
| TMBOY | 45:2aa9f933c8d2 | 115 | private void handlePlay(PlayPayload payload) { |
| TMBOY | 45:2aa9f933c8d2 | 116 | PlayPayload.AudioItem item = payload.audioItem; |
| TMBOY | 45:2aa9f933c8d2 | 117 | if (payload.playBehavior == PlayPayload.PlayBehavior.REPLACE_ALL) { |
| TMBOY | 45:2aa9f933c8d2 | 118 | clearAll(); |
| TMBOY | 45:2aa9f933c8d2 | 119 | } else if (payload.playBehavior == PlayPayload.PlayBehavior.REPLACE_ENQUEUED) { |
| TMBOY | 45:2aa9f933c8d2 | 120 | clearEnqueued(); |
| TMBOY | 45:2aa9f933c8d2 | 121 | } |
| TMBOY | 45:2aa9f933c8d2 | 122 | final PlayPayload.Stream stream = item.stream; |
| TMBOY | 45:2aa9f933c8d2 | 123 | String streamUrl = stream.url; |
| TMBOY | 45:2aa9f933c8d2 | 124 | String streamId = stream.token; |
| TMBOY | 45:2aa9f933c8d2 | 125 | long offset = stream.offsetInMilliseconds; |
| TMBOY | 45:2aa9f933c8d2 | 126 | LogUtil.i(TAG, "URL:" + streamUrl); |
| TMBOY | 45:2aa9f933c8d2 | 127 | LogUtil.i(TAG, "StreamId:" + streamId); |
| TMBOY | 45:2aa9f933c8d2 | 128 | LogUtil.i(TAG, "Offset:" + offset); |
| TMBOY | 45:2aa9f933c8d2 | 129 | add(stream); |
| TMBOY | 45:2aa9f933c8d2 | 130 | } |
| TMBOY | 45:2aa9f933c8d2 | 131 | |
| TMBOY | 45:2aa9f933c8d2 | 132 | /** |
| TMBOY | 45:2aa9f933c8d2 | 133 | * 处理停止指令(Stop) |
| TMBOY | 45:2aa9f933c8d2 | 134 | * |
| TMBOY | 45:2aa9f933c8d2 | 135 | * @param payload payload |
| TMBOY | 45:2aa9f933c8d2 | 136 | */ |
| TMBOY | 45:2aa9f933c8d2 | 137 | private void handleStop(StopPayload payload) { |
| TMBOY | 45:2aa9f933c8d2 | 138 | stop(); |
| TMBOY | 45:2aa9f933c8d2 | 139 | } |
| TMBOY | 45:2aa9f933c8d2 | 140 | |
| TMBOY | 45:2aa9f933c8d2 | 141 | /** |
| TMBOY | 45:2aa9f933c8d2 | 142 | * 处理清空队列指令(Stop) |
| TMBOY | 45:2aa9f933c8d2 | 143 | * |
| TMBOY | 45:2aa9f933c8d2 | 144 | * @param clearQueuePayload clearQueuePayload |
| TMBOY | 45:2aa9f933c8d2 | 145 | */ |
| TMBOY | 45:2aa9f933c8d2 | 146 | private void handleClearQueue(ClearQueuePayload clearQueuePayload) { |
| TMBOY | 45:2aa9f933c8d2 | 147 | // 清除播放列表,并停止当前播放的音频(如果有) |
| TMBOY | 45:2aa9f933c8d2 | 148 | if (clearQueuePayload.clearBehavior == ClearQueuePayload.ClearBehavior.CLEAR_ALL) { |
| TMBOY | 45:2aa9f933c8d2 | 149 | audioPlayStateReport.clearQueueAll(); |
| TMBOY | 45:2aa9f933c8d2 | 150 | clearAll(); |
| TMBOY | 45:2aa9f933c8d2 | 151 | } else if (clearQueuePayload.clearBehavior == ClearQueuePayload.ClearBehavior.CLEAR_ENQUEUED) { |
| TMBOY | 45:2aa9f933c8d2 | 152 | // 清除播放列表,但不影响当前播放 |
| TMBOY | 45:2aa9f933c8d2 | 153 | audioPlayStateReport.clearQueueEnqueued(); |
| TMBOY | 45:2aa9f933c8d2 | 154 | clearEnqueued(); |
| TMBOY | 45:2aa9f933c8d2 | 155 | } |
| TMBOY | 45:2aa9f933c8d2 | 156 | } |
| TMBOY | 45:2aa9f933c8d2 | 157 | |
| TMBOY | 45:2aa9f933c8d2 | 158 | private void add(PlayPayload.Stream stream) { |
| TMBOY | 45:2aa9f933c8d2 | 159 | String expectedPreviousToken = stream.expectedPreviousToken; |
| TMBOY | 45:2aa9f933c8d2 | 160 | boolean startPlaying = playQueue.isEmpty(); |
| TMBOY | 45:2aa9f933c8d2 | 161 | if (expectedPreviousToken == null || latestStreamToken.isEmpty() |
| TMBOY | 45:2aa9f933c8d2 | 162 | || latestStreamToken.equals(expectedPreviousToken)) { |
| TMBOY | 45:2aa9f933c8d2 | 163 | playQueue.add(stream); |
| TMBOY | 45:2aa9f933c8d2 | 164 | } |
| TMBOY | 45:2aa9f933c8d2 | 165 | LogUtil.d(TAG, " coming playQueue size :" + playQueue.size()); |
| TMBOY | 45:2aa9f933c8d2 | 166 | if (startPlaying) { |
| TMBOY | 45:2aa9f933c8d2 | 167 | startPlay(); |
| TMBOY | 45:2aa9f933c8d2 | 168 | } |
| TMBOY | 45:2aa9f933c8d2 | 169 | } |
| TMBOY | 45:2aa9f933c8d2 | 170 | |
| TMBOY | 45:2aa9f933c8d2 | 171 | /** |
| TMBOY | 45:2aa9f933c8d2 | 172 | * 开始播放音乐 |
| TMBOY | 45:2aa9f933c8d2 | 173 | */ |
| TMBOY | 45:2aa9f933c8d2 | 174 | private void startPlay() { |
| TMBOY | 45:2aa9f933c8d2 | 175 | if (playQueue.isEmpty()) { |
| TMBOY | 45:2aa9f933c8d2 | 176 | LogUtil.d(TAG, "startPlay-playQueue isEmpty !!"); |
| TMBOY | 45:2aa9f933c8d2 | 177 | return; |
| TMBOY | 45:2aa9f933c8d2 | 178 | } |
| TMBOY | 45:2aa9f933c8d2 | 179 | PlayPayload.Stream currentStream = playQueue.peek(); |
| TMBOY | 45:2aa9f933c8d2 | 180 | if (currentStream == null) { |
| TMBOY | 45:2aa9f933c8d2 | 181 | return; |
| TMBOY | 45:2aa9f933c8d2 | 182 | } |
| TMBOY | 45:2aa9f933c8d2 | 183 | latestStreamToken = currentStream.token; |
| TMBOY | 45:2aa9f933c8d2 | 184 | String url = currentStream.url; |
| TMBOY | 45:2aa9f933c8d2 | 185 | // 从哪个位置开始播放 |
| TMBOY | 45:2aa9f933c8d2 | 186 | long offset = currentStream.offsetInMilliseconds; |
| TMBOY | 45:2aa9f933c8d2 | 187 | // 判断是否是流类型还是URL类型 |
| TMBOY | 45:2aa9f933c8d2 | 188 | if (currentStream.hasAttachedContent()) { |
| TMBOY | 45:2aa9f933c8d2 | 189 | mediaPlayer.play(new IMediaPlayer.MediaResource(currentStream.getAttachedContent())); |
| TMBOY | 45:2aa9f933c8d2 | 190 | } else { |
| TMBOY | 45:2aa9f933c8d2 | 191 | mediaPlayer.play(new IMediaPlayer.MediaResource(url)); |
| TMBOY | 45:2aa9f933c8d2 | 192 | } |
| TMBOY | 45:2aa9f933c8d2 | 193 | mediaPlayer.seekTo((int) offset); |
| TMBOY | 45:2aa9f933c8d2 | 194 | } |
| TMBOY | 45:2aa9f933c8d2 | 195 | |
| TMBOY | 45:2aa9f933c8d2 | 196 | private IMediaPlayer.IMediaPlayerListener mediaPlayerListener = new IMediaPlayer.SimpleMediaPlayerListener() { |
| TMBOY | 45:2aa9f933c8d2 | 197 | // 是否处于暂停 |
| TMBOY | 45:2aa9f933c8d2 | 198 | private boolean isPause; |
| TMBOY | 45:2aa9f933c8d2 | 199 | // 是否第一次到达了100 |
| TMBOY | 45:2aa9f933c8d2 | 200 | private boolean stutterFinished; |
| TMBOY | 45:2aa9f933c8d2 | 201 | // 是否处于上报ProgressReport事件中 |
| TMBOY | 45:2aa9f933c8d2 | 202 | private boolean progressReporting; |
| TMBOY | 45:2aa9f933c8d2 | 203 | // 是否处于缓冲中 |
| TMBOY | 45:2aa9f933c8d2 | 204 | private boolean bufferUnderRunInProgress; |
| TMBOY | 45:2aa9f933c8d2 | 205 | |
| TMBOY | 45:2aa9f933c8d2 | 206 | @Override |
| TMBOY | 45:2aa9f933c8d2 | 207 | public void onInit() { |
| TMBOY | 45:2aa9f933c8d2 | 208 | super.onInit(); |
| TMBOY | 45:2aa9f933c8d2 | 209 | LogUtil.d(TAG, "onInit"); |
| TMBOY | 45:2aa9f933c8d2 | 210 | isPause = false; |
| TMBOY | 45:2aa9f933c8d2 | 211 | stutterFinished = false; |
| TMBOY | 45:2aa9f933c8d2 | 212 | progressReporting = false; |
| TMBOY | 45:2aa9f933c8d2 | 213 | bufferUnderRunInProgress = false; |
| TMBOY | 45:2aa9f933c8d2 | 214 | } |
| TMBOY | 45:2aa9f933c8d2 | 215 | |
| TMBOY | 45:2aa9f933c8d2 | 216 | @Override |
| TMBOY | 45:2aa9f933c8d2 | 217 | public void onPrepared() { |
| TMBOY | 45:2aa9f933c8d2 | 218 | super.onPrepared(); |
| TMBOY | 45:2aa9f933c8d2 | 219 | LogUtil.d(TAG, "onPrepared"); |
| TMBOY | 45:2aa9f933c8d2 | 220 | fireOnPrepared(); |
| TMBOY | 45:2aa9f933c8d2 | 221 | } |
| TMBOY | 45:2aa9f933c8d2 | 222 | |
| TMBOY | 45:2aa9f933c8d2 | 223 | @Override |
| TMBOY | 45:2aa9f933c8d2 | 224 | public void onPlaying() { |
| TMBOY | 45:2aa9f933c8d2 | 225 | super.onPlaying(); |
| TMBOY | 45:2aa9f933c8d2 | 226 | LogUtil.d(TAG, "onPlaying"); |
| TMBOY | 45:2aa9f933c8d2 | 227 | // 暂停后继续播放 |
| TMBOY | 45:2aa9f933c8d2 | 228 | if (isPause) { |
| TMBOY | 45:2aa9f933c8d2 | 229 | isPause = false; |
| TMBOY | 45:2aa9f933c8d2 | 230 | audioPlayStateReport.playbackResumed(); |
| TMBOY | 45:2aa9f933c8d2 | 231 | } else { |
| TMBOY | 45:2aa9f933c8d2 | 232 | // 第一次播放 |
| TMBOY | 45:2aa9f933c8d2 | 233 | PlayPayload.Stream stream = playQueue.peek(); |
| TMBOY | 45:2aa9f933c8d2 | 234 | if (stream == null) { |
| TMBOY | 45:2aa9f933c8d2 | 235 | return; |
| TMBOY | 45:2aa9f933c8d2 | 236 | } |
| TMBOY | 45:2aa9f933c8d2 | 237 | long offset = stream.offsetInMilliseconds; |
| TMBOY | 45:2aa9f933c8d2 | 238 | LogUtil.d(TAG, "onPlaying---Duration----:" + mediaPlayer.getDuration()); |
| TMBOY | 45:2aa9f933c8d2 | 239 | timer.reset(offset, mediaPlayer.getDuration()); |
| TMBOY | 45:2aa9f933c8d2 | 240 | |
| TMBOY | 45:2aa9f933c8d2 | 241 | // 上报PlaybackStarted事件 |
| TMBOY | 45:2aa9f933c8d2 | 242 | audioPlayStateReport.playbackStarted(); |
| TMBOY | 45:2aa9f933c8d2 | 243 | } |
| TMBOY | 45:2aa9f933c8d2 | 244 | startTimerAndProgressReporter(); |
| TMBOY | 45:2aa9f933c8d2 | 245 | fireOnPlaying(); |
| TMBOY | 45:2aa9f933c8d2 | 246 | } |
| TMBOY | 45:2aa9f933c8d2 | 247 | |
| TMBOY | 45:2aa9f933c8d2 | 248 | @Override |
| TMBOY | 45:2aa9f933c8d2 | 249 | public void onPaused() { |
| TMBOY | 45:2aa9f933c8d2 | 250 | LogUtil.d(TAG, "onPaused"); |
| TMBOY | 45:2aa9f933c8d2 | 251 | stopTimerAndProgressReporter(); |
| TMBOY | 45:2aa9f933c8d2 | 252 | isPause = true; |
| TMBOY | 45:2aa9f933c8d2 | 253 | audioPlayStateReport.playbackPaused(); |
| TMBOY | 45:2aa9f933c8d2 | 254 | fireOnPaused(); |
| TMBOY | 45:2aa9f933c8d2 | 255 | } |
| TMBOY | 45:2aa9f933c8d2 | 256 | |
| TMBOY | 45:2aa9f933c8d2 | 257 | @Override |
| TMBOY | 45:2aa9f933c8d2 | 258 | public void onStopped() { |
| TMBOY | 45:2aa9f933c8d2 | 259 | super.onStopped(); |
| TMBOY | 45:2aa9f933c8d2 | 260 | stopTimerAndProgressReporter(); |
| TMBOY | 45:2aa9f933c8d2 | 261 | audioPlayStateReport.playbackStopped(); |
| TMBOY | 45:2aa9f933c8d2 | 262 | fireOnStopped(); |
| TMBOY | 45:2aa9f933c8d2 | 263 | } |
| TMBOY | 45:2aa9f933c8d2 | 264 | |
| TMBOY | 45:2aa9f933c8d2 | 265 | @Override |
| TMBOY | 45:2aa9f933c8d2 | 266 | public void onCompletion() { |
| TMBOY | 45:2aa9f933c8d2 | 267 | LogUtil.d(TAG, "onCompletion"); |
| TMBOY | 45:2aa9f933c8d2 | 268 | stopTimerAndProgressReporter(); |
| TMBOY | 45:2aa9f933c8d2 | 269 | playQueue.poll(); |
| TMBOY | 45:2aa9f933c8d2 | 270 | audioPlayStateReport.playbackFinished(); |
| TMBOY | 45:2aa9f933c8d2 | 271 | audioPlayStateReport.playbackNearlyFinished(); |
| TMBOY | 45:2aa9f933c8d2 | 272 | if (!playQueue.isEmpty()) { |
| TMBOY | 45:2aa9f933c8d2 | 273 | startPlay(); |
| TMBOY | 45:2aa9f933c8d2 | 274 | } |
| TMBOY | 45:2aa9f933c8d2 | 275 | fireOnCompletion(); |
| TMBOY | 45:2aa9f933c8d2 | 276 | } |
| TMBOY | 45:2aa9f933c8d2 | 277 | |
| TMBOY | 45:2aa9f933c8d2 | 278 | @Override |
| TMBOY | 45:2aa9f933c8d2 | 279 | public void onRelease() { |
| TMBOY | 45:2aa9f933c8d2 | 280 | LogUtil.d(TAG, "onError"); |
| TMBOY | 45:2aa9f933c8d2 | 281 | stopTimerAndProgressReporter(); |
| TMBOY | 45:2aa9f933c8d2 | 282 | fireOnRelease(); |
| TMBOY | 45:2aa9f933c8d2 | 283 | } |
| TMBOY | 45:2aa9f933c8d2 | 284 | |
| TMBOY | 45:2aa9f933c8d2 | 285 | @Override |
| TMBOY | 45:2aa9f933c8d2 | 286 | public void onError(String error, IMediaPlayer.ErrorType errorType) { |
| TMBOY | 45:2aa9f933c8d2 | 287 | LogUtil.d(TAG, "onError"); |
| TMBOY | 45:2aa9f933c8d2 | 288 | playQueue.clear(); |
| TMBOY | 45:2aa9f933c8d2 | 289 | audioPlayStateReport.playbackFailed(errorType); |
| TMBOY | 45:2aa9f933c8d2 | 290 | stopTimerAndProgressReporter(); |
| TMBOY | 45:2aa9f933c8d2 | 291 | fireOnError(error, errorType); |
| TMBOY | 45:2aa9f933c8d2 | 292 | } |
| TMBOY | 45:2aa9f933c8d2 | 293 | |
| TMBOY | 45:2aa9f933c8d2 | 294 | @Override |
| TMBOY | 45:2aa9f933c8d2 | 295 | public void onBufferingUpdate(int percent) { |
| TMBOY | 45:2aa9f933c8d2 | 296 | LogUtil.d(TAG, "onBufferingUpdate:" + percent); |
| TMBOY | 45:2aa9f933c8d2 | 297 | fireOnBufferingUpdate(percent); |
| TMBOY | 45:2aa9f933c8d2 | 298 | PlayPayload.Stream stream = playQueue.peek(); |
| TMBOY | 45:2aa9f933c8d2 | 299 | if (stream == null) { |
| TMBOY | 45:2aa9f933c8d2 | 300 | return; |
| TMBOY | 45:2aa9f933c8d2 | 301 | } |
| TMBOY | 45:2aa9f933c8d2 | 302 | // Play指令有progressReportDelayInMilliseconds |
| TMBOY | 45:2aa9f933c8d2 | 303 | if (!progressReporting && stream.getProgressReportRequired()) { |
| TMBOY | 45:2aa9f933c8d2 | 304 | LogUtil.d(TAG, "onBufferingUpdate:" + percent); |
| TMBOY | 45:2aa9f933c8d2 | 305 | progressReporting = true; |
| TMBOY | 45:2aa9f933c8d2 | 306 | progressReporter.disable(); |
| TMBOY | 45:2aa9f933c8d2 | 307 | progressReporter.setup(stream.progressReport); |
| TMBOY | 45:2aa9f933c8d2 | 308 | long offset = stream.offsetInMilliseconds; |
| TMBOY | 45:2aa9f933c8d2 | 309 | timer.reset(offset, mediaPlayer.getDuration()); |
| TMBOY | 45:2aa9f933c8d2 | 310 | startTimerAndProgressReporter(); |
| TMBOY | 45:2aa9f933c8d2 | 311 | } |
| TMBOY | 45:2aa9f933c8d2 | 312 | |
| TMBOY | 45:2aa9f933c8d2 | 313 | // 已经缓冲完成了 |
| TMBOY | 45:2aa9f933c8d2 | 314 | if (stutterFinished) { |
| TMBOY | 45:2aa9f933c8d2 | 315 | return; |
| TMBOY | 45:2aa9f933c8d2 | 316 | } |
| TMBOY | 45:2aa9f933c8d2 | 317 | // 开始缓冲 |
| TMBOY | 45:2aa9f933c8d2 | 318 | if (!bufferUnderRunInProgress) { |
| TMBOY | 45:2aa9f933c8d2 | 319 | LogUtil.d(TAG, "==playbackStutterStarted"); |
| TMBOY | 45:2aa9f933c8d2 | 320 | bufferUnderRunInProgress = true; |
| TMBOY | 45:2aa9f933c8d2 | 321 | bufferingStartMilliseconds = System.currentTimeMillis(); |
| TMBOY | 45:2aa9f933c8d2 | 322 | audioPlayStateReport.playbackStutterStarted(); |
| TMBOY | 45:2aa9f933c8d2 | 323 | } |
| TMBOY | 45:2aa9f933c8d2 | 324 | // 缓冲完毕后上报playbackStutterFinished |
| TMBOY | 45:2aa9f933c8d2 | 325 | if (percent >= 100) { |
| TMBOY | 45:2aa9f933c8d2 | 326 | stutterFinished = true; |
| TMBOY | 45:2aa9f933c8d2 | 327 | bufferingEndMilliseconds = System.currentTimeMillis(); |
| TMBOY | 45:2aa9f933c8d2 | 328 | audioPlayStateReport.playbackStutterFinished(); |
| TMBOY | 45:2aa9f933c8d2 | 329 | } |
| TMBOY | 45:2aa9f933c8d2 | 330 | } |
| TMBOY | 45:2aa9f933c8d2 | 331 | }; |
| TMBOY | 45:2aa9f933c8d2 | 332 | |
| TMBOY | 45:2aa9f933c8d2 | 333 | private void startTimerAndProgressReporter() { |
| TMBOY | 45:2aa9f933c8d2 | 334 | timer.start(); |
| TMBOY | 45:2aa9f933c8d2 | 335 | if (progressReporter.isSetup()) { |
| TMBOY | 45:2aa9f933c8d2 | 336 | progressReporter.start(); |
| TMBOY | 45:2aa9f933c8d2 | 337 | } |
| TMBOY | 45:2aa9f933c8d2 | 338 | } |
| TMBOY | 45:2aa9f933c8d2 | 339 | |
| TMBOY | 45:2aa9f933c8d2 | 340 | private void stopTimerAndProgressReporter() { |
| TMBOY | 45:2aa9f933c8d2 | 341 | timer.stop(); |
| TMBOY | 45:2aa9f933c8d2 | 342 | progressReporter.stop(); |
| TMBOY | 45:2aa9f933c8d2 | 343 | } |
| TMBOY | 45:2aa9f933c8d2 | 344 | |
| TMBOY | 45:2aa9f933c8d2 | 345 | private void clearAll() { |
| TMBOY | 45:2aa9f933c8d2 | 346 | stop(); |
| TMBOY | 45:2aa9f933c8d2 | 347 | playQueue.clear(); |
| TMBOY | 45:2aa9f933c8d2 | 348 | } |
| TMBOY | 45:2aa9f933c8d2 | 349 | |
| TMBOY | 45:2aa9f933c8d2 | 350 | private void clearEnqueued() { |
| TMBOY | 45:2aa9f933c8d2 | 351 | PlayPayload.Stream top = playQueue.poll(); |
| TMBOY | 45:2aa9f933c8d2 | 352 | playQueue.clear(); |
| TMBOY | 45:2aa9f933c8d2 | 353 | if (top != null) { |
| TMBOY | 45:2aa9f933c8d2 | 354 | playQueue.add(top); |
| TMBOY | 45:2aa9f933c8d2 | 355 | } |
| TMBOY | 45:2aa9f933c8d2 | 356 | } |
| TMBOY | 45:2aa9f933c8d2 | 357 | |
| TMBOY | 45:2aa9f933c8d2 | 358 | private void stop() { |
| TMBOY | 45:2aa9f933c8d2 | 359 | if (!playQueue.isEmpty() && isPlayingOrPaused()) { |
| TMBOY | 45:2aa9f933c8d2 | 360 | stopTimerAndProgressReporter(); |
| TMBOY | 45:2aa9f933c8d2 | 361 | // 要把播放策略中的对应的那一条删除了 |
| TMBOY | 45:2aa9f933c8d2 | 362 | mediaPlayer.stop(); |
| TMBOY | 45:2aa9f933c8d2 | 363 | } |
| TMBOY | 45:2aa9f933c8d2 | 364 | } |
| TMBOY | 45:2aa9f933c8d2 | 365 | |
| TMBOY | 45:2aa9f933c8d2 | 366 | private boolean isPlaying() { |
| TMBOY | 45:2aa9f933c8d2 | 367 | return (audioPlayStateReport.getState() == AudioPlayStateReport.AudioPlayerState.PLAYING |
| TMBOY | 45:2aa9f933c8d2 | 368 | || audioPlayStateReport.getState() == AudioPlayStateReport.AudioPlayerState.PAUSED |
| TMBOY | 45:2aa9f933c8d2 | 369 | || audioPlayStateReport.getState() == AudioPlayStateReport.AudioPlayerState.BUFFER_UNDERRUN); |
| TMBOY | 45:2aa9f933c8d2 | 370 | } |
| TMBOY | 45:2aa9f933c8d2 | 371 | |
| TMBOY | 45:2aa9f933c8d2 | 372 | private boolean isPlayingOrPaused() { |
| TMBOY | 45:2aa9f933c8d2 | 373 | return isPlaying() || audioPlayStateReport.getState() == AudioPlayStateReport.AudioPlayerState.PAUSED; |
| TMBOY | 45:2aa9f933c8d2 | 374 | } |
| TMBOY | 45:2aa9f933c8d2 | 375 | |
| TMBOY | 45:2aa9f933c8d2 | 376 | @Override |
| TMBOY | 45:2aa9f933c8d2 | 377 | public void release() { |
| TMBOY | 45:2aa9f933c8d2 | 378 | if (mediaPlayer != null) { |
| TMBOY | 45:2aa9f933c8d2 | 379 | mediaPlayer.release(); |
| TMBOY | 45:2aa9f933c8d2 | 380 | mediaPlayer.removeMediaPlayerListener(mediaPlayerListener); |
| TMBOY | 45:2aa9f933c8d2 | 381 | } |
| TMBOY | 45:2aa9f933c8d2 | 382 | stopTimerAndProgressReporter(); |
| TMBOY | 45:2aa9f933c8d2 | 383 | audioPlayerListeners.clear(); |
| TMBOY | 45:2aa9f933c8d2 | 384 | } |
| TMBOY | 45:2aa9f933c8d2 | 385 | |
| TMBOY | 45:2aa9f933c8d2 | 386 | /** |
| TMBOY | 45:2aa9f933c8d2 | 387 | * 播放上报时需要的信息 |
| TMBOY | 45:2aa9f933c8d2 | 388 | */ |
| TMBOY | 45:2aa9f933c8d2 | 389 | private AudioPlayStateReport.AudioPlayStateReportListener audioPlayStateReportListener = |
| TMBOY | 45:2aa9f933c8d2 | 390 | new AudioPlayStateReport.AudioPlayStateReportListener() { |
| TMBOY | 45:2aa9f933c8d2 | 391 | @Override |
| TMBOY | 45:2aa9f933c8d2 | 392 | public String getCurrentStreamToken() { |
| TMBOY | 45:2aa9f933c8d2 | 393 | return latestStreamToken; |
| TMBOY | 45:2aa9f933c8d2 | 394 | } |
| TMBOY | 45:2aa9f933c8d2 | 395 | |
| TMBOY | 45:2aa9f933c8d2 | 396 | @Override |
| TMBOY | 45:2aa9f933c8d2 | 397 | public long getCurrentOffsetInMilliseconds() { |
| TMBOY | 45:2aa9f933c8d2 | 398 | return getCurrentOffsetInMillisecondsByTime(); |
| TMBOY | 45:2aa9f933c8d2 | 399 | } |
| TMBOY | 45:2aa9f933c8d2 | 400 | |
| TMBOY | 45:2aa9f933c8d2 | 401 | @Override |
| TMBOY | 45:2aa9f933c8d2 | 402 | public long getStutterDurationInMilliseconds() { |
| TMBOY | 45:2aa9f933c8d2 | 403 | // 缓冲时间ms |
| TMBOY | 45:2aa9f933c8d2 | 404 | return bufferingEndMilliseconds - bufferingStartMilliseconds; |
| TMBOY | 45:2aa9f933c8d2 | 405 | } |
| TMBOY | 45:2aa9f933c8d2 | 406 | }; |
| TMBOY | 45:2aa9f933c8d2 | 407 | |
| TMBOY | 45:2aa9f933c8d2 | 408 | private long getCurrentOffsetInMillisecondsByTime() { |
| TMBOY | 45:2aa9f933c8d2 | 409 | AudioPlayStateReport.AudioPlayerState playerActivity = audioPlayStateReport.getState(); |
| TMBOY | 45:2aa9f933c8d2 | 410 | long offset; |
| TMBOY | 45:2aa9f933c8d2 | 411 | switch (playerActivity) { |
| TMBOY | 45:2aa9f933c8d2 | 412 | case PLAYING: |
| TMBOY | 45:2aa9f933c8d2 | 413 | case PAUSED: |
| TMBOY | 45:2aa9f933c8d2 | 414 | case BUFFER_UNDERRUN: |
| TMBOY | 45:2aa9f933c8d2 | 415 | case STOPPED: |
| TMBOY | 45:2aa9f933c8d2 | 416 | case FINISHED: |
| TMBOY | 45:2aa9f933c8d2 | 417 | offset = timer.getOffsetInMilliseconds(); |
| TMBOY | 45:2aa9f933c8d2 | 418 | break; |
| TMBOY | 45:2aa9f933c8d2 | 419 | case IDLE: |
| TMBOY | 45:2aa9f933c8d2 | 420 | default: |
| TMBOY | 45:2aa9f933c8d2 | 421 | offset = 0; |
| TMBOY | 45:2aa9f933c8d2 | 422 | } |
| TMBOY | 45:2aa9f933c8d2 | 423 | LogUtil.d(TAG, "getCurrentOffsetInMilliseconds offset:" + offset); |
| TMBOY | 45:2aa9f933c8d2 | 424 | return offset; |
| TMBOY | 45:2aa9f933c8d2 | 425 | } |
| TMBOY | 45:2aa9f933c8d2 | 426 | |
| TMBOY | 45:2aa9f933c8d2 | 427 | private static class ProgressReportDelayEventRunnable implements Runnable { |
| TMBOY | 45:2aa9f933c8d2 | 428 | private final AudioPlayStateReport audioPlayStateReport; |
| TMBOY | 45:2aa9f933c8d2 | 429 | |
| TMBOY | 45:2aa9f933c8d2 | 430 | ProgressReportDelayEventRunnable(AudioPlayStateReport audioPlayStateReport) { |
| TMBOY | 45:2aa9f933c8d2 | 431 | this.audioPlayStateReport = audioPlayStateReport; |
| TMBOY | 45:2aa9f933c8d2 | 432 | } |
| TMBOY | 45:2aa9f933c8d2 | 433 | |
| TMBOY | 45:2aa9f933c8d2 | 434 | @Override |
| TMBOY | 45:2aa9f933c8d2 | 435 | public void run() { |
| TMBOY | 45:2aa9f933c8d2 | 436 | audioPlayStateReport.reportProgressDelay(); |
| TMBOY | 45:2aa9f933c8d2 | 437 | } |
| TMBOY | 45:2aa9f933c8d2 | 438 | } |
| TMBOY | 45:2aa9f933c8d2 | 439 | |
| TMBOY | 45:2aa9f933c8d2 | 440 | private static class ProgressReportIntervalEventRunnable implements Runnable { |
| TMBOY | 45:2aa9f933c8d2 | 441 | private final AudioPlayStateReport audioPlayStateReport; |
| TMBOY | 45:2aa9f933c8d2 | 442 | |
| TMBOY | 45:2aa9f933c8d2 | 443 | ProgressReportIntervalEventRunnable(AudioPlayStateReport audioPlayStateReport) { |
| TMBOY | 45:2aa9f933c8d2 | 444 | this.audioPlayStateReport = audioPlayStateReport; |
| TMBOY | 45:2aa9f933c8d2 | 445 | } |
| TMBOY | 45:2aa9f933c8d2 | 446 | |
| TMBOY | 45:2aa9f933c8d2 | 447 | @Override |
| TMBOY | 45:2aa9f933c8d2 | 448 | public void run() { |
| TMBOY | 45:2aa9f933c8d2 | 449 | audioPlayStateReport.reportProgressInterval(); |
| TMBOY | 45:2aa9f933c8d2 | 450 | } |
| TMBOY | 45:2aa9f933c8d2 | 451 | } |
| TMBOY | 45:2aa9f933c8d2 | 452 | |
| TMBOY | 45:2aa9f933c8d2 | 453 | private void fireOnPrepared() { |
| TMBOY | 45:2aa9f933c8d2 | 454 | for (IMediaPlayer.IMediaPlayerListener listener : audioPlayerListeners) { |
| TMBOY | 45:2aa9f933c8d2 | 455 | listener.onPrepared(); |
| TMBOY | 45:2aa9f933c8d2 | 456 | } |
| TMBOY | 45:2aa9f933c8d2 | 457 | } |
| TMBOY | 45:2aa9f933c8d2 | 458 | |
| TMBOY | 45:2aa9f933c8d2 | 459 | private void fireOnRelease() { |
| TMBOY | 45:2aa9f933c8d2 | 460 | for (IMediaPlayer.IMediaPlayerListener listener : audioPlayerListeners) { |
| TMBOY | 45:2aa9f933c8d2 | 461 | listener.onRelease(); |
| TMBOY | 45:2aa9f933c8d2 | 462 | } |
| TMBOY | 45:2aa9f933c8d2 | 463 | } |
| TMBOY | 45:2aa9f933c8d2 | 464 | |
| TMBOY | 45:2aa9f933c8d2 | 465 | private void fireOnPlaying() { |
| TMBOY | 45:2aa9f933c8d2 | 466 | for (IMediaPlayer.IMediaPlayerListener listener : audioPlayerListeners) { |
| TMBOY | 45:2aa9f933c8d2 | 467 | listener.onPlaying(); |
| TMBOY | 45:2aa9f933c8d2 | 468 | } |
| TMBOY | 45:2aa9f933c8d2 | 469 | } |
| TMBOY | 45:2aa9f933c8d2 | 470 | |
| TMBOY | 45:2aa9f933c8d2 | 471 | private void fireOnPaused() { |
| TMBOY | 45:2aa9f933c8d2 | 472 | for (IMediaPlayer.IMediaPlayerListener listener : audioPlayerListeners) { |
| TMBOY | 45:2aa9f933c8d2 | 473 | listener.onPaused(); |
| TMBOY | 45:2aa9f933c8d2 | 474 | } |
| TMBOY | 45:2aa9f933c8d2 | 475 | } |
| TMBOY | 45:2aa9f933c8d2 | 476 | |
| TMBOY | 45:2aa9f933c8d2 | 477 | private void fireOnStopped() { |
| TMBOY | 45:2aa9f933c8d2 | 478 | for (IMediaPlayer.IMediaPlayerListener listener : audioPlayerListeners) { |
| TMBOY | 45:2aa9f933c8d2 | 479 | listener.onStopped(); |
| TMBOY | 45:2aa9f933c8d2 | 480 | } |
| TMBOY | 45:2aa9f933c8d2 | 481 | } |
| TMBOY | 45:2aa9f933c8d2 | 482 | |
| TMBOY | 45:2aa9f933c8d2 | 483 | private void fireOnCompletion() { |
| TMBOY | 45:2aa9f933c8d2 | 484 | for (IMediaPlayer.IMediaPlayerListener listener : audioPlayerListeners) { |
| TMBOY | 45:2aa9f933c8d2 | 485 | listener.onCompletion(); |
| TMBOY | 45:2aa9f933c8d2 | 486 | } |
| TMBOY | 45:2aa9f933c8d2 | 487 | } |
| TMBOY | 45:2aa9f933c8d2 | 488 | |
| TMBOY | 45:2aa9f933c8d2 | 489 | private void fireOnError(String error, IMediaPlayer.ErrorType errorType) { |
| TMBOY | 45:2aa9f933c8d2 | 490 | for (IMediaPlayer.IMediaPlayerListener listener : audioPlayerListeners) { |
| TMBOY | 45:2aa9f933c8d2 | 491 | listener.onError(error, errorType); |
| TMBOY | 45:2aa9f933c8d2 | 492 | } |
| TMBOY | 45:2aa9f933c8d2 | 493 | } |
| TMBOY | 45:2aa9f933c8d2 | 494 | |
| TMBOY | 45:2aa9f933c8d2 | 495 | private void fireOnBufferingUpdate(int percent) { |
| TMBOY | 45:2aa9f933c8d2 | 496 | for (IMediaPlayer.IMediaPlayerListener listener : audioPlayerListeners) { |
| TMBOY | 45:2aa9f933c8d2 | 497 | listener.onBufferingUpdate(percent); |
| TMBOY | 45:2aa9f933c8d2 | 498 | } |
| TMBOY | 45:2aa9f933c8d2 | 499 | } |
| TMBOY | 45:2aa9f933c8d2 | 500 | |
| TMBOY | 45:2aa9f933c8d2 | 501 | private void fireBufferingStart() { |
| TMBOY | 45:2aa9f933c8d2 | 502 | for (IMediaPlayer.IMediaPlayerListener listener : audioPlayerListeners) { |
| TMBOY | 45:2aa9f933c8d2 | 503 | listener.onBufferingStart(); |
| TMBOY | 45:2aa9f933c8d2 | 504 | } |
| TMBOY | 45:2aa9f933c8d2 | 505 | } |
| TMBOY | 45:2aa9f933c8d2 | 506 | |
| TMBOY | 45:2aa9f933c8d2 | 507 | private void fireBufferingEnd() { |
| TMBOY | 45:2aa9f933c8d2 | 508 | for (IMediaPlayer.IMediaPlayerListener listener : audioPlayerListeners) { |
| TMBOY | 45:2aa9f933c8d2 | 509 | listener.onBufferingEnd(); |
| TMBOY | 45:2aa9f933c8d2 | 510 | } |
| TMBOY | 45:2aa9f933c8d2 | 511 | } |
| TMBOY | 45:2aa9f933c8d2 | 512 | |
| TMBOY | 45:2aa9f933c8d2 | 513 | public void addAudioPlayListener(IMediaPlayer.IMediaPlayerListener listener) { |
| TMBOY | 45:2aa9f933c8d2 | 514 | audioPlayerListeners.add(listener); |
| TMBOY | 45:2aa9f933c8d2 | 515 | } |
| TMBOY | 45:2aa9f933c8d2 | 516 | } |
