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)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章