Android音频开发:使用ExoPlayer播放音频
Posted 红日666
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android音频开发:使用ExoPlayer播放音频相关的知识,希望对你有一定的参考价值。
一、Android音频开发(一):音频基础知识
二、Android音频开发(二):录制音频(WAV及MP3格式)
三、Android音频开发(三):使用ExoPlayer播放音频
四、Android音频开发(四):音频播放模式
五、Android音频开发(五):感应(息屏/亮屏)管理
附GitHub源码:MultimediaExplore
备注:ExoPlayer的解码是依赖android系统提供的原生解码模块MediaCodec进行视频和音频解码的。关于ExoPlayer具体可参考:ExoPlayer
一、音频播放的权限及依赖:
音频播放可能涉及到的权限:
<uses-permission android:name="android.permission.INTERNET" />
<!--音频模式切换权限-->
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<!--唤屏/息屏权限-->
<uses-permission android:name="android.Manifest.permission.DEVICE_POWER"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
音频播放器所需依赖:
// 多媒体播放器
implementation 'com.google.android.exoplayer:exoplayer-core:2.15.0'
implementation 'com.google.android.exoplayer:exoplayer-ui:2.15.0'
implementation 'com.google.android.exoplayer:exoplayer-hls:2.15.0'
implementation 'com.google.android.exoplayer:exoplayer-dash:2.15.0'
implementation 'com.google.android.exoplayer:exoplayer-transformer:2.15.0'
implementation 'com.google.android.exoplayer:exoplayer-rtsp:2.15.0'
implementation 'com.google.android.exoplayer:exoplayer-smoothstreaming:2.15.0'
二、ExoPlayer实例生成:
生成SimpleExoPlayer实例,然后将build好的音频资源set到音频播放器即可进行播放。这里需要注意一点的是如果要获取音频的播放进度,需要生成一个如下图的handlerInner Handler实例,然后将其addEventListener中。否则如果直接使用从外部传过来的hander,所得到的音频播放进度会一直是0。
public void prepareAudioPlayer(Context context, Handler handler, Uri uri)
if (player == null)
player = new SimpleExoPlayer.Builder(context).build();
mediaSource = AudioMediaSourceManager.getInstance().buildMediaSource(uri, isLocalResource);
if (mediaSource == null || player == null)
return;
if (handlerInner == null)
handlerInner = new Handler()
@Override
public void handleMessage(Message msg)
super.handleMessage(msg);
Message msgOuter = new Message();
if (msg.what == WHAT_POSITION)
currentPosition = player.getCurrentPosition() / 1000;
contentPosition = player.getContentPosition() / 1000;
contentBufferedPosition = player.getContentBufferedPosition() / 1000;
Log.d(TAG, "-----> currentPosition:" + currentPosition + " contentPosition:" + contentPosition + " contentBufferedPosition:" + contentBufferedPosition);
HashMap<String, Long> hashMap = new HashMap<>();
hashMap.put("currentPosition", currentPosition);
hashMap.put("contentPosition", contentPosition);
hashMap.put("contentBufferedPosition", contentBufferedPosition);
msgOuter.what = WHAT_POSITION;
msgOuter.obj = hashMap;
handler.sendMessage(msgOuter);
if (currentPosition < duration)
sendEmptyMessageDelayed(WHAT_POSITION, 300);
else if (msg.what == WHAT_DURATION)
msgOuter.obj = msg.obj;
handler.sendMessage(msgOuter);
;
mediaSource.addEventListener(handlerInner, new MediaSourceEventListener()
@Override
public void onLoadStarted(int windowIndex, @Nullable MediaSource.MediaPeriodId mediaPeriodId, LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData)
Log.d(TAG, "onLoadStarted ---> duration:" + duration);
@Override
public void onLoadCompleted(int windowIndex, @Nullable MediaSource.MediaPeriodId mediaPeriodId, LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData)
mediaSource.removeEventListener(this);
//发送时长消息
duration = player.getDuration() / 1000;
Message msg = new Message();
msg.what = WHAT_DURATION;
msg.obj = duration;
handlerInner.sendMessage(msg);
//发送position消息
Message msgPos = new Message();
msgPos.what = WHAT_POSITION;
handlerInner.sendMessage(msgPos);
Log.d(TAG, "onLoadCompleted ---> duration:" + duration);
);
player.setMediaSource(mediaSource);
player.addListener(new Player.Listener()
@Override
public void onPlayWhenReadyChanged(boolean playWhenReady, int reason)
Log.d(TAG, "onPlayWhenReadyChanged---> playWhenReady:" + playWhenReady);
AudioPlayer.this.playWhenReady = playWhenReady;
@Override
public void onPlaybackStateChanged(int playbackState)
Log.d(TAG, "onPlaybackStateChanged---> playbackState:" + playbackState);
switch (playbackState)
case Player.STATE_READY:
Log.d(TAG, "STATE_READY");
break;
case Player.STATE_BUFFERING:
Log.d(TAG, "STATE_BUFFERING");
break;
case Player.STATE_ENDED:
Log.d(TAG, "STATE_ENDED");
audiostatus = AudioPlayStatus.AUDIO_STOP;
AudioModeManager.getInstance().abandonAudioFocus();
break;
case Player.STATE_IDLE:
Log.d(TAG, "STATE_IDLE");
audioStatus = AudioPlayStatus.AUDIO_IDLE;
AudioModeManager.getInstance().abandonAudioFocus();
break;
@Override
public void onIsPlayingChanged(boolean isPlaying)
Log.d(TAG, "onIsPlayingChanged---> isPlaying:" + isPlaying);
if (isPlaying)
audioStatus = AudioPlayStatus.AUDIO_START;
else
);
player.prepare();
三、音频播放生命周期方法:
public void play()
Log.d(TAG, "play");
if (player == null)
return;
AudioModeManager.getInstance().requestAudioFocus();
if (playWhenReady)
if (!player.isPlaying())
player.setPlayWhenReady(true);
else
player.prepare();
player.setPlayWhenReady(true);
audioStatus = AudioPlayStatus.AUDIO_START;
public void pause()
Log.d(TAG, "pause");
if (player == null)
return;
AudioModeManager.getInstance().abandonAudioFocus();
if (player.isPlaying())
player.pause();
audioStatus = AudioPlayStatus.AUDIO_PAUSE;
public void stop()
Log.d(TAG, "stop");
if (player == null)
return;
AudioModeManager.getInstance().abandonAudioFocus();
player.stop();
audioStatus = AudioPlayStatus.AUDIO_STOP;
public void cancel()
Log.d(TAG, "cancel");
public void release()
Log.d(TAG, "release");
if (player == null)
return;
AudioModeManager.getInstance().abandonAudioFocus();
player.release();
if (handlerInner != null)
handlerInner.removeCallbacksAndMessages(null);
audioStatus = AudioPlayStatus.AUDIO_RELEASE;
四、音频播放管理AudioPlayManager:
类似AudioRecordManager的作用,音频播放器全局单例,代码略。
以上是关于Android音频开发:使用ExoPlayer播放音频的主要内容,如果未能解决你的问题,请参考以下文章