android media player实现一个可随机/顺序播放的音频播放器

Android媒体框架: https://developer.android.com/guide/topics/media-apps/audio-app/building-an-audio-app
https://developer.android.com/guide/topics/media-apps/images/audio-activity-and-service.png

    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation "com.android.support:support-media-compat:28.0.0"

服务端(媒体播放资源提供端):

  • MediaBrowserServiceCompat
  • onGetRoot
  • onLoadChildren
  • MediaSessionCompat
  • MediaSessionCompat.Token
  • MediaSessionCompat.Callback
  • MediaControllerCompat
  • MediaControllerCompat.Callback
  • PlaybackStateCompat.Builder
  • MediaPlayer

实际播放器,基于接口可被替换

  • 客户端(展示媒体进度和控制播放状态)

  • MediaBrowserCompat.ConnectionCallback
  • MediaControllerCompat.Callback
  • MediaBrowserCompat.SubscriptionCallback

单曲循环和整体循环

1.单曲循环 PlaybackStateCompat.REPEAT_MODE_ONE
2.整体循环 PlaybackStateCompat.REPEAT_MODE_ALL
3.不做循环 PlaybackStateCompat.REPEAT_MODE_NONE

随机播放和顺序播放

两者之间的联系

  1. 随机播放是否允许再次播放 顺序播放已播放过的内容
  2. 顺序播放是否允许再次播放 随机播放已播放过的内容
  3. 随机播放顺序播放 都是播放队列不循环播放模式

几个问题:

  1. 一般 顺序播放/随机播放/单曲循环/列表循环 是在一个按钮上做来回切换
    但是getRepeatMode 和 getShuffleMode是两个模式, 简单做下同步
单曲循环 = controllerCompat.getRepeatMode() == PlaybackStateCompat.REPEAT_MODE_ONE 
          && controllerCompat.getShuffleMode() == PlaybackStateCompat.SHUFFLE_MODE_NONE

if (单曲循环) { 
      controllerCompat.getTransportControls().setShuffleMode(PlaybackStateCompat.SHUFFLE_MODE_NONE);
      controllerCompat.getTransportControls().setRepeatMode(PlaybackStateCompat.REPEAT_MODE_ONE);
}  

点击按钮循环模式切换和应用
shuffleIndex = (++shuffleIndex % shuffleConfigMapSize);

点击按钮切换的配置列表
 private void defaultShuffleConfig(MediaControllerCompat controllerCompat) {
        playerShuffleResource.add(new ShuffleConfig(1, R.drawable.icon_play_mode_shuffle));
        playerShuffleResource.add(new ShuffleConfig(2, R.drawable.icon_play_mode_order));
        playerShuffleResource.add(new ShuffleConfig(3, R.drawable.icon_play_cycle_one));
        playerShuffleResource.add(new ShuffleConfig(4, R.drawable.icon_play_cycle_all));
    }
  1. 按队列后台播放时,前台会触发指定的歌曲播放
  1. 如果指定的歌曲在队列的某个位置,从此位置后开始继续顺序或者随机播放
  2. 如果指定的歌曲不在列表中,先插入队列,在改变播放指针
  3. sendCustomAction 播放指定的 index
private void showPlayIndex(MediaControllerCompat mediaControllerCompat) {
        Bundle bundle = getIntent().getExtras();
        if (null != bundle) {
            mediaControllerCompat.getTransportControls().sendCustomAction(AudioPlayerHelper.ACTION_INDEX, bundle);
        }
    }
  1. 随机播放和顺序播放可以是
    同一个完整的播放队列(好做同步控制,添加,删除等)
    +两个播放指针 + 两个播放指针记录
    +两个已播队列

  2. 无重复整体随机index方法:
    如果播放时随机的话会导致重复播放问题

  if (mShuffleList.size() >= 3) {
        int[] shuffleListIndexes = randomList(0, mShuffleList.size() - 1, mShuffleList.size());
   }
   
  public static int[] randomList(int min, int max, int n) {
       int len = max - min + 1;

       if (max < min || n > len) {
           return null;
       }

       int[] source = new int[len];
       for (int i = min; i < min + len; i++) {
           source[i - min] = i;
       }

       int[] result = new int[n];
       Random rd = new Random();
       int index = 0;
       for (int i = 0; i < result.length; i++) {
           index = Math.abs(rd.nextInt() % len--);
           result[i] = source[index];
           source[index] = source[len];
       }
       return result;
    }

代码实现

在这里插入图片描述
待整理后上传…

  1. 媒体服务之 musicService
  2. 播放展示之 musicActivity
  3. 播放展示之 musicView
  4. 播放展示之 musicProgressBar
  5. 播放展示之 musicNotification (MediaStyle)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章