Android 音频播放

来源:互联网 发布:上传图片可预览js插件 编辑:程序博客网 时间:2024/06/08 15:09

http://blog.csdn.net/java_android_c/article/details/52678265


Android平台播放音频的方式一般有3种。1.利用系统内置的应用程序播放音频    2.利用AudioTrack播放原始音频   3.使用MediaPlayer播放。此3种音频播放方式,以第三种MediaPlayer播放这种方式使用的最多,必须掌握!

一、使用系统内置的程序。

Google想的“周到”,一般都给我们提供了一些内置程序,然而这些内置程序的UI效果,那真是感人啊!一般内置程序,我们就是看看而已。

[java] view plain copy
  1. Intent intent=new Intent(Intent.ACTION_VIEW);  
  2. intent.setDataAndType(url,type); //eg:intent.setDataAndType(url,“audio/mp3”);  url音频文件路径  
  3. startActivity(intent);  

二、使用AudioTrack播放音频

AudioTrack只能用来播放原始音频(PCM)

[java] view plain copy
  1. //播放音频(PCM)  
  2.     public void play()  
  3.     {     
  4.         DataInputStream dis=null;  
  5.         try {  
  6.              //从音频文件中读取声音  
  7.              dis=new DataInputStream(new BufferedInputStream(new FileInputStream(recordingFile)));  
  8.             } catch (FileNotFoundException e) {  
  9.               e.printStackTrace();  
  10.             }  
  11.         //最小缓存区  
  12.         int bufferSizeInBytes=AudioTrack.getMinBufferSize(sampleRateInHz,AudioFormat.CHANNEL_OUT_MONO,AudioFormat.ENCODING_PCM_16BIT);  
  13.         //创建AudioTrack对象   依次传入 :流类型、采样率(与采集的要一致)、音频通道(采集是IN 播放时OUT)、量化位数、最小缓冲区、模式  
  14.         player=new AudioTrack(AudioManager.STREAM_MUSIC,sampleRateInHz,AudioFormat.CHANNEL_OUT_MONO,AudioFormat.ENCODING_PCM_16BIT, bufferSizeInBytes, AudioTrack.MODE_STREAM);  
  15.           
  16.         byte[] data =new byte [bufferSizeInBytes];  
  17.         player.play();//开始播放  
  18.         while(true)  
  19.         {  
  20.             int i=0;  
  21.             try {  
  22.                 while(dis.available()>0&&i<data.length)  
  23.                 {  
  24.                   data[i]=dis.readByte();//录音时write Byte 那么读取时就该为readByte要相互对应  
  25.                   i++;  
  26.                 }  
  27.             } catch (IOException e) {  
  28.                 // TODO Auto-generated catch block  
  29.                 e.printStackTrace();  
  30.             }  
  31.             player.write(data,0,data.length);  
  32.               
  33.             if(i!=bufferSizeInBytes) //表示读取完了  
  34.             {  
  35.                 player.stop();//停止播放  
  36.                 player.release();//释放资源  
  37.                 break;  
  38.             }  
  39.         }  
  40.           
  41.     }  
这里是播放PCM的关键代码,完整Demo在本文的末尾会给出相应的链接!主要是从文件中读取数据到数组中,然后写到AudiotTrack之中,然后AudioTrack就会将其播放,利i!=bufferSizeInBytes 判断其读取完了(文件的末尾)。


三、使用MediaPlayer进行音频播放。

MediaPlayer是很强大的一个Android系统内置的类,它不仅可以播放音频同时还可以播放视频。最常见的方法有:

start()开始播放        pause()暂停播放    stop()停止播放       prepareAsync() /prepare()  开始准备     

getCurrentPosition() 当前播放的位置         getDuration()文件总的时长      seekTo (int position)定位播放

示例代码 演示利用MediaPlayer和Seekbar进行音频 的播放 、暂停、拖动快进播放等 。效果如图:(具体完整代码在备注里面可下载MediaPlayerDemo)


布局文件:

[html] view plain copy
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:background="@drawable/background"  
  6.     tools:context="${relativePackage}.${activityClass}" >  
  7.   
  8.     <TextView   
  9.         android:layout_width="wrap_content"  
  10.         android:layout_height="wrap_content"  
  11.         android:text="天空之城主题曲(宫崎骏)"  
  12.         android:textColor="#F8F8F8"  
  13.         android:textSize="18sp"  
  14.         android:ellipsize="marquee"  
  15.         android:layout_centerInParent="true"  
  16.         />  
  17.       
  18.     <LinearLayout   
  19.         android:layout_width="match_parent"  
  20.         android:layout_height="wrap_content"  
  21.         android:layout_marginLeft="5dp"  
  22.         android:layout_marginRight="5dp"  
  23.         android:layout_marginBottom="5dp"  
  24.         android:layout_above="@+id/bottom"  
  25.         android:gravity="center_vertical"  
  26.         >  
  27.      
  28.     <TextView  
  29.         android:id="@+id/left"  
  30.         android:layout_width="wrap_content"  
  31.         android:layout_height="wrap_content"  
  32.         android:text="00:00"  
  33.         android:textColor="#F8F8F8"  
  34.         />  
  35.       
  36.     <SeekBar   
  37.         android:id="@+id/seek"  
  38.         android:layout_width="match_parent"  
  39.         android:layout_height="wrap_content"  
  40.         android:layout_weight="1"  
  41.         android:enabled="false"  
  42.         />  
  43.      
  44.     <TextView  
  45.         android:id="@+id/right"  
  46.         android:layout_width="wrap_content"  
  47.         android:layout_height="wrap_content"  
  48.         android:text="00:00"  
  49.         android:textColor="#F8F8F8"  
  50.         />  
  51.       
  52.     </LinearLayout>  
  53.       
  54.     <LinearLayout  
  55.         android:id="@+id/bottom"  
  56.         android:layout_width="match_parent"  
  57.         android:layout_height="wrap_content"  
  58.         android:layout_alignParentBottom="true"  
  59.         android:layout_marginBottom="5dp"  
  60.         android:orientation="horizontal" >  
  61.           
  62.         <Button  
  63.             android:id="@+id/start"   
  64.             android:layout_width="0dp"  
  65.             android:layout_height="wrap_content"  
  66.             android:layout_weight="1"  
  67.             android:text="播放"  
  68.             android:textColor="#F8F8F8"  
  69.             android:textSize="14sp"  
  70.             android:enabled="false"  
  71.             />  
  72.           
  73.         <Button  
  74.             android:id="@+id/stop"   
  75.             android:layout_width="0dp"  
  76.             android:layout_height="wrap_content"  
  77.             android:layout_weight="1"  
  78.             android:text="暂停"  
  79.             android:textSize="14sp"  
  80.             android:textColor="#F8F8F8"  
  81.             android:enabled="false"  
  82.             />  
  83.           
  84.     </LinearLayout>  
  85.       
  86. </RelativeLayout>  

初始化MediaPlayer

[java] view plain copy
  1.       mAssetManager=getAssets();  
  2. try {  
  3.     afd=mAssetManager.openFd("sky.mp3");// 创建天空之城的AssetFileDescriptor文件  
  4.     } catch (IOException e) {  
  5.     e.printStackTrace();  
  6.     Log.e(TAG,"创建AssetFileDescriptor 异常 ,请查看根福是否存在");  
  7. }  
  8. mMediaPlayer=new MediaPlayer();  
  9. try {  
  10.     //设置播放源 ,当然还有其他的重载方法 eg:setDataSource(String path) path可以使网络路径也可以是本地路径,网络的记得加权限  
  11.     mMediaPlayer.setDataSource(afd.getFileDescriptor());   
  12. catch (Exception e) {  
  13.     e.printStackTrace();  
  14.     Log.e(TAG,"设置播放源异常" );  
  15. }  
  16. mMediaPlayer.prepareAsync(); //MediaPlayer 开始准备  异步的, 还有prepare()这个是同步的  

MediaPlayer设置相应的监听器

[java] view plain copy
  1. seek.setMax(100);//设置长度100  
  2. seek.setOnSeekBarChangeListener(this);//设置Seekbar的滑动监听器  
  3. mMediaPlayer.setOnPreparedListener(this);//设置准备就绪监听  
  4. mMediaPlayer.setOnCompletionListener(this);//设置播放完成  
[java] view plain copy
  1. //结束滑动时     
  2. @Override  
  3. public void onStopTrackingTouch(SeekBar seekBar) {  
  4.       int a=(int)((sum/100.0)*(seekBar.getProgress()));  
  5.       mMediaPlayer.seekTo(a); //seekTo方法接收的单位是:毫秒  
  6.       handler.sendEmptyMessage(START); //更新seekBar  
  7. }  
[java] view plain copy
  1. @Override  
  2. public void onPrepared(MediaPlayer mp) {  
  3.        //准备就绪完成  
  4.         start.setEnabled(true);  
  5.         stop.setEnabled(true);  
  6.         seek.setEnabled(true);  
  7.         sum=mMediaPlayer.getDuration();  
  8.         right.setText(FormatTime(sum/1000));  }  
[java] view plain copy
  1. //播放完成  
  2. @Override  
  3. public void onCompletion(MediaPlayer mp) {  
  4.     start.setText("播放");  
  5.     seek.setProgress(0);  
  6.     mMediaPlayer.seekTo(0);  
  7. }  
Handler 更新SeekBar的状态:
[java] view plain copy
  1. private Handler handler=new Handler()  
  2.    {  
  3.     @Override  
  4.     public void handleMessage(Message msg) {  
  5.         switch (msg.what) {  
  6.             case 1:{  
  7.                 int current=mMediaPlayer.getCurrentPosition();// 得到数值的单位是毫秒  
  8.                 int prass=(int)(current/(sum*1.0)*100);  
  9.                 left.setText(FormatTime(current/1000));  
  10.                 seek.setProgress(prass);  
  11.                 if(!pause)  
  12.                 {  
  13.                   handler.sendEmptyMessageDelayed(1,1000);//1 秒后继续更新  
  14.                 }  
  15.                 break;  
  16.             }  
  17.               
  18.             case 0:{  
  19.                 //停止更新  
  20.                 pause=true;  
  21.                 break;  
  22.             }  
  23.         default:  
  24.             break;  
  25.         }  
  26.     }  
  27.       
  28.    };  

1.比较容易让人混淆的是pause方法和stop方法的区别:2个方法都可以让音频停止。

调用Pause方法后想再次听见声音直接调用start方法之后即可。调用stop方法停止音频之后,再次调用start方法之后不会播放,要先调用prepareAsync或者prepare方法,之后在public void onPrepared(MediaPlayer mp)回调方法里面调用start方法才会播放。

2.start方法要在准备就绪,即在public void onPrepared(MediaPlayer mp)里面回调。

3.不使用MediaPlayer时记得stop,然后release 释放相关的资源。(本例在Activity的OnDestroy方法中调用的)

下图是MediaPlayer状态及方法流程图:




四、备注:

AudioTrack播放PCMDemo  如果对Demo中音频采集不熟悉,可以查阅 Android 音频采集

MediaPlayerDemo(利用MediaPlayer播放音频)



0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 小米mix装在兜里还能解锁怎么办 痰咳不出来憋的嘴唇紫了怎么办 京东闪电退款后不给退货怎么办 我的中国银行卡在异地被冻结怎么办 qq密保号码换了验证不了怎么办 qq登陆需要密保手机验证怎么办 微信漂流瓶被投诉收不到回复怎么办 电视的屏幕出现三条黑线怎么办 付了定金的房子不想要了怎么办 顾客刚买了东西就退怎么办 飞机票买了但是没有报团怎么办 日本寄东西回来深圳海关扣了怎么办 xp框架安装模块后无限重启怎么办 手机百度云下载的文件不见了怎么办 百度云手机号换了文件不见了怎么办 好劵app提现密码忘了要怎么办 微信上买的衣服不给退货怎么办 在微信上买的衣服不给退货怎么办 贴贴纸的地方出现色差了怎么办 贴在玻璃上的贴纸撕掉后有胶怎么办 魅族手机部分时间上划失效怎么办 别人电脑上c盘文件无权访问怎么办 网络已连接但上不了网怎么办 asp复选框选中的有重复值怎么办 邮件在邮递中出现损坏怎么办呢? 爱彩彩票资金密码忘记了怎么办 注册彩票网站忘了资金密码怎么办 电车电瓶加水后电压变低怎么办 电动车电瓶四块电池坏了一块怎么办 把小孩的玩具修坏了怎么办 电动车插头太紧了插不到底怎么办 宜家沙发不能更换布套怎么办 苹果官网买的无线充坏了怎么办 苹果官网上买的耳机坏了怎么办 led灯开关关掉了闪烁是怎么办 我朋友借的网贷光给我打电话怎么办 电脑上的文件变成了图片查看怎么办 外卖店打印机纸卡住打不开了怎么办 微信撤回图片留下一堆代码怎么办 拼多多砍价免费拿砍不到0元怎么办 一岁三个月宝宝老足拉肚子怎么办丶