Android音频播放

Posted 一杯清泉

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android音频播放相关的知识,希望对你有一定的参考价值。

        这里使用MediaPlayer来实现媒体音频的播放和相关设置,能够实现播放,暂停,停止,快进,设置声音大小,播放倍速,循环播放,播放时长,播放进度等等。

        创建媒体播放器:

MediaPlayer player = new MediaPlayer();

一、相关接口介绍

  • Runnable:用于周期性获取audio的播放进度
  • MediaPlayer.OnCompletionListener:audio播放完毕的回调
  • MediaPlayer.OnErrorListener:audio播放出错的回调
  • MediaPlayer.OnSeekCompleteListener:快进,后退的回调
  • MediaPlayer.OnBufferingUpdateListener:播放缓冲区加载的回调
  • MediaPlayer.OnPreparedListener:播放资源初始化好了的回调

        写一个类,分别实现上述接口,来实现audio的相关功能。

二、开始播放

public void play(String callback) {
    if (!checkArgument(callback)) {
        return;
    }
    try {
        player.reset();
        player.setAudiostreamType(AudioManager.STREAM_MUSIC);
        player.setDataSource(data.src);
        player.setLooping(data.loop);
        setVolume();
        setPlaybackRate();
        player.setOnPreparedListener(this);
        player.prepare();
    } catch (IOException e) {
        LogUtils.d("播放出错:" + e.getMessage());
    }
}

1、player.reset()

重置播放器

2、setAudioStreamType

AudioManager.STREAM_MUSIC:播放音乐模式,其他模式参考API源码

3、setDataSource

设置播放资源,可以设置本地资源和网络资源

4、setLooping

是否循环播放

5、setVolume

设置播放的声音大小,0-1之间,0表示没声音,1表示声音最大

private void setVolume() {
    float volume = getFloat(data.volume, 1);
    if (volume >= 0 && volume <= 1) {
        player.setVolume(volume, volume);
    }
}

public float getFloat(String value, float defaultValue) {
    if (TextUtils.isEmpty(value)) {
        return defaultValue;
    }
    if (StringUtils.isNumber(value)) {
        return Float.parseFloat(value);
    }
    return defaultValue;
}

6、setPlaybackRate

设置播放倍速,这里设置0.5倍速到2倍速播放

private void setPlaybackRate() {
    float playbackRate = getFloat(data.playbackRate, 1);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && playbackRate >= 0.5 && playbackRate <= 2.0) {
        PlaybackParams params = player.getPlaybackParams();
        params.setSpeed(playbackRate);
        player.setPlaybackParams(params);
    }
}

7、player.prepare()

调用该方法,会触发onPrepared回调,在这里面播放和注册其他回调。

@Override
public void onPrepared(MediaPlayer mp) {
    LogUtils.d("开始播放");
    setSeek(data.startTime);
    player.start();
    //获取播放时长,每隔一秒回调一次
    duration = mp.getDuration();
    //监听进度
    handler.postDelayed(JsAudioHelper.this, 1000);
    //监听播放完毕
    player.setOnCompletionListener(JsAudioHelper.this);
    //监听播放错误
    player.setOnErrorListener(JsAudioHelper.this);
    //监听进度
    player.setOnSeekCompleteListener(JsAudioHelper.this);
    //监听buff
    player.setOnBufferingUpdateListener(JsAudioHelper.this);
}

 setSeek(data.startTime):设置开始播放的时间位置,单位秒 


private void setSeek(String position) {
    int pos = StringUtils.getInteger(position, 0);
    if (pos > 0) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            player.seekTo(pos * 1000, MediaPlayer.SEEK_CLOSEST);
        } else {
            player.seekTo(pos * 1000);
        }
    }
}

三、暂停播放

public void pause() {
    if (!isPaused()) {
        player.pause();
    }
    callBackYes(onPlayCallback);
    LogUtils.d("暂停");
}

四、停止播放

public void stop() {
    player.stop();
    handler.removeCallbacksAndMessages(null);
    currentTime = 0;
    callBackYes(onStopCallback);
    LogUtils.d("停止");
}

五、是否在播放

public boolean isPaused() {
    return !player.isPlaying();
}

六、获取当前的播放进度

@Override
public void run() {
    if (currentTime > player.getCurrentPosition()) {
        //暂停的时候player.getCurrentPosition为0
        return;
    }
    currentTime = player.getCurrentPosition();
    int percent = (int) Math.ceil(currentTime * 100f / duration);
    LogUtils.d("进度百分比:" + percent + " %");
    LogUtils.d("当前时间:" + calculateTime(currentTime / 1000));
    LogUtils.d("总时间:" + calculateTime(duration / 1000));
    if (percent == 100) {
        handler.removeCallbacks(this);
        currentTime = 0;
    } else {
        handler.postDelayed(this, 1000);
    }
}
public String calculateTime(int time) {
    int minute;
    int second;
    if (time > 60) {
        minute = time / 60;
        second = time % 60;
        //分钟再0~9
        if (minute >= 0 && minute < 10) {
            //判断秒
            if (second >= 0 && second < 10) {
                return "0" + minute + ":" + "0" + second;
            } else {
                return "0" + minute + ":" + second;
            }
        } else {
            //分钟大于10再判断秒
            if (second >= 0 && second < 10) {
                return minute + ":" + "0" + second;
            } else {
                return minute + ":" + second;
            }
        }
    } else if (time < 60) {
        second = time;
        if (second >= 0 && second < 10) {
            return "00:" + "0" + second;
        } else {
            return "00:" + second;
        }
    }
    return "";
}

七、是否播放资源

public void destroy() {
    stop();
    player.release();
    LogUtils.d("销毁");
}

        2021年7月19日于重庆渝北区酒店(出差)!!!

 

以上是关于Android音频播放的主要内容,如果未能解决你的问题,请参考以下文章

在 IOS 中,如何乱序播放音频片段的一部分?

Android OpenGLES3绘图 - 音频可视化(模仿MIUI系统效果)

蓝牙延迟和 Android 音频提示

无法对非静态方法 getAssets() 进行静态引用 - 无法在片段中播放音频

从 url 中提取音频片段并使用纯 Web Audio API 播放

使用主播放列表时,HLS.js 一次加载所有子片段