| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594 |
- package com.yc.music.impl;
- import android.content.Context;
- import android.content.Intent;
- import android.content.IntentFilter;
- import android.media.AudioManager;
- import android.media.MediaPlayer;
- import com.yc.music.config.MusicConstant;
- import com.yc.music.config.MusicPlayAction;
- import com.yc.music.config.PlayModeEnum;
- import com.yc.music.inter.InterPlayAudio;
- import com.yc.music.inter.OnPlayerEventListener;
- import com.yc.music.manager.AudioFocusManager;
- import com.yc.music.manager.MediaSessionManager;
- import com.yc.music.model.AudioBean;
- import com.yc.music.receiver.AudioBroadcastReceiver;
- import com.yc.music.receiver.AudioEarPhoneReceiver;
- import com.yc.music.service.PlayAudioService;
- import com.yc.music.tool.BaseAppHelper;
- import com.yc.music.tool.QuitTimerHelper;
- import com.yc.music.utils.MusicSpUtils;
- import com.yc.music.utils.NotificationHelper;
- import com.yc.videotool.VideoLogUtils;
- import java.io.IOException;
- import java.util.List;
- import java.util.Random;
- import static com.yc.music.service.PlayAudioService.UPDATE_PLAY_PROGRESS_SHOW;
- public class PlayAudioImpl implements InterPlayAudio {
- private Context context;
- private PlayAudioService service;
- /**
- * 播放进度监听器
- */
- private OnPlayerEventListener mListener;
- /**
- * 正在播放的歌曲的序号
- */
- private int mPlayingPosition = -1;
- /**
- * 正在播放的歌曲[本地|网络]
- */
- private AudioBean mPlayingMusic;
- /**
- * 音频list集合
- */
- private List<AudioBean> audioMusics;
- /**
- * 播放器
- */
- private MediaPlayer mPlayer;
- /**
- * 允许与媒体控制器、音量键、媒体按钮和传输控件交互
- */
- private MediaSessionManager mMediaSessionManager;
- /**
- * 捕获/丢弃音乐焦点处理
- */
- private AudioFocusManager mAudioFocusManager;
- /**
- * 来电/耳机拔出时暂停播放
- * 在播放时调用,在暂停时注销
- */
- private final AudioEarPhoneReceiver mNoisyReceiver = new AudioEarPhoneReceiver();
- private final IntentFilter mFilter = new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
- /**
- * 其他广播
- * 比如:屏幕灭了后再次亮了,会显示锁屏页面
- * 这个在onCreate中创建,在onDestroy中销毁
- */
- private final AudioBroadcastReceiver mAudioReceiver = new AudioBroadcastReceiver();
- /**
- * 广播接受者标识,避免多次注册广播
- */
- private boolean mReceiverTag = false;
- /**
- * 播放状态
- */
- private int mPlayState = MusicPlayAction.STATE_IDLE;
- @Override
- public void init(PlayAudioService service) {
- this.context = service;
- this.service = service;
- createMediaPlayer();
- initMediaSessionManager();
- initAudioFocusManager();
- initEarPhoneBroadcastReceiver();
- initAudioBroadcastReceiver();
- }
- @Override
- public void play(int position) {
- audioMusics = BaseAppHelper.get().getMusicList();
- if (audioMusics.isEmpty()) {
- return;
- }
- if (position < 0) {
- position = audioMusics.size() - 1;
- } else if (position >= audioMusics.size()) {
- //如果是最后一首音乐,则播放时直接播放第一首音乐
- position = 0;
- }
- mPlayingPosition = position;
- AudioBean music = audioMusics.get(mPlayingPosition);
- String id = music.getId();
- VideoLogUtils.e("PlayService"+"----id----"+ id);
- //保存当前播放的musicId,下次进来可以记录状态
- long musicId = Long.parseLong(id);
- MusicSpUtils.getInstance(MusicConstant.SP_NAME).put(MusicConstant.MUSIC_ID,musicId);
- play(music);
- }
- @Override
- public void play() {
- if (!isPreparing() && !isPausing()) {
- return;
- }
- if(mPlayingMusic==null){
- return;
- }
- if(mAudioFocusManager.requestAudioFocus()){
- if(mPlayer!=null){
- mPlayer.start();
- mPlayState = MusicPlayAction.STATE_PLAYING;
- //开始发送消息,执行进度条进度更新
- QuitTimerHelper.getInstance().getHandler().sendEmptyMessage(UPDATE_PLAY_PROGRESS_SHOW);
- if (mListener != null) {
- mListener.onPlayerStart();
- }
- //当点击播放按钮时(播放详情页面或者底部控制栏),同步通知栏中播放按钮状态
- NotificationHelper.get().showPlay(mPlayingMusic);
- //注册监听来电/耳机拔出时暂停播放广播
- if(!mReceiverTag){
- mReceiverTag = true;
- context.registerReceiver(mNoisyReceiver, mFilter);
- }
- mMediaSessionManager.updatePlaybackState();
- }
- }
- }
- @Override
- public void play(AudioBean music) {
- mPlayingMusic = music;
- createMediaPlayer();
- try {
- mPlayer.reset();
- //把音频路径传给播放器
- mPlayer.setDataSource(mPlayingMusic.getPath());
- //准备
- mPlayer.prepareAsync();
- //设置状态为准备中
- mPlayState = MusicPlayAction.STATE_PREPARING;
- //监听
- mPlayer.setOnPreparedListener(mOnPreparedListener);
- mPlayer.setOnBufferingUpdateListener(mOnBufferingUpdateListener);
- mPlayer.setOnCompletionListener(mOnCompletionListener);
- mPlayer.setOnSeekCompleteListener(mOnSeekCompleteListener);
- mPlayer.setOnErrorListener(mOnErrorListener);
- mPlayer.setOnInfoListener(mOnInfoListener);
- //当播放的时候,需要刷新界面信息
- if (mListener != null) {
- mListener.onChange(mPlayingMusic);
- }
- //更新通知栏
- NotificationHelper.get().showPlay(mPlayingMusic);
- //更新
- mMediaSessionManager.updateMetaData(mPlayingMusic);
- mMediaSessionManager.updatePlaybackState();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- @Override
- public void stop() {
- if (isDefault()) {
- return;
- }
- pause();
- if(mPlayer!=null){
- mPlayer.reset();
- mPlayState = MusicPlayAction.STATE_IDLE;
- }
- }
- @Override
- public void playPause() {
- if (isPreparing()) {
- stop();
- } else if (isPlaying()) {
- pause();
- } else if (isPausing()) {
- play();
- } else {
- play(getPlayingPosition());
- }
- }
- @Override
- public void release() {
- //放弃音频焦点
- mAudioFocusManager.abandonAudioFocus();
- mMediaSessionManager.release();
- //注销广播接收者
- context.unregisterReceiver(mAudioReceiver);
- //销毁MediaPlayer
- mPlayer.reset();
- mPlayer.release();
- mPlayer = null;
- }
- @Override
- public void pause() {
- if(mPlayer!=null){
- //暂停
- mPlayer.pause();
- //切换状态
- mPlayState = MusicPlayAction.STATE_PAUSE;
- //移除,注意一定要移除,否则一直走更新方法
- QuitTimerHelper.getInstance().getHandler().removeMessages(UPDATE_PLAY_PROGRESS_SHOW);
- //监听
- if (mListener != null) {
- mListener.onPlayerPause();
- }
- //当点击暂停按钮时(播放详情页面或者底部控制栏),同步通知栏中暂停按钮状态
- NotificationHelper.get().showPause(mPlayingMusic);
- //注销监听来电/耳机拔出时暂停播放广播
- //判断广播是否注册
- if (mReceiverTag) {
- //Tag值 赋值为false 表示该广播已被注销
- mReceiverTag = false;
- context.unregisterReceiver(mNoisyReceiver);
- }
- mMediaSessionManager.updatePlaybackState();
- }
- }
- @Override
- public void seekTo(int progress) {
- //只有当播放或者暂停的时候才允许拖动bar
- if (isPlaying() || isPausing()) {
- mPlayer.seekTo(progress);
- if(mListener!=null){
- mListener.onUpdateProgress(progress);
- }
- mMediaSessionManager.updatePlaybackState();
- }
- }
- @Override
- public void next() {
- //建议都添加这个判断
- if (audioMusics.isEmpty()) {
- return;
- }
- int playMode = MusicSpUtils.getInstance(MusicConstant.SP_NAME).getInt(MusicConstant.PLAY_MODE, 0);
- int size = audioMusics.size();
- PlayModeEnum mode = PlayModeEnum.valueOf(playMode);
- switch (mode) {
- //随机
- case SHUFFLE:
- mPlayingPosition = new Random().nextInt(size);
- play(mPlayingPosition);
- break;
- //单曲
- case SINGLE:
- play(mPlayingPosition);
- break;
- //顺序播放并且循环
- case LOOP:
- default:
- if (mPlayingPosition != size - 1) {
- // 如果不是最后一首,则还有下一首
- mPlayingPosition++;
- } else {
- // 如果是最后一首,则切换回第一首
- mPlayingPosition = 0;
- }
- VideoLogUtils.e("PlayService"+"----mPlayingPosition----"+ mPlayingPosition);
- play(mPlayingPosition);
- break;
- }
- }
- @Override
- public void prev() {
- //建议都添加这个判断
- if (audioMusics.isEmpty()) {
- return;
- }
- int playMode = MusicSpUtils.getInstance(MusicConstant.SP_NAME).getInt(MusicConstant.PLAY_MODE, 0);
- int size = audioMusics.size();
- PlayModeEnum mode = PlayModeEnum.valueOf(playMode);
- switch (mode) {
- //随机
- case SHUFFLE:
- mPlayingPosition = new Random().nextInt(size);
- play(mPlayingPosition);
- break;
- //单曲
- case SINGLE:
- play(mPlayingPosition);
- break;
- //顺序播放并且循环
- case LOOP:
- default:
- if(mPlayingPosition != 0){
- // 如果不是第一首,则还有上一首
- mPlayingPosition--;
- } else {
- // 如果没有上一首,则切换到最后一首
- mPlayingPosition = size;
- }
- play(mPlayingPosition);
- break;
- }
- }
- @Override
- public void updatePlayProgress() {
- updatePlayProgressShow();
- }
- @Override
- public void setOnPlayEventListener(OnPlayerEventListener listener) {
- mListener = listener;
- }
- /**
- * 创建MediaPlayer对象
- */
- private void createMediaPlayer() {
- if(mPlayer==null){
- //MediaCodec codec = new MediaCodec();
- mPlayer = new MediaPlayer();
- }
- }
- /** 音频准备好的监听器 */
- private MediaPlayer.OnPreparedListener mOnPreparedListener = new MediaPlayer.OnPreparedListener() {
- /** 当音频准备好可以播放了,则这个方法会被调用 */
- @Override
- public void onPrepared(MediaPlayer mp) {
- if (isPreparing()) {
- play();
- }
- }
- };
- /** 当音频播放结束的时候的监听器 */
- private MediaPlayer.OnCompletionListener mOnCompletionListener = new MediaPlayer.OnCompletionListener() {
- /** 当音频播放结果的时候这个方法会被调用 */
- @Override
- public void onCompletion(MediaPlayer mp) {
- next();
- }
- };
- /** 当音频缓冲的监听器 */
- private MediaPlayer.OnBufferingUpdateListener mOnBufferingUpdateListener = new MediaPlayer.OnBufferingUpdateListener() {
- @Override
- public void onBufferingUpdate(MediaPlayer mp, int percent) {
- if (mListener != null) {
- // 缓冲百分比
- mListener.onBufferingUpdate(percent);
- }
- }
- };
- /** 跳转完成时的监听 */
- private MediaPlayer.OnSeekCompleteListener mOnSeekCompleteListener = new MediaPlayer.OnSeekCompleteListener() {
- @Override
- public void onSeekComplete(MediaPlayer mp) {
- }
- };
- /**
- * 播放错误的监听
- */
- private MediaPlayer.OnErrorListener mOnErrorListener = new MediaPlayer.OnErrorListener() {
- @Override
- public boolean onError(MediaPlayer mp, int what, int extra) {
- return false;
- }
- };
- /**
- * 设置音频信息监听器
- */
- private MediaPlayer.OnInfoListener mOnInfoListener = new MediaPlayer.OnInfoListener() {
- @Override
- public boolean onInfo(MediaPlayer mp, int what, int extra) {
- return false;
- }
- };
- /**
- * 是否正在播放
- * @return true表示正在播放
- */
- public boolean isPlaying() {
- return mPlayState == MusicPlayAction.STATE_PLAYING;
- }
- /**
- * 是否暂停
- * @return true表示暂停
- */
- public boolean isPausing() {
- return mPlayState == MusicPlayAction.STATE_PAUSE;
- }
- /**
- * 是否正在准备中
- * @return true表示正在准备中
- */
- public boolean isPreparing() {
- return mPlayState == MusicPlayAction.STATE_PREPARING;
- }
- /**
- * 是否正在准备中
- * @return true表示正在准备中
- */
- public boolean isDefault() {
- return mPlayState == MusicPlayAction.STATE_IDLE;
- }
- /**
- * 更新播放进度的显示,时间的显示
- */
- private void updatePlayProgressShow() {
- if (isPlaying() && mListener != null) {
- int currentPosition = mPlayer.getCurrentPosition();
- mListener.onUpdateProgress(currentPosition);
- }
- VideoLogUtils.e("updatePlayProgressShow");
- // 每30毫秒更新一下显示的内容,注意这里时间不要太短,因为这个是一个循环
- // 经过测试,60毫秒更新一次有点卡,30毫秒最为顺畅
- QuitTimerHelper.getInstance().getHandler().sendEmptyMessageDelayed(UPDATE_PLAY_PROGRESS_SHOW, 300);
- }
- /**
- * 获取正在播放的本地歌曲的序号
- */
- public int getPlayingPosition() {
- return mPlayingPosition;
- }
- /**
- * 获取正在播放的歌曲[本地|网络]
- */
- public AudioBean getPlayingMusic() {
- return mPlayingMusic;
- }
- /**
- * 获取播放的进度
- * @return long类型值
- */
- public long getCurrentPosition() {
- if (isPlaying() || isPausing()) {
- return mPlayer.getCurrentPosition();
- } else {
- return 0;
- }
- }
- /**
- * 判斷是否有上一首音頻
- * @return true表示有
- */
- public boolean isHavePre() {
- if(audioMusics !=null && audioMusics.size()>0){
- if(mPlayingPosition != 0){
- // 如果不是第一首,则还有上一首
- return true;
- } else {
- return false;
- }
- }else {
- return false;
- }
- }
- /**
- * 判斷是否有下一首音頻
- * @return true表示有
- */
- public boolean isHaveNext() {
- if(audioMusics !=null && audioMusics.size()>0){
- if (mPlayingPosition != audioMusics.size() - 1) {
- // 如果不是最后一首,则还有下一首
- return true;
- } else {
- // 如果是最后一首,则切换回第一首
- return false;
- }
- }else {
- return false;
- }
- }
- /**------------------------------------------------------------------------------------------*/
- /**
- * 允许与媒体控制器、音量键、媒体按钮和传输控件交互。
- * 播放器除了播放了音乐之外什么都没做,就可以分别在任务管理、锁屏、负一屏控制我的播放器
- */
- private void initMediaSessionManager() {
- mMediaSessionManager = new MediaSessionManager(service);
- }
- /**
- * 捕获/丢弃音乐焦点处理
- */
- private void initAudioFocusManager() {
- mAudioFocusManager = new AudioFocusManager(service);
- }
- /**
- * 初始化耳机插入和拔出监听
- */
- private void initEarPhoneBroadcastReceiver() {
- //这块直接在清单文件注册
- }
- /**
- * 初始化IntentFilter添加action意图
- * 主要是监听屏幕亮了与灭了
- */
- private void initAudioBroadcastReceiver() {
- final IntentFilter filter = new IntentFilter();
- //来电/耳机
- filter.addAction(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
- //锁屏
- filter.addAction(MusicConstant.LOCK_SCREEN_ACTION);
- //当屏幕灭了
- filter.addAction(Intent.ACTION_SCREEN_OFF);
- //当屏幕亮了
- filter.addAction(Intent.ACTION_SCREEN_ON);
- context.registerReceiver(mAudioReceiver, filter);
- }
- /**
- * 删除或下载歌曲后刷新正在播放的本地歌曲的序号
- */
- public void updatePlayingPosition() {
- int position = 0;
- long id = MusicSpUtils.getInstance(MusicConstant.SP_NAME).getLong(MusicConstant.MUSIC_ID,-1);
- if(audioMusics.isEmpty()){
- return;
- }
- for (int i = 0; i < audioMusics.size(); i++) {
- String musicId = audioMusics.get(i).getId();
- VideoLogUtils.e("PlayService"+"----musicId----"+ musicId);
- if (Long.parseLong(musicId) == id) {
- position = i;
- break;
- }
- }
- mPlayingPosition = position;
- long musicId = Long.parseLong(audioMusics.get(mPlayingPosition).getId());
- MusicSpUtils.getInstance(MusicConstant.SP_NAME).put(MusicConstant.MUSIC_ID,musicId);
- }
- }
|