网络音频播放
前面有文章曾经地介绍过MediaPlayer的基本用法,这里就更加深入地讲解MediaPlayer的在线播放功能。本文主要实现MediaPlayer在线播放音频的功能,由于在线视频播放比在线音频播放复杂,因此先介绍在线音频播放的实现,这样可以帮助大家逐步深入了解MediaPlayer的在线播放功能。
先来看看本文程序运行的结果如下图所示:
主要代码:
mediaPlayer=new MediaPlayer();
//设置类型
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
//=================网络路径
mediaPlayer.setDataSource(this,Uri.parse("http://192.168.43.46:8080/aa.mp3"));
/* 准备 */
mediaPlayer.prepareAsync();
//监听:准备完成的监听
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mediaPlayer.start();
// 把图标变为暂停图标
imageButton.setImageResource(android.R.drawable.ic_media_pause);
//获取音乐的总时长
int duration=mediaPlayer.getDuration();
//设置进度条的最大值为音乐总时长
seekBar.setMax(duration);
new MyThread().start();
}
});
在应用程序加载到播放音频之间有一个明显的滞后时间。延迟的长度取决于用于构建电话Internet连接的数据网络的速度。如果详细分析的话,可以找到是在调用prepare方法和start方法之间发生了这样的延迟。在运行prepare期间,MediaPlayer将填充一个缓冲区,因为即使网络速度缓慢也能平稳的播放音频。当这么操作时,prepare方法实际上发生了阻塞。这意味着应用程序可能要等到prepare方法完成之后才会响应。幸运的是,有一种方法可以解决这个问题,即prepareAsync方法。该方法会立即返回,并在后台执行缓冲和其他工作,从而允许应用程序继续运行。
完整示例代码在前两篇有写,这里就不展示出来了,只需在play()方法中把上段代码更换即可。
另外注意的是想实现在线播放音频需要手机电脑连接同一个局网,运行tomcat/bin/startup.bat文件,然后执行cmd命令ipconfig找到无线局网IP地址,在浏览器输入地址,我示例的地址是192.168.43.46:8080,把需要播放的音频文件下载并放到tomcat\webapps\ROOT下,在手机上输入网址也可以播放说明环境已经配好此时写代码改路径即可。
SoundPool音频池
SoundPool音频池
使用SoundPool播放音效
——如果应用程序经常需要播放密集,短促的音效。这时还用Mediaplayer就显得不合适。
——MediaPlayer的缺点:资源占用量较高,延迟时间较长不支持多个音频同时播放。
——SoundPool使用音效池来播放一些较短的声音片段,它的优势资源占用量低和反应延迟小。
1.创建对象:new SoundPool(num,stream,0)
第一个参数指定支持多少个声音
第二个参数指定声音类型
第三个参数指定声音品质,还没有启作用
如:soundPool = new SoundPool(3,AudioManager.STREAM_MUSIC, 0);
在android21的版本建议使用SoundPool中的内部类来创建:
SoundPool pool=new SoundPool.Builder().setMaxStreams(3).build();
2.添加音频:load()加载声音,最好使用hashMap来管理:HashMap<Integer,Integer>
load(Context context,int resId,int priority)
load(String path,int priority)priority播放声音的优先级,目前没有启作用
如:int id=soundPool.load(this,R.raw.nudge,1)
map.put(1,soundPool.load(this,R.raw.nudge,1));
返回的该声音的ID,之后就根据该ID来播放指定声音
3.播放:play(int,float,float,int,int,float)
第一个参数指定播放哪个声音
第二三个参数指定左右音量
第四个参数播放声音的优先级,值越大越优先播放,0最小
第五个参数是否循环,0不循环,-1循环
第六个参数播放的比率,1为正常的,
如:soundPool.play(pools.get(1), 1, 1, 0,0,1);
暂停:pause()
停止:stop()
释放资源:release();
注意:1)在硬件较差的客户端中,SoundPool比MediaPlay使用延迟更大
2)避免使用SoundPool来播放歌曲获取做游戏的背景音乐。只有那些短促,密集的声音才考虑使用SoundPool进行播放。
步骤:
1.首先在res文件下新建raw文件
2.然后把我们加载的音效放在raw文件下
3.然后就可以写代码了,关键代码:
package com.pxd.mediaplayer;
import android.media.AudioManager;
import android.media.SoundPool;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
public class PlayAnimalActivity extends AppCompatActivity {
private SoundPool soundPool;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_play_animal);
//实例化音频池
soundPool = new SoundPool(4, AudioManager.STREAM_MUSIC,0);
//给音频池设置加载完成的监听
soundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
@Override
public void onLoadComplete(SoundPool soundPool, int i, int i1) {
soundPool.play(i,1,1,1,100,1);
}
});
}
public void playKFC(View view){
soundPool.load(this,R.raw.rooster,1);
}
public void playTwo(View view){
soundPool.load(this,R.raw.chimp,1);
}
public void playThree(View view){
soundPool.load(this,R.raw.crickets,1);
}
public void playFour(View view){
soundPool.load(this,R.raw.roar,1);
}
public void playDog(View view){
soundPool.load(this,R.raw.dogbark,1);
}
@Override
protected void onDestroy() {
super.onDestroy();
if(soundPool!=null){
soundPool.release();
soundPool=null;
}
}
}
布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="playKFC"
android:text="音效鸡" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="playTwo"
android:text="音效Two" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="playThree"
android:text="音效Three" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="playFour"
android:text="音效Four" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="playDog"
android:text="音效狗" />
</LinearLayout>
SoundPool使用的注意事项
因为SoundPool的一些设计上的BUG,从固件版本1.0开始就有些没有修复的,以后应该会慢慢修复。这里简单提一下:
虽然SoundPool可以装载多个音频资源,但是最大只能申请1MB的内存空间,这就意味着只能用使用它播放一些很短的声音片段,而不是用它来播放歌曲或者做游戏背景音乐。
SoundPool提供的pause()、resume()、stop()最好不要轻易使用,因为它有时候会使程序莫名其妙的终止,如果使用,最好做大量的测试。而且有时候也不会立即终止播放声音,而是会等缓冲区的音频数据播放完才会停止。
虽然SoundPool比MediaPlayer的效率好,但也不是绝对不存在延迟的问题,尤其在那些性能不太好的手机中,SoundPool的延迟问题会更严重,但是现在一般的手机配置,那一点的延迟还是可以接受的。