Android 音频播放

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

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

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

Intent intent=new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(url,type); //eg:intent.setDataAndType(url,“audio/mp3”);  url音频文件路径
startActivity(intent);

二、使用AudioTrack播放音频

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

//播放音频(PCM)
	public void play()
	{
		DataInputStream dis=null;
		try {
			 //从音频文件中读取声音
		     dis=new DataInputStream(new BufferedInputStream(new FileInputStream(recordingFile)));
		    } catch (FileNotFoundException e) {
			  e.printStackTrace();
		    }
		//最小缓存区
		int bufferSizeInBytes=AudioTrack.getMinBufferSize(sampleRateInHz,AudioFormat.CHANNEL_OUT_MONO,AudioFormat.ENCODING_PCM_16BIT);
		//创建AudioTrack对象   依次传入 :流类型、采样率(与采集的要一致)、音频通道(采集是IN 播放时OUT)、量化位数、最小缓冲区、模式
	    player=new AudioTrack(AudioManager.STREAM_MUSIC,sampleRateInHz,AudioFormat.CHANNEL_OUT_MONO,AudioFormat.ENCODING_PCM_16BIT, bufferSizeInBytes, AudioTrack.MODE_STREAM);

		byte[] data =new byte [bufferSizeInBytes];
		player.play();//开始播放
		while(true)
		{
			int i=0;
	    	try {
				while(dis.available()>0&&i<data.length)
				{
				  data[i]=dis.readByte();//录音时write Byte 那么读取时就该为readByte要相互对应
				  i++;
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	    	player.write(data,0,data.length);

	    	if(i!=bufferSizeInBytes) //表示读取完了
	    	{
	    		player.stop();//停止播放
	    		player.release();//释放资源
	    		break;
	    	}
		}

	}

这里是播放PCM的关键代码,完整Demo在本文的末尾会给出相应的链接!主要是从文件中读取数据到数组中,然后写到AudiotTrack之中,然后AudioTrack就会将其播放,利i!=bufferSizeInBytes 判断其读取完了(文件的末尾)。

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

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

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

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

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

布局文件:

<RelativeLayout 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:background="@drawable/background"
    tools:context="${relativePackage}.${activityClass}" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="天空之城主题曲(宫崎骏)"
        android:textColor="#F8F8F8"
        android:textSize="18sp"
        android:ellipsize="marquee"
        android:layout_centerInParent="true"
        />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="5dp"
        android:layout_marginRight="5dp"
        android:layout_marginBottom="5dp"
        android:layout_above="@+id/bottom"
        android:gravity="center_vertical"
        >

    <TextView
        android:id="@+id/left"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="00:00"
        android:textColor="#F8F8F8"
        />

    <SeekBar
        android:id="@+id/seek"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:enabled="false"
        />

    <TextView
        android:id="@+id/right"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="00:00"
        android:textColor="#F8F8F8"
        />

    </LinearLayout>

    <LinearLayout
        android:id="@+id/bottom"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="5dp"
        android:orientation="horizontal" >

        <Button
            android:id="@+id/start"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="播放"
            android:textColor="#F8F8F8"
            android:textSize="14sp"
            android:enabled="false"
            />

        <Button
            android:id="@+id/stop"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="暂停"
            android:textSize="14sp"
            android:textColor="#F8F8F8"
            android:enabled="false"
            />

    </LinearLayout>

</RelativeLayout>

初始化MediaPlayer

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

MediaPlayer设置相应的监听器

     seek.setMax(100);//设置长度100
	    seek.setOnSeekBarChangeListener(this);//设置Seekbar的滑动监听器
	    mMediaPlayer.setOnPreparedListener(this);//设置准备就绪监听
	    mMediaPlayer.setOnCompletionListener(this);//设置播放完成
 //结束滑动时
	@Override
	public void onStopTrackingTouch(SeekBar seekBar) {
		  int a=(int)((sum/100.0)*(seekBar.getProgress()));
		  mMediaPlayer.seekTo(a); //seekTo方法接收的单位是:毫秒
		  handler.sendEmptyMessage(START); //更新seekBar
	}
       @Override
       public void onPrepared(MediaPlayer mp) {
		            //准备就绪完成
               start.setEnabled(true);
               stop.setEnabled(true);
               seek.setEnabled(true);
               sum=mMediaPlayer.getDuration();
               right.setText(FormatTime(sum/1000));  }
 //播放完成
	@Override
	public void onCompletion(MediaPlayer mp) {
		start.setText("播放");
		seek.setProgress(0);
		mMediaPlayer.seekTo(0);
	}

Handler 更新SeekBar的状态:

 private Handler handler=new Handler()
    {
		@Override
		public void handleMessage(Message msg) {
			switch (msg.what) {
			    case 1:{
			    	int current=mMediaPlayer.getCurrentPosition();// 得到数值的单位是毫秒
			    	int prass=(int)(current/(sum*1.0)*100);
			    	left.setText(FormatTime(current/1000));
			    	seek.setProgress(prass);
			    	if(!pause)
			    	{
			    	  handler.sendEmptyMessageDelayed(1,1000);//1 秒后继续更新
			    	}
			    	break;
			    }

			    case 0:{
			    	//停止更新
			    	pause=true;
			    	break;
			    }
			default:
				break;
			}
		}

    };

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播放音频)

时间: 2024-10-10 12:45:35

Android 音频播放的相关文章

Android 音频播放——AudioTrack直接播PCM、MediaPlayer播媒体文件可以是audio

http://blog.csdn.net/java_android_c/article/details/52678265 Android平台播放音频的方式一般有3种.1.利用系统内置的应用程序播放音频    2.利用AudioTrack播放原始音频   3.使用MediaPlayer播放.此3种音频播放方式,以第三种MediaPlayer播放这种方式使用的最多,必须掌握! 一.使用系统内置的程序. Google想的"周到",一般都给我们提供了一些内置程序,然而这些内置程序的UI效果,那

Android 音频播放的可视化实现

最近开发的小应用想实现音频播放的可视化,看了一下要用到快速傅里叶变换的知识!不会要去翻高等代数的书复习吧!!! 幸好有大大已经写好的fft for Java 的开源库,生活在Java的世界真实好啊! 先把文章转过来备份着,接下来的时间就好好研究一下怎么应用到自己的的project里面. http://www.jb51.net/article/32887.htm fft 4 Java 的开源包在这里下载:www.netlib.org/fftpack/jfftpack.tgz 直接将里面javaso

Android 音频播放之SoundPool的使用和封装

一般大家使用的是MediaPlayer来播放音频,它的创建和销毁都是非常消耗资源的,如果我们的需求是播放一些短促而且频繁播放的音频的话MediaPlayer就有些不合适了,我们来讲讲SoundPool来播放短促的音频: SoundPool结构如下 初始化SoundPool 初始化SoundPool 我们直接new SoundPool (int maxStreams, int streamType, int srcQuality)即可 参数解释: 参数 解释 maxStreams 最大的流的数量

Android音频播放实例

MediaPlayer: 此类适合播放较大文件,此类文件应该存储在SD卡上,而不是在资源文件里,还有此类每次只能播放一个音频文件. 1.从资源文件中播放 MediaPlayer player = new MediaPlayer.create(this,R.raw.test); player.stare(); 2.从文件系统播放 MediaPlayer player = new MediaPlayer(); String path = "/sdcard/test.mp3"; player

Android通过意图使用内置的音频播放器

如果实现一个音频文件的播放,那么在应用程序中提供播放音频文件功能的最简单的方式是利用内置的"Music(音乐)"应用程序的功能--即使用系统自带的或已安装好的音乐播放器来播放指定的音频文件. 本例比较简单,下面直接给出源代码: 布局文件activity_main: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http:/

求教,是否直接可以调用android的libmedia.so库进行音频播放

问题描述 问题: 在C++代码中是否可以调用android系统的libmedia.so, 我用C++写了一个测试程序,调用了libmedia.so中mediaplayer.cpp中的方法进行音频播放,可以通过编译,也可以在android系统的机顶盒中执行,但是prepare()方法一直被阻塞,求大神指点该如何解决啊,给点思路好吗?以下是测试代码: #include <stdio.h> #include <stdlib.h> #include <mediaplayer.h>

Android音频文件浏览+音频播放

该Demo运行后,会显示所有你sd卡上的音乐文件列表, 并可以点击列表选择某一首歌曲进行播放. 运行效果: 点击download出现: 然后点击歌曲调用系统播放器播放. 源代码: activity_audio_browser.xml: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tool

Android音频开发之——如何播放一帧音频

本文重点关注如何在Android平台上播放一帧音频数据.阅读本文之前,建议先读一下<Android音频开发(1):基础知识>,因为音频开发过程中,经常要涉及到这些基础知识,掌握了这些重要的概念后,开发过程中的很多参数和流程就会更加容易理解. Android SDK 提供了3套音频播放的API,分别是:MediaPlayer,SoundPool,AudioTrack,关于它们的区别可以看这篇文章:<Intro to the three Android Audio APIs>,简单来说

Android平台中关于音频播放

Android平台中关于音频播放有以下三种方式: 1.SoundPool ---- 适合短促且对反应速度比较高的情况(游戏音效或按键声等) 2.MediaPlayer ---- 适合比较长且时间要求不高的情况 3.AudioTrack ---- 播放解码后的PCM码流 方法一:SoundPool 1)SoundPool简介 SoundPool类是Android用于管理和播放应用程序的音频资源的类.一个SoundPool对象可以看作是一个可以从APK中导入资源或者从文件系统中载入文件的样本集合.它