ex
Fork of mbed-os-example-mbed5-blinky by
dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/framework/BaseMultiChannelMediaPlayer.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.framework; |
| TMBOY | 45:2aa9f933c8d2 | 17 | |
| TMBOY | 45:2aa9f933c8d2 | 18 | import com.baidu.duer.dcs.systeminterface.IMediaPlayer; |
| TMBOY | 45:2aa9f933c8d2 | 19 | import com.baidu.duer.dcs.systeminterface.IPlatformFactory; |
| TMBOY | 45:2aa9f933c8d2 | 20 | import com.baidu.duer.dcs.util.LogUtil; |
| TMBOY | 45:2aa9f933c8d2 | 21 | |
| TMBOY | 45:2aa9f933c8d2 | 22 | import java.util.Comparator; |
| TMBOY | 45:2aa9f933c8d2 | 23 | import java.util.Iterator; |
| TMBOY | 45:2aa9f933c8d2 | 24 | import java.util.Map; |
| TMBOY | 45:2aa9f933c8d2 | 25 | import java.util.TreeMap; |
| TMBOY | 45:2aa9f933c8d2 | 26 | import java.util.concurrent.ConcurrentHashMap; |
| TMBOY | 45:2aa9f933c8d2 | 27 | |
| TMBOY | 45:2aa9f933c8d2 | 28 | /** |
| TMBOY | 45:2aa9f933c8d2 | 29 | * 1.用途:控制各个DeviceModule的播放策略-基类,主要控制的是{@link com.baidu.duer.dcs.devicemodule.alerts.AlertsDeviceModule} |
| TMBOY | 45:2aa9f933c8d2 | 30 | * and {@link com.baidu.duer.dcs.devicemodule.voiceoutput.VoiceOutputDeviceModule} |
| TMBOY | 45:2aa9f933c8d2 | 31 | * and {@link com.baidu.duer.dcs.devicemodule.audioplayer.AudioPlayerDeviceModule} |
| TMBOY | 45:2aa9f933c8d2 | 32 | * <p> |
| TMBOY | 45:2aa9f933c8d2 | 33 | * 2.如果你需要实现自己的策略需要复写handlePlay方法,该sample中提供了一种暂停策略,即 |
| TMBOY | 45:2aa9f933c8d2 | 34 | * {@link com.baidu.duer.dcs.framework.PauseStrategyMultiChannelMediaPlayer} |
| TMBOY | 45:2aa9f933c8d2 | 35 | * <p> |
| TMBOY | 45:2aa9f933c8d2 | 36 | * Created by guxiuzhong@baidu.com on 2017/5/31. |
| TMBOY | 45:2aa9f933c8d2 | 37 | */ |
| TMBOY | 45:2aa9f933c8d2 | 38 | public abstract class BaseMultiChannelMediaPlayer { |
| TMBOY | 45:2aa9f933c8d2 | 39 | // 注册的mediaPlayer |
| TMBOY | 45:2aa9f933c8d2 | 40 | protected Map<String, ChannelMediaPlayerInfo> mediaPlayers = new ConcurrentHashMap<>(); |
| TMBOY | 45:2aa9f933c8d2 | 41 | private IPlatformFactory factory; |
| TMBOY | 45:2aa9f933c8d2 | 42 | |
| TMBOY | 45:2aa9f933c8d2 | 43 | public BaseMultiChannelMediaPlayer(IPlatformFactory factory) { |
| TMBOY | 45:2aa9f933c8d2 | 44 | this.factory = factory; |
| TMBOY | 45:2aa9f933c8d2 | 45 | } |
| TMBOY | 45:2aa9f933c8d2 | 46 | |
| TMBOY | 45:2aa9f933c8d2 | 47 | /** |
| TMBOY | 45:2aa9f933c8d2 | 48 | * 添加一个频道并创建一个mediaPlayer |
| TMBOY | 45:2aa9f933c8d2 | 49 | * |
| TMBOY | 45:2aa9f933c8d2 | 50 | * @param channelName 频道的名字 |
| TMBOY | 45:2aa9f933c8d2 | 51 | * @param priority 频道的优先级 |
| TMBOY | 45:2aa9f933c8d2 | 52 | * @return IMediaPlayer 用于处理端能力的播放 |
| TMBOY | 45:2aa9f933c8d2 | 53 | */ |
| TMBOY | 45:2aa9f933c8d2 | 54 | public IMediaPlayer addNewChannel(String channelName, int priority) { |
| TMBOY | 45:2aa9f933c8d2 | 55 | IMediaPlayer mediaPlayer = factory.createMediaPlayer(); |
| TMBOY | 45:2aa9f933c8d2 | 56 | |
| TMBOY | 45:2aa9f933c8d2 | 57 | ChannelMediaPlayerInfo info = new ChannelMediaPlayerInfo(); |
| TMBOY | 45:2aa9f933c8d2 | 58 | info.channelName = channelName; |
| TMBOY | 45:2aa9f933c8d2 | 59 | info.priority = priority; |
| TMBOY | 45:2aa9f933c8d2 | 60 | info.mediaPlayer = mediaPlayer; |
| TMBOY | 45:2aa9f933c8d2 | 61 | mediaPlayers.put(channelName, info); |
| TMBOY | 45:2aa9f933c8d2 | 62 | |
| TMBOY | 45:2aa9f933c8d2 | 63 | return new ChannelMediaPlayer(info); |
| TMBOY | 45:2aa9f933c8d2 | 64 | } |
| TMBOY | 45:2aa9f933c8d2 | 65 | |
| TMBOY | 45:2aa9f933c8d2 | 66 | /** |
| TMBOY | 45:2aa9f933c8d2 | 67 | * 处理对话频道(speak), 闹钟/提醒频道(alert),音乐频道(audio)的播放策略, |
| TMBOY | 45:2aa9f933c8d2 | 68 | * 比如: 当播放一个低优先级的指令内容时,来了一个高优先级的播放指令是否需要暂停/降低 低优先级频道对应的mediaPlayer |
| TMBOY | 45:2aa9f933c8d2 | 69 | * |
| TMBOY | 45:2aa9f933c8d2 | 70 | * @param channelName 频道的名字(即通过addNewChannel方法指定的) |
| TMBOY | 45:2aa9f933c8d2 | 71 | * @param mediaResource 媒体资源 |
| TMBOY | 45:2aa9f933c8d2 | 72 | */ |
| TMBOY | 45:2aa9f933c8d2 | 73 | protected abstract void handlePlay(String channelName, IMediaPlayer.MediaResource mediaResource); |
| TMBOY | 45:2aa9f933c8d2 | 74 | |
| TMBOY | 45:2aa9f933c8d2 | 75 | protected int getPriorityByChannelName(String channelName) { |
| TMBOY | 45:2aa9f933c8d2 | 76 | if (mediaPlayers.containsKey(channelName)) { |
| TMBOY | 45:2aa9f933c8d2 | 77 | ChannelMediaPlayerInfo info = mediaPlayers.get(channelName); |
| TMBOY | 45:2aa9f933c8d2 | 78 | return info.priority; |
| TMBOY | 45:2aa9f933c8d2 | 79 | } |
| TMBOY | 45:2aa9f933c8d2 | 80 | return UNKNOWN_PRIORITY; |
| TMBOY | 45:2aa9f933c8d2 | 81 | } |
| TMBOY | 45:2aa9f933c8d2 | 82 | |
| TMBOY | 45:2aa9f933c8d2 | 83 | /** |
| TMBOY | 45:2aa9f933c8d2 | 84 | * 根据频道的名字获取对应的播放器 |
| TMBOY | 45:2aa9f933c8d2 | 85 | * |
| TMBOY | 45:2aa9f933c8d2 | 86 | * @param channelName channelName 频道的名字 |
| TMBOY | 45:2aa9f933c8d2 | 87 | * @return IMediaPlayer |
| TMBOY | 45:2aa9f933c8d2 | 88 | */ |
| TMBOY | 45:2aa9f933c8d2 | 89 | protected IMediaPlayer getMediaPlayer(String channelName) { |
| TMBOY | 45:2aa9f933c8d2 | 90 | if (channelName != null && channelName.length() > 0) { |
| TMBOY | 45:2aa9f933c8d2 | 91 | if (mediaPlayers.containsKey(channelName)) { |
| TMBOY | 45:2aa9f933c8d2 | 92 | return mediaPlayers.get(channelName).mediaPlayer; |
| TMBOY | 45:2aa9f933c8d2 | 93 | } |
| TMBOY | 45:2aa9f933c8d2 | 94 | } |
| TMBOY | 45:2aa9f933c8d2 | 95 | return null; |
| TMBOY | 45:2aa9f933c8d2 | 96 | } |
| TMBOY | 45:2aa9f933c8d2 | 97 | |
| TMBOY | 45:2aa9f933c8d2 | 98 | private static final String TAG = BaseMultiChannelMediaPlayer.class.getSimpleName(); |
| TMBOY | 45:2aa9f933c8d2 | 99 | protected static final int UNKNOWN_PRIORITY = -1; |
| TMBOY | 45:2aa9f933c8d2 | 100 | // 按优先级保存的需要播放的数据 |
| TMBOY | 45:2aa9f933c8d2 | 101 | protected Map<Integer, ChannelMediaPlayerInfo> currentPlayMap = new TreeMap<>( |
| TMBOY | 45:2aa9f933c8d2 | 102 | new Comparator<Integer>() { |
| TMBOY | 45:2aa9f933c8d2 | 103 | public int compare(Integer obj1, Integer obj2) { |
| TMBOY | 45:2aa9f933c8d2 | 104 | // 降序排序 |
| TMBOY | 45:2aa9f933c8d2 | 105 | return obj2 - obj1; |
| TMBOY | 45:2aa9f933c8d2 | 106 | } |
| TMBOY | 45:2aa9f933c8d2 | 107 | }); |
| TMBOY | 45:2aa9f933c8d2 | 108 | |
| TMBOY | 45:2aa9f933c8d2 | 109 | /** |
| TMBOY | 45:2aa9f933c8d2 | 110 | * 播放信息 |
| TMBOY | 45:2aa9f933c8d2 | 111 | */ |
| TMBOY | 45:2aa9f933c8d2 | 112 | protected static class ChannelMediaPlayerInfo { |
| TMBOY | 45:2aa9f933c8d2 | 113 | // 播放信息 |
| TMBOY | 45:2aa9f933c8d2 | 114 | IMediaPlayer.MediaResource mediaResource; |
| TMBOY | 45:2aa9f933c8d2 | 115 | // 频道名字 |
| TMBOY | 45:2aa9f933c8d2 | 116 | String channelName; |
| TMBOY | 45:2aa9f933c8d2 | 117 | // 频道优先级 |
| TMBOY | 45:2aa9f933c8d2 | 118 | int priority; |
| TMBOY | 45:2aa9f933c8d2 | 119 | // 播放器 |
| TMBOY | 45:2aa9f933c8d2 | 120 | IMediaPlayer mediaPlayer; |
| TMBOY | 45:2aa9f933c8d2 | 121 | } |
| TMBOY | 45:2aa9f933c8d2 | 122 | |
| TMBOY | 45:2aa9f933c8d2 | 123 | /** |
| TMBOY | 45:2aa9f933c8d2 | 124 | * 获取控制音量,静音等操作的实例 |
| TMBOY | 45:2aa9f933c8d2 | 125 | * |
| TMBOY | 45:2aa9f933c8d2 | 126 | * @return ISpeakerController |
| TMBOY | 45:2aa9f933c8d2 | 127 | */ |
| TMBOY | 45:2aa9f933c8d2 | 128 | public ISpeakerController getSpeakerController() { |
| TMBOY | 45:2aa9f933c8d2 | 129 | return new SpeakerControllerImpl(); |
| TMBOY | 45:2aa9f933c8d2 | 130 | } |
| TMBOY | 45:2aa9f933c8d2 | 131 | |
| TMBOY | 45:2aa9f933c8d2 | 132 | /** |
| TMBOY | 45:2aa9f933c8d2 | 133 | * 暂停所有的mediaPlayer播放 |
| TMBOY | 45:2aa9f933c8d2 | 134 | */ |
| TMBOY | 45:2aa9f933c8d2 | 135 | private void pauseAll() { |
| TMBOY | 45:2aa9f933c8d2 | 136 | // 需要暂停所有的播放,有可能没有requestDialogId的指令正在speaking |
| TMBOY | 45:2aa9f933c8d2 | 137 | Iterator<Map.Entry<String, ChannelMediaPlayerInfo>> it = mediaPlayers.entrySet().iterator(); |
| TMBOY | 45:2aa9f933c8d2 | 138 | while (it.hasNext()) { |
| TMBOY | 45:2aa9f933c8d2 | 139 | Map.Entry<String, ChannelMediaPlayerInfo> entry = it.next(); |
| TMBOY | 45:2aa9f933c8d2 | 140 | ChannelMediaPlayerInfo value = entry.getValue(); |
| TMBOY | 45:2aa9f933c8d2 | 141 | value.mediaPlayer.pause(); |
| TMBOY | 45:2aa9f933c8d2 | 142 | } |
| TMBOY | 45:2aa9f933c8d2 | 143 | } |
| TMBOY | 45:2aa9f933c8d2 | 144 | |
| TMBOY | 45:2aa9f933c8d2 | 145 | private void stop(String channelName) { |
| TMBOY | 45:2aa9f933c8d2 | 146 | IMediaPlayer mediaPlayer = getMediaPlayer(channelName); |
| TMBOY | 45:2aa9f933c8d2 | 147 | if (mediaPlayer != null) { |
| TMBOY | 45:2aa9f933c8d2 | 148 | mediaPlayer.stop(); |
| TMBOY | 45:2aa9f933c8d2 | 149 | } |
| TMBOY | 45:2aa9f933c8d2 | 150 | } |
| TMBOY | 45:2aa9f933c8d2 | 151 | |
| TMBOY | 45:2aa9f933c8d2 | 152 | /** |
| TMBOY | 45:2aa9f933c8d2 | 153 | * 设置所有频道的mediaPlayer的音量 |
| TMBOY | 45:2aa9f933c8d2 | 154 | * |
| TMBOY | 45:2aa9f933c8d2 | 155 | * @param volume 音量 0-1 |
| TMBOY | 45:2aa9f933c8d2 | 156 | */ |
| TMBOY | 45:2aa9f933c8d2 | 157 | private void setVolumeAll(float volume) { |
| TMBOY | 45:2aa9f933c8d2 | 158 | Iterator<Map.Entry<String, ChannelMediaPlayerInfo>> it = mediaPlayers.entrySet().iterator(); |
| TMBOY | 45:2aa9f933c8d2 | 159 | while (it.hasNext()) { |
| TMBOY | 45:2aa9f933c8d2 | 160 | Map.Entry<String, ChannelMediaPlayerInfo> entry = it.next(); |
| TMBOY | 45:2aa9f933c8d2 | 161 | ChannelMediaPlayerInfo info = entry.getValue(); |
| TMBOY | 45:2aa9f933c8d2 | 162 | info.mediaPlayer.setVolume(volume); |
| TMBOY | 45:2aa9f933c8d2 | 163 | } |
| TMBOY | 45:2aa9f933c8d2 | 164 | } |
| TMBOY | 45:2aa9f933c8d2 | 165 | |
| TMBOY | 45:2aa9f933c8d2 | 166 | /** |
| TMBOY | 45:2aa9f933c8d2 | 167 | * 获取最高优先级的音量 |
| TMBOY | 45:2aa9f933c8d2 | 168 | * |
| TMBOY | 45:2aa9f933c8d2 | 169 | * @return float 0-1 |
| TMBOY | 45:2aa9f933c8d2 | 170 | */ |
| TMBOY | 45:2aa9f933c8d2 | 171 | private float getVolumeTopPriority() { |
| TMBOY | 45:2aa9f933c8d2 | 172 | Iterator<Map.Entry<String, ChannelMediaPlayerInfo>> it = mediaPlayers.entrySet().iterator(); |
| TMBOY | 45:2aa9f933c8d2 | 173 | if (it.hasNext()) { |
| TMBOY | 45:2aa9f933c8d2 | 174 | Map.Entry<String, ChannelMediaPlayerInfo> entry = it.next(); |
| TMBOY | 45:2aa9f933c8d2 | 175 | ChannelMediaPlayerInfo info = entry.getValue(); |
| TMBOY | 45:2aa9f933c8d2 | 176 | return info.mediaPlayer.getVolume(); |
| TMBOY | 45:2aa9f933c8d2 | 177 | } |
| TMBOY | 45:2aa9f933c8d2 | 178 | return 0; |
| TMBOY | 45:2aa9f933c8d2 | 179 | } |
| TMBOY | 45:2aa9f933c8d2 | 180 | |
| TMBOY | 45:2aa9f933c8d2 | 181 | /** |
| TMBOY | 45:2aa9f933c8d2 | 182 | * 设置所有频道的mediaPlayer静音状态 |
| TMBOY | 45:2aa9f933c8d2 | 183 | * |
| TMBOY | 45:2aa9f933c8d2 | 184 | * @param mute 静音状态 |
| TMBOY | 45:2aa9f933c8d2 | 185 | */ |
| TMBOY | 45:2aa9f933c8d2 | 186 | private void setMuteAll(boolean mute) { |
| TMBOY | 45:2aa9f933c8d2 | 187 | Iterator<Map.Entry<String, ChannelMediaPlayerInfo>> it = mediaPlayers.entrySet().iterator(); |
| TMBOY | 45:2aa9f933c8d2 | 188 | while (it.hasNext()) { |
| TMBOY | 45:2aa9f933c8d2 | 189 | Map.Entry<String, ChannelMediaPlayerInfo> entry = it.next(); |
| TMBOY | 45:2aa9f933c8d2 | 190 | ChannelMediaPlayerInfo info = entry.getValue(); |
| TMBOY | 45:2aa9f933c8d2 | 191 | info.mediaPlayer.setMute(mute); |
| TMBOY | 45:2aa9f933c8d2 | 192 | } |
| TMBOY | 45:2aa9f933c8d2 | 193 | } |
| TMBOY | 45:2aa9f933c8d2 | 194 | |
| TMBOY | 45:2aa9f933c8d2 | 195 | /** |
| TMBOY | 45:2aa9f933c8d2 | 196 | * 获取最高优先级的mediaPlayer静音状态 |
| TMBOY | 45:2aa9f933c8d2 | 197 | * |
| TMBOY | 45:2aa9f933c8d2 | 198 | * @return true 静音,false 非静音 |
| TMBOY | 45:2aa9f933c8d2 | 199 | */ |
| TMBOY | 45:2aa9f933c8d2 | 200 | private boolean getMuteTopPriority() { |
| TMBOY | 45:2aa9f933c8d2 | 201 | Iterator<Map.Entry<String, ChannelMediaPlayerInfo>> it = mediaPlayers.entrySet().iterator(); |
| TMBOY | 45:2aa9f933c8d2 | 202 | if (it.hasNext()) { |
| TMBOY | 45:2aa9f933c8d2 | 203 | Map.Entry<String, ChannelMediaPlayerInfo> entry = it.next(); |
| TMBOY | 45:2aa9f933c8d2 | 204 | ChannelMediaPlayerInfo info = entry.getValue(); |
| TMBOY | 45:2aa9f933c8d2 | 205 | return info.mediaPlayer.getMute(); |
| TMBOY | 45:2aa9f933c8d2 | 206 | } |
| TMBOY | 45:2aa9f933c8d2 | 207 | return false; |
| TMBOY | 45:2aa9f933c8d2 | 208 | } |
| TMBOY | 45:2aa9f933c8d2 | 209 | |
| TMBOY | 45:2aa9f933c8d2 | 210 | protected void findToPlay() { |
| TMBOY | 45:2aa9f933c8d2 | 211 | LogUtil.d(TAG, "findToPlay"); |
| TMBOY | 45:2aa9f933c8d2 | 212 | // 找到最高优先级的重新播放 |
| TMBOY | 45:2aa9f933c8d2 | 213 | Iterator<Map.Entry<Integer, ChannelMediaPlayerInfo>> it = currentPlayMap.entrySet().iterator(); |
| TMBOY | 45:2aa9f933c8d2 | 214 | if (!it.hasNext()) { |
| TMBOY | 45:2aa9f933c8d2 | 215 | return; |
| TMBOY | 45:2aa9f933c8d2 | 216 | } |
| TMBOY | 45:2aa9f933c8d2 | 217 | Map.Entry<Integer, ChannelMediaPlayerInfo> entry = it.next(); |
| TMBOY | 45:2aa9f933c8d2 | 218 | ChannelMediaPlayerInfo info = entry.getValue(); |
| TMBOY | 45:2aa9f933c8d2 | 219 | LogUtil.d(TAG, "findToPlay-channelName:" + info.channelName); |
| TMBOY | 45:2aa9f933c8d2 | 220 | if (info.mediaPlayer.getPlayState() == IMediaPlayer.PlayState.PAUSED) { |
| TMBOY | 45:2aa9f933c8d2 | 221 | LogUtil.d(TAG, "findToPlay-value-resume:" + info.priority); |
| TMBOY | 45:2aa9f933c8d2 | 222 | info.mediaPlayer.resume(); |
| TMBOY | 45:2aa9f933c8d2 | 223 | } else { |
| TMBOY | 45:2aa9f933c8d2 | 224 | LogUtil.d(TAG, "findToPlay-PlayState:" + info.mediaPlayer.getPlayState()); |
| TMBOY | 45:2aa9f933c8d2 | 225 | // 不是处于正在播放或者准备播放中或者准备完成,开始播放 |
| TMBOY | 45:2aa9f933c8d2 | 226 | if (info.mediaPlayer.getPlayState() != IMediaPlayer.PlayState.PLAYING |
| TMBOY | 45:2aa9f933c8d2 | 227 | && info.mediaPlayer.getPlayState() != IMediaPlayer.PlayState.PREPARING |
| TMBOY | 45:2aa9f933c8d2 | 228 | && info.mediaPlayer.getPlayState() != IMediaPlayer.PlayState.PREPARED) { |
| TMBOY | 45:2aa9f933c8d2 | 229 | LogUtil.d(TAG, "findToPlay-value-play:" + info.priority); |
| TMBOY | 45:2aa9f933c8d2 | 230 | info.mediaPlayer.play(info.mediaResource); |
| TMBOY | 45:2aa9f933c8d2 | 231 | } else { |
| TMBOY | 45:2aa9f933c8d2 | 232 | LogUtil.d(TAG, "findToPlay-value-isPlaying-false:" + info.priority); |
| TMBOY | 45:2aa9f933c8d2 | 233 | } |
| TMBOY | 45:2aa9f933c8d2 | 234 | } |
| TMBOY | 45:2aa9f933c8d2 | 235 | } |
| TMBOY | 45:2aa9f933c8d2 | 236 | |
| TMBOY | 45:2aa9f933c8d2 | 237 | private final class ListenerProxy extends IMediaPlayer.SimpleMediaPlayerListener { |
| TMBOY | 45:2aa9f933c8d2 | 238 | private String channelName; |
| TMBOY | 45:2aa9f933c8d2 | 239 | |
| TMBOY | 45:2aa9f933c8d2 | 240 | ListenerProxy(String channelName) { |
| TMBOY | 45:2aa9f933c8d2 | 241 | this.channelName = channelName; |
| TMBOY | 45:2aa9f933c8d2 | 242 | } |
| TMBOY | 45:2aa9f933c8d2 | 243 | |
| TMBOY | 45:2aa9f933c8d2 | 244 | @Override |
| TMBOY | 45:2aa9f933c8d2 | 245 | public void onStopped() { |
| TMBOY | 45:2aa9f933c8d2 | 246 | super.onStopped(); |
| TMBOY | 45:2aa9f933c8d2 | 247 | // stop 后就删除不需要播放了 |
| TMBOY | 45:2aa9f933c8d2 | 248 | int priority = getPriorityByChannelName(channelName); |
| TMBOY | 45:2aa9f933c8d2 | 249 | LogUtil.d(TAG, "ListenerProxy onStopped del:" + channelName); |
| TMBOY | 45:2aa9f933c8d2 | 250 | if (priority != UNKNOWN_PRIORITY) { |
| TMBOY | 45:2aa9f933c8d2 | 251 | currentPlayMap.remove(priority); |
| TMBOY | 45:2aa9f933c8d2 | 252 | } |
| TMBOY | 45:2aa9f933c8d2 | 253 | LogUtil.d(TAG, "ListenerProxy onStopped after del :" + currentPlayMap.size()); |
| TMBOY | 45:2aa9f933c8d2 | 254 | } |
| TMBOY | 45:2aa9f933c8d2 | 255 | |
| TMBOY | 45:2aa9f933c8d2 | 256 | @Override |
| TMBOY | 45:2aa9f933c8d2 | 257 | public void onCompletion() { |
| TMBOY | 45:2aa9f933c8d2 | 258 | super.onCompletion(); |
| TMBOY | 45:2aa9f933c8d2 | 259 | LogUtil.d(TAG, "ListenerProxy onCompletion,channelName:" + channelName); |
| TMBOY | 45:2aa9f933c8d2 | 260 | // 删除当前的 |
| TMBOY | 45:2aa9f933c8d2 | 261 | int priority = BaseMultiChannelMediaPlayer.this.getPriorityByChannelName(channelName); |
| TMBOY | 45:2aa9f933c8d2 | 262 | if (priority != UNKNOWN_PRIORITY) { |
| TMBOY | 45:2aa9f933c8d2 | 263 | currentPlayMap.remove(priority); |
| TMBOY | 45:2aa9f933c8d2 | 264 | } |
| TMBOY | 45:2aa9f933c8d2 | 265 | } |
| TMBOY | 45:2aa9f933c8d2 | 266 | } |
| TMBOY | 45:2aa9f933c8d2 | 267 | |
| TMBOY | 45:2aa9f933c8d2 | 268 | /** |
| TMBOY | 45:2aa9f933c8d2 | 269 | * 带有优先级信息的IMediaPlayer |
| TMBOY | 45:2aa9f933c8d2 | 270 | */ |
| TMBOY | 45:2aa9f933c8d2 | 271 | private final class ChannelMediaPlayer implements IMediaPlayer { |
| TMBOY | 45:2aa9f933c8d2 | 272 | private ChannelMediaPlayerInfo mediaPlayerInfo; |
| TMBOY | 45:2aa9f933c8d2 | 273 | private String channelName; |
| TMBOY | 45:2aa9f933c8d2 | 274 | private IMediaPlayer mediaPlayer; |
| TMBOY | 45:2aa9f933c8d2 | 275 | |
| TMBOY | 45:2aa9f933c8d2 | 276 | ChannelMediaPlayer(ChannelMediaPlayerInfo info) { |
| TMBOY | 45:2aa9f933c8d2 | 277 | this.mediaPlayerInfo = info; |
| TMBOY | 45:2aa9f933c8d2 | 278 | this.channelName = mediaPlayerInfo.channelName; |
| TMBOY | 45:2aa9f933c8d2 | 279 | this.mediaPlayer = mediaPlayerInfo.mediaPlayer; |
| TMBOY | 45:2aa9f933c8d2 | 280 | } |
| TMBOY | 45:2aa9f933c8d2 | 281 | |
| TMBOY | 45:2aa9f933c8d2 | 282 | @Override |
| TMBOY | 45:2aa9f933c8d2 | 283 | public void play(MediaResource mediaResource) { |
| TMBOY | 45:2aa9f933c8d2 | 284 | LogUtil.d(TAG, "ChannelMediaPlayer-play,will handlePlay"); |
| TMBOY | 45:2aa9f933c8d2 | 285 | BaseMultiChannelMediaPlayer.this.handlePlay(channelName, mediaResource); |
| TMBOY | 45:2aa9f933c8d2 | 286 | } |
| TMBOY | 45:2aa9f933c8d2 | 287 | |
| TMBOY | 45:2aa9f933c8d2 | 288 | @Override |
| TMBOY | 45:2aa9f933c8d2 | 289 | public void pause() { |
| TMBOY | 45:2aa9f933c8d2 | 290 | mediaPlayer.pause(); |
| TMBOY | 45:2aa9f933c8d2 | 291 | } |
| TMBOY | 45:2aa9f933c8d2 | 292 | |
| TMBOY | 45:2aa9f933c8d2 | 293 | @Override |
| TMBOY | 45:2aa9f933c8d2 | 294 | public void stop() { |
| TMBOY | 45:2aa9f933c8d2 | 295 | LogUtil.d(TAG, "ChannelMediaPlayer-stop-channelName:" + channelName); |
| TMBOY | 45:2aa9f933c8d2 | 296 | BaseMultiChannelMediaPlayer.this.handleStop(channelName); |
| TMBOY | 45:2aa9f933c8d2 | 297 | } |
| TMBOY | 45:2aa9f933c8d2 | 298 | |
| TMBOY | 45:2aa9f933c8d2 | 299 | @Override |
| TMBOY | 45:2aa9f933c8d2 | 300 | public void resume() { |
| TMBOY | 45:2aa9f933c8d2 | 301 | mediaPlayer.resume(); |
| TMBOY | 45:2aa9f933c8d2 | 302 | } |
| TMBOY | 45:2aa9f933c8d2 | 303 | |
| TMBOY | 45:2aa9f933c8d2 | 304 | @Override |
| TMBOY | 45:2aa9f933c8d2 | 305 | public void seekTo(int milliseconds) { |
| TMBOY | 45:2aa9f933c8d2 | 306 | mediaPlayer.seekTo(milliseconds); |
| TMBOY | 45:2aa9f933c8d2 | 307 | } |
| TMBOY | 45:2aa9f933c8d2 | 308 | |
| TMBOY | 45:2aa9f933c8d2 | 309 | @Override |
| TMBOY | 45:2aa9f933c8d2 | 310 | public void release() { |
| TMBOY | 45:2aa9f933c8d2 | 311 | mediaPlayer.release(); |
| TMBOY | 45:2aa9f933c8d2 | 312 | } |
| TMBOY | 45:2aa9f933c8d2 | 313 | |
| TMBOY | 45:2aa9f933c8d2 | 314 | @Override |
| TMBOY | 45:2aa9f933c8d2 | 315 | public PlayState getPlayState() { |
| TMBOY | 45:2aa9f933c8d2 | 316 | return mediaPlayer.getPlayState(); |
| TMBOY | 45:2aa9f933c8d2 | 317 | } |
| TMBOY | 45:2aa9f933c8d2 | 318 | |
| TMBOY | 45:2aa9f933c8d2 | 319 | @Override |
| TMBOY | 45:2aa9f933c8d2 | 320 | public void setVolume(float volume) { |
| TMBOY | 45:2aa9f933c8d2 | 321 | mediaPlayer.setVolume(volume); |
| TMBOY | 45:2aa9f933c8d2 | 322 | } |
| TMBOY | 45:2aa9f933c8d2 | 323 | |
| TMBOY | 45:2aa9f933c8d2 | 324 | @Override |
| TMBOY | 45:2aa9f933c8d2 | 325 | public float getVolume() { |
| TMBOY | 45:2aa9f933c8d2 | 326 | return mediaPlayer.getVolume(); |
| TMBOY | 45:2aa9f933c8d2 | 327 | } |
| TMBOY | 45:2aa9f933c8d2 | 328 | |
| TMBOY | 45:2aa9f933c8d2 | 329 | @Override |
| TMBOY | 45:2aa9f933c8d2 | 330 | public void setMute(boolean mute) { |
| TMBOY | 45:2aa9f933c8d2 | 331 | mediaPlayer.setMute(mute); |
| TMBOY | 45:2aa9f933c8d2 | 332 | } |
| TMBOY | 45:2aa9f933c8d2 | 333 | |
| TMBOY | 45:2aa9f933c8d2 | 334 | @Override |
| TMBOY | 45:2aa9f933c8d2 | 335 | public boolean getMute() { |
| TMBOY | 45:2aa9f933c8d2 | 336 | return mediaPlayer.getMute(); |
| TMBOY | 45:2aa9f933c8d2 | 337 | } |
| TMBOY | 45:2aa9f933c8d2 | 338 | |
| TMBOY | 45:2aa9f933c8d2 | 339 | @Override |
| TMBOY | 45:2aa9f933c8d2 | 340 | public long getCurrentPosition() { |
| TMBOY | 45:2aa9f933c8d2 | 341 | return mediaPlayer.getCurrentPosition(); |
| TMBOY | 45:2aa9f933c8d2 | 342 | } |
| TMBOY | 45:2aa9f933c8d2 | 343 | |
| TMBOY | 45:2aa9f933c8d2 | 344 | @Override |
| TMBOY | 45:2aa9f933c8d2 | 345 | public long getDuration() { |
| TMBOY | 45:2aa9f933c8d2 | 346 | return mediaPlayer.getDuration(); |
| TMBOY | 45:2aa9f933c8d2 | 347 | } |
| TMBOY | 45:2aa9f933c8d2 | 348 | |
| TMBOY | 45:2aa9f933c8d2 | 349 | @Override |
| TMBOY | 45:2aa9f933c8d2 | 350 | public float getBufferPercentage() { |
| TMBOY | 45:2aa9f933c8d2 | 351 | return mediaPlayer.getBufferPercentage(); |
| TMBOY | 45:2aa9f933c8d2 | 352 | } |
| TMBOY | 45:2aa9f933c8d2 | 353 | |
| TMBOY | 45:2aa9f933c8d2 | 354 | @Override |
| TMBOY | 45:2aa9f933c8d2 | 355 | public void addMediaPlayerListener(IMediaPlayerListener listener) { |
| TMBOY | 45:2aa9f933c8d2 | 356 | // 注意add的顺序 |
| TMBOY | 45:2aa9f933c8d2 | 357 | // 先1后2的目的是播放完要先从等待播放map中删除对应改成播放完的那一条。 |
| TMBOY | 45:2aa9f933c8d2 | 358 | // 1.先add wrappedListener |
| TMBOY | 45:2aa9f933c8d2 | 359 | IMediaPlayerListener wrappedListener = |
| TMBOY | 45:2aa9f933c8d2 | 360 | new ListenerProxy(channelName); |
| TMBOY | 45:2aa9f933c8d2 | 361 | mediaPlayer.addMediaPlayerListener(wrappedListener); |
| TMBOY | 45:2aa9f933c8d2 | 362 | |
| TMBOY | 45:2aa9f933c8d2 | 363 | // 2.再addDeviceModule通知到DeviceModule |
| TMBOY | 45:2aa9f933c8d2 | 364 | mediaPlayer.addMediaPlayerListener(listener); |
| TMBOY | 45:2aa9f933c8d2 | 365 | } |
| TMBOY | 45:2aa9f933c8d2 | 366 | |
| TMBOY | 45:2aa9f933c8d2 | 367 | @Override |
| TMBOY | 45:2aa9f933c8d2 | 368 | public void removeMediaPlayerListener(IMediaPlayerListener listener) { |
| TMBOY | 45:2aa9f933c8d2 | 369 | mediaPlayer.removeMediaPlayerListener(listener); |
| TMBOY | 45:2aa9f933c8d2 | 370 | } |
| TMBOY | 45:2aa9f933c8d2 | 371 | |
| TMBOY | 45:2aa9f933c8d2 | 372 | @Override |
| TMBOY | 45:2aa9f933c8d2 | 373 | public void setActive(boolean isActive) { |
| TMBOY | 45:2aa9f933c8d2 | 374 | LogUtil.d(TAG, "ChannelMediaPlayer-setActive-isActive:" + isActive); |
| TMBOY | 45:2aa9f933c8d2 | 375 | mediaPlayer.setActive(isActive); |
| TMBOY | 45:2aa9f933c8d2 | 376 | // 不是处于活跃频道 |
| TMBOY | 45:2aa9f933c8d2 | 377 | if (!isActive && mediaPlayer.getPlayState() != IMediaPlayer.PlayState.STOPPED) { |
| TMBOY | 45:2aa9f933c8d2 | 378 | BaseMultiChannelMediaPlayer.this.handleActive(); |
| TMBOY | 45:2aa9f933c8d2 | 379 | } |
| TMBOY | 45:2aa9f933c8d2 | 380 | } |
| TMBOY | 45:2aa9f933c8d2 | 381 | |
| TMBOY | 45:2aa9f933c8d2 | 382 | @Override |
| TMBOY | 45:2aa9f933c8d2 | 383 | public boolean isActive() { |
| TMBOY | 45:2aa9f933c8d2 | 384 | return mediaPlayer.isActive(); |
| TMBOY | 45:2aa9f933c8d2 | 385 | } |
| TMBOY | 45:2aa9f933c8d2 | 386 | } |
| TMBOY | 45:2aa9f933c8d2 | 387 | |
| TMBOY | 45:2aa9f933c8d2 | 388 | /** |
| TMBOY | 45:2aa9f933c8d2 | 389 | * 处理停止播放 |
| TMBOY | 45:2aa9f933c8d2 | 390 | */ |
| TMBOY | 45:2aa9f933c8d2 | 391 | private void handleStop(String channelName) { |
| TMBOY | 45:2aa9f933c8d2 | 392 | stop(channelName); |
| TMBOY | 45:2aa9f933c8d2 | 393 | pauseAll(); |
| TMBOY | 45:2aa9f933c8d2 | 394 | } |
| TMBOY | 45:2aa9f933c8d2 | 395 | |
| TMBOY | 45:2aa9f933c8d2 | 396 | /** |
| TMBOY | 45:2aa9f933c8d2 | 397 | * 设置对话通道不活跃后的处理逻辑 |
| TMBOY | 45:2aa9f933c8d2 | 398 | */ |
| TMBOY | 45:2aa9f933c8d2 | 399 | private void handleActive() { |
| TMBOY | 45:2aa9f933c8d2 | 400 | // 找到最高优先级的开始播放 |
| TMBOY | 45:2aa9f933c8d2 | 401 | findToPlay(); |
| TMBOY | 45:2aa9f933c8d2 | 402 | } |
| TMBOY | 45:2aa9f933c8d2 | 403 | |
| TMBOY | 45:2aa9f933c8d2 | 404 | /** |
| TMBOY | 45:2aa9f933c8d2 | 405 | * 控制接口 |
| TMBOY | 45:2aa9f933c8d2 | 406 | */ |
| TMBOY | 45:2aa9f933c8d2 | 407 | public interface ISpeakerController { |
| TMBOY | 45:2aa9f933c8d2 | 408 | /** |
| TMBOY | 45:2aa9f933c8d2 | 409 | * 设置音量(0-1) |
| TMBOY | 45:2aa9f933c8d2 | 410 | * |
| TMBOY | 45:2aa9f933c8d2 | 411 | * @param volume 音量(0-1) |
| TMBOY | 45:2aa9f933c8d2 | 412 | */ |
| TMBOY | 45:2aa9f933c8d2 | 413 | void setVolume(float volume); |
| TMBOY | 45:2aa9f933c8d2 | 414 | |
| TMBOY | 45:2aa9f933c8d2 | 415 | /** |
| TMBOY | 45:2aa9f933c8d2 | 416 | * 获取当前最高通道的音量 |
| TMBOY | 45:2aa9f933c8d2 | 417 | * |
| TMBOY | 45:2aa9f933c8d2 | 418 | * @return 音量(0-1) |
| TMBOY | 45:2aa9f933c8d2 | 419 | */ |
| TMBOY | 45:2aa9f933c8d2 | 420 | float getVolume(); |
| TMBOY | 45:2aa9f933c8d2 | 421 | |
| TMBOY | 45:2aa9f933c8d2 | 422 | /** |
| TMBOY | 45:2aa9f933c8d2 | 423 | * 设置是否静音 |
| TMBOY | 45:2aa9f933c8d2 | 424 | * |
| TMBOY | 45:2aa9f933c8d2 | 425 | * @param mute 是否静音 |
| TMBOY | 45:2aa9f933c8d2 | 426 | */ |
| TMBOY | 45:2aa9f933c8d2 | 427 | void setMute(boolean mute); |
| TMBOY | 45:2aa9f933c8d2 | 428 | |
| TMBOY | 45:2aa9f933c8d2 | 429 | /** |
| TMBOY | 45:2aa9f933c8d2 | 430 | * 获取当前最高通道的静音状态 |
| TMBOY | 45:2aa9f933c8d2 | 431 | * |
| TMBOY | 45:2aa9f933c8d2 | 432 | * @return 静音状态,true 是静音 |
| TMBOY | 45:2aa9f933c8d2 | 433 | */ |
| TMBOY | 45:2aa9f933c8d2 | 434 | boolean getMute(); |
| TMBOY | 45:2aa9f933c8d2 | 435 | } |
| TMBOY | 45:2aa9f933c8d2 | 436 | |
| TMBOY | 45:2aa9f933c8d2 | 437 | /** |
| TMBOY | 45:2aa9f933c8d2 | 438 | * 给speak-controller 用的,控制一些音量等操作 |
| TMBOY | 45:2aa9f933c8d2 | 439 | */ |
| TMBOY | 45:2aa9f933c8d2 | 440 | private final class SpeakerControllerImpl implements ISpeakerController { |
| TMBOY | 45:2aa9f933c8d2 | 441 | |
| TMBOY | 45:2aa9f933c8d2 | 442 | @Override |
| TMBOY | 45:2aa9f933c8d2 | 443 | public void setVolume(float volume) { |
| TMBOY | 45:2aa9f933c8d2 | 444 | BaseMultiChannelMediaPlayer.this.setVolumeAll(volume); |
| TMBOY | 45:2aa9f933c8d2 | 445 | findToPlay(); |
| TMBOY | 45:2aa9f933c8d2 | 446 | } |
| TMBOY | 45:2aa9f933c8d2 | 447 | |
| TMBOY | 45:2aa9f933c8d2 | 448 | @Override |
| TMBOY | 45:2aa9f933c8d2 | 449 | public float getVolume() { |
| TMBOY | 45:2aa9f933c8d2 | 450 | return BaseMultiChannelMediaPlayer.this.getVolumeTopPriority(); |
| TMBOY | 45:2aa9f933c8d2 | 451 | } |
| TMBOY | 45:2aa9f933c8d2 | 452 | |
| TMBOY | 45:2aa9f933c8d2 | 453 | @Override |
| TMBOY | 45:2aa9f933c8d2 | 454 | public void setMute(boolean mute) { |
| TMBOY | 45:2aa9f933c8d2 | 455 | BaseMultiChannelMediaPlayer.this.setMuteAll(mute); |
| TMBOY | 45:2aa9f933c8d2 | 456 | findToPlay(); |
| TMBOY | 45:2aa9f933c8d2 | 457 | } |
| TMBOY | 45:2aa9f933c8d2 | 458 | |
| TMBOY | 45:2aa9f933c8d2 | 459 | @Override |
| TMBOY | 45:2aa9f933c8d2 | 460 | public boolean getMute() { |
| TMBOY | 45:2aa9f933c8d2 | 461 | return BaseMultiChannelMediaPlayer.this.getMuteTopPriority(); |
| TMBOY | 45:2aa9f933c8d2 | 462 | } |
| TMBOY | 45:2aa9f933c8d2 | 463 | } |
| TMBOY | 45:2aa9f933c8d2 | 464 | } |
