Android MediaPlayer 播放音频的方式

作者:Android_note 时间:2021-09-07 07:27:09 

主要介绍使用MediaPlayer播放音频的方式。关于MediaPlayer的基础知识,比如状态,可以参考Android MediaPlayer 基础简介。

为了方便表达,定义变量名为mediaPlayer。

MediaPlayer的使用方式

创建MediaPlayer

可以直接 new MediaPlayer,也可以用MediaPlayer提供的create方法创建。

mediaPlayer = new MediaPlayer();

使用create方法创建成功后,mediaPlayer处于Prepared状态。可以直接start播放。


mediaPlayer = MediaPlayer.create(getApplicationContext(), Uri.fromFile(file));
mediaPlayer.start();

设置音源 - setDataSource

通过调用setDataSource来设置音源。setDataSource有多个重载方法,我们来看常用的几种。

例如设置使用assets里的资源。实际情况可能需要try catch。


AssetFileDescriptor fd = null;
MediaPlayer mediaPlayer = new MediaPlayer();
fd = context.getApplicationContext().getAssets().openFd(name);
mediaPlayer.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength());

本地文件,需要文件的绝对路径。


mediaPlayer.setDataSource(file.getAbsolutePath());

或者获取文件的Uri来创建mediaPlayer。


mediaPlayer = MediaPlayer.create(getApplicationContext(), Uri.fromFile(file));

设置网络音频,也是用setDataSource方法,设置url。

mediaPlayer.setDataSource("https://demo.com/sample.mp3"));

播放网络音频时,如果使用的是http,有可能会报错


java.io.IOException: Cleartext HTTP traffic to demo.com not permitted

可以简单地设置一下manifest,设置usesCleartextTraffic=”true”


<application
android:usesCleartextTraffic="true">

准备 - prepare

同步和异步准备音频资源。prepareAsync()是异步的方式,prepare是同步的。注意线程调度问题,同时不要阻塞UI线程。

使用异步方式准备音频,经常与MediaPlayer.OnPreparedListener * 配合使用。异步准备时,也可以进行其他的设置。


mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
mediaPlayer.start(); // 准备好了就播放
}
});

循环播放 - Looping

设置循环播放setLooping。

mediaPlayer.setLooping(true);

播放完毕后,不会回调OnCompletionListener,而是从头播放当前音频。

播放 - start

播放音频,调用start方法。

mediaPlayer.start();

处于Prepared,Pause和PlaybackComplete状态时,可以调用start方法,进入Started状态。

暂停 - pause

暂停播放,使用pause方法。在暂停前先判断一下mediaPlayer的是否在播放。


if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
}

 

暂停成功则处于Paused状态。

停止 - stop

回顾一下MediaPlayer状态切换的图示,我们可以得知在播放中,暂停,播放完成这3个状态下,可以调用stop方法,进入Stopped状态。

mediaPlayer.stop();

调进度 - seekTo

调整播放进度。我们平时使用音乐播放软件一般都会有这个功能。
seekTo方法接受一个毫秒参数。


int targetMS = (int) (percent * mediaPlayer.getDuration());
mediaPlayer.seekTo(targetMS);

 

seekTo并不会改变MediaPlayer的状态。


int targetMS = (int) (percent * mediaPlayer.getDuration());
mediaPlayer.seekTo(targetMS);

reset后的mediaPlayer进入Idle状态。需要重新设置音源与准备。

释放 - release

不再使用这个mediaPlayer时,应当尽快释放掉,以释放相关的资源。

调用release后,mediaPlayer进入End状态。此时这个mediaPlayer就不能再使用了。

常用 *

缓冲 * OnBufferingUpdateListener

比如我们加载网络音频的时候,常用这个 * 来监听缓冲进度。显示缓冲进度,也可以提高用户体验。


mMediaPlayer.prepareAsync();
mMediaPlayer.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() {
@Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
// percent代表缓冲百分比
}
});

错误 * OnErrorListener


mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mediaPlayer, int i, int i1) {
return true; // 返回true表示在此处理错误,不会回调onCompletion
}
});

注意onError的返回值。可以选择自己处理error。


* @return True if the method handled the error, false if it didn't.
* Returning false, or not having an OnErrorListener at all, will
* cause the OnCompletionListener to be called.
*/
boolean onError(MediaPlayer mp, int what, int extra);

播放完毕 * OnCompletionListener


mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
// 播放完毕
}
});

使用示例

播放assets里的音频

播放assets里的音频文件,使用到AssetFileDescriptor类。使用后记得关闭AssetFileDescriptor。


private void playAssetsAudio(final String name, Context context) {
Log.d(TAG, "playAssetWordSound: try to play assets sound file. -> " + name);
AssetFileDescriptor fd = null;
try {
MediaPlayer mediaPlayer;
Log.v(TAG, "Looking in assets.");
fd = context.getApplicationContext().getAssets().openFd(name);
mediaPlayer = new MediaPlayer();
mediaPlayer.reset();
mediaPlayer.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength());
mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
 @Override
 public void onPrepared(MediaPlayer mediaPlayer) {
 Log.d(TAG, "onPrepared: " + name);
 mediaPlayer.start();
 }
});
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
 @Override
 public void onCompletion(MediaPlayer mp) {
 mp.release();
 Log.d(TAG, "onCompletion: " + name);
 }
});
mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
 @Override
 public boolean onError(MediaPlayer mp, int i, int i1) {
 mp.release();
 return true;
 }
});
} catch (Exception e) {
try {
 if (fd != null) {
 fd.close();
 }
} catch (Exception e1) {
 Log.e(TAG, "Exception close fd: ", e1);
}
} finally {
if (fd != null) {
 try {
 fd.close();
 } catch (IOException e) {
 Log.e(TAG, "Finally, close fd ", e);
 }
}
}
}

播放本地音频文件

尝试播放音频文件。仅播放一次。


private void playAudioFile(final File file) {
Log.d(TAG, "playAudioFile: " + file.getAbsolutePath());
MediaPlayer mediaPlayer;
try {
mediaPlayer = new MediaPlayer();
mediaPlayer.setLooping(false);
mediaPlayer.setDataSource(file.getAbsolutePath());
mediaPlayer.prepare();
mediaPlayer.start();
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
 @Override
 public void onCompletion(MediaPlayer mp) {
 mp.release();
 }
});
mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
 @Override
 public boolean onError(MediaPlayer mediaPlayer, int i, int i1) {
 Log.d(TAG, "Play local sound onError: " + i + ", " + i1);
 return true;
 }
});
} catch (Exception e) {
Log.e(TAG, "playAudioFile: ", e);
}
}

播放在线音频

设置url,播放在线音频


private void playOnlineSound(String soundUrlDict) {
try {
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(soundUrlDict);
mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
 @Override
 public void onPrepared(MediaPlayer mediaPlayer) {
 mediaPlayer.start();
 }
});
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
 @Override
 public void onCompletion(MediaPlayer mp) {
 if (mp != null) {
  mp.release();
 }
 Log.d(TAG, "onCompletion: play sound.");
 }
});
mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
 @Override
 public boolean onError(MediaPlayer mediaPlayer, int i, int i1) {
 Log.d(TAG, "Play online sound onError: " + i + ", " + i1);
 return false;
 }
});
} catch (IOException e1) {
Log.e(TAG, "url: ", e1);
}
}

代码可以参考示例工程: https://github.com/RustFisher/android-MediaPlayer

总结

以上所述是小编给大家介绍的Android MediaPlayer 播放音频的方式,网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

来源:https://rustfisher.com/2019/09/22/Android/Android-MediaPlayer_use_play_audio/

标签:Android,MediaPlayer,音频
0
投稿

猜你喜欢

  • Java中如何动态创建接口的实现方法

    2023-11-25 15:13:02
  • C#实现String类型和json之间的相互转换功能示例

    2023-06-18 07:35:32
  • 理解Java当中的回调机制(翻译)

    2023-03-15 04:21:00
  • Java的Struts框架中Action的编写与拦截器的使用方法

    2021-11-22 02:58:53
  • c# 模拟串口通信 SerialPort的实现示例

    2023-09-03 22:19:50
  • spring boot 注入 property的三种方式(推荐)

    2023-01-23 05:10:27
  • java中replaceAll替换圆括号实例代码

    2023-09-30 16:29:54
  • 详解java基础--提示对话框的使用

    2023-01-31 12:11:46
  • Springboot 如何指定获取出 yml文件里面的配置值

    2022-08-29 21:04:48
  • Android Usb设备的监听(Dev)外设端口的判定以及耳机的插拔

    2022-12-07 19:23:44
  • C#中Equals和GetHashCode使用及区别

    2023-12-10 14:47:27
  • Java获取时间打印到控制台代码实例

    2022-07-20 22:43:48
  • SpringBoot整合rockerMQ消息队列详解

    2021-10-03 10:55:14
  • java简单实现用语音读txt文档方法总结

    2022-11-10 22:02:54
  • Springboot整合企业微信机器人助手推送消息的实现

    2023-08-18 08:37:37
  • JAVA回顾:封装,继承,多态

    2021-09-26 20:17:59
  • C#使用 NAudio 实现音频可视化的方法

    2022-10-07 09:31:58
  • Springboot启动流程详细分析

    2023-11-29 00:23:10
  • Spring异常捕获且回滚事务解决方案

    2023-04-25 18:32:41
  • Java数据结构之线索化二叉树的实现

    2022-03-16 15:25:34
  • asp之家 软件编程 m.aspxhome.com