zoukankan      html  css  js  c++  java
  • Android中的音频处理------SoundPool,MediaRecorder,MediaPlayer以及RingStone总结

    用Soundpool可以播一些短的反应速度要求高的声音, 比如游戏中的爆破声,

    而Mediaplayer适合播放长点的。 MediaRecorder主要用来录音。


    SoundPool载入音乐文件使用了独立的线程,不会阻塞UI主线程的操作。

    但是这里如果音效文件过大没有载入完成,我们调用play方法时可能产生严重的后果,

    这里AndroidSDK提供了一个SoundPool.OnLoadCompleteListener类来帮助我们了解媒体文件是否载入完成,

    我们重载onLoadComplete(SoundPool soundPool, int sampleId, int status) 方法即可获得。

    sampleId

    the sample ID of the sound loaded.

    status

    the status of the load operation (0 = success)

     
    从上面的onLoadComplete方法可以看出该类有很多参数,

    比如类似id,SoundPool在load时可以处理多个媒体一次初始化并放入内存中,

    这里效率比MediaPlayer高了很多。 


    SoundPool类支持同时播放多个音效,这对于游戏来说是十分必要的,

    而MediaPlayer类是同步执行的只能一个文件一个文件的播放。

     

    创建:

    public SoundPool(int maxStream, intstreamType, int srcQuality)
      maxStream —— 同时播放的流的最大数量
      streamType —— 流的类型,一般为STREAM_MUSIC(具体在AudioManager类中列出)
      srcQuality —— 采样率转化质量,当前无效果,使用0作为默认值
      

    eg:
      SoundPool soundPool = new SoundPool(3, AudioManager.STREAM_MUSIC,0);
        创建了一个最多支持3个流同时播放的,类型标记为音乐的SoundPool。

     

    一般把多个声音放到HashMap中去,比如
        soundPool = new SoundPool(4, AudioManager.STREAM_MUSIC,100);
        soundPoolMap = new HashMap<Integer,Integer>();  
        soundPoolMap.put(1, soundPool.load(this, R.raw.dingdong,1));

     

    加载:
     int  load(Context context, intresId, int priority)  //从APK资源载入
      int  load(FileDescriptor fd, long offset, long length, intpriority)  //从FileDescriptor对象载入
      int  load(AssetFileDescriptor afd, int priority)  //从Asset对象载入
      int  load(String path, int priority)  //从完整文件路径名载入
    最后一个参数为优先级。


    播放:
    play(int soundID, float leftVolume, float rightVolume, int priority, int loop,float rate) ,

    其中leftVolume和rightVolume表示左右音量,priority表示优先级,loop表示循环次数,rate表示速率,


    //速率最低0.5最高为2,1代表正常速度
    sp.play(soundId, 1, 1, 1, 0, 1.0f); 


      而停止则可以使用 pause(int streamID) 方法,

    这里的streamID和soundID均在构造SoundPool类的第一个参数中指明了总数量,而id从0开始。

     

    获取audioManager对象

    AudioManager mAudioManager = (AudioManager)getSystemService(AUDIO_SERVICE);

    播放音效

    mAudioManager.playSoundEffect(AudioManager.FX_KEY_CLICK);

     

    一般AudioManager在OnResume和OnStop方法需进行如下处理:

    // Get ready to play sound effects
    	@Override
    	protected void onResume() {
    		super.onResume();
    		mAudioManager.setSpeakerphoneOn(true);
    		mAudioManager.loadSoundEffects();
    	}
    
    	// Release resources & clean up
    	@Override
    	protected void onPause() {
    		if (null != mSoundPool) {
    			mSoundPool.unload(mSoundId);
    			mSoundPool.release();
    			mSoundPool = null;
    		}
    		mAudioManager.setSpeakerphoneOn(false);
    		mAudioManager.unloadSoundEffects();
    		super.onPause();
    	}
    


    MediaRecorder用来录音。

    开启录音:

    private static final String mFileName = Environment
    			.getExternalStorageDirectory().getAbsolutePath()
    			+ "/audiorecordtest.3gp";
    private void startRecording() {
    	mRecorder = new MediaRecorder();
    		mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    		mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
    	mRecorder.setOutputFile(mFileName);
    		mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
    
    		try {
    			mRecorder.prepare();
    		} catch (IOException e) {
    			Log.e(TAG, "Couldn't prepare and start MediaRecorder");
    		}
    
    		mRecorder.start();
    	}
    

    关闭录音:

    private void stopRecording() {
    		if (null != mRecorder) {
    			mRecorder.stop();
    			mRecorder.release();
    			mRecorder = null;
    		}
    	}
    


    方法说明:

    MediaRecorder中的setAudioSource()方法设置声音来源,一般传入MediaRecorder.AudioSource.MIC指定录制来自麦克风的声音。

    setOutputFormat设置录制音频文件的格式。(注意必须在设置编码格式之前设置,否则会抛出异常)

    setAudioEncoder设置编码格式

    setAudioEncodingBitRate(int bitRate)设置编码位率

    setAudioSamplingRate(int samplingRate)设置采样率

    setOutputFile(String path)设置音频文件的保存位置

    然后prepare(),start() 开始播放

    stop(),release() 停止播放,释放资源



    MediaPlayer

    Android支持有限數量的同步Media Player對象,如果不釋放它們,將會在系統耗盡資源時導致ANR

    因此,完成播放時調用mediaPlay.release()方法釋放相關資源。


    //從一個包資源加載音頻

             MediaPlayerresourcePlayer = MediaPlayer.create(this, R.raw.my_audio);

    //從一個本地文件加載音頻

             MediaPlayer resourcePlayer= MediaPlayer.create(this, Uri.parse("file:///sdcard/localfile.mp3"));

    //從一個在線資源加載音頻

             MediaPlayer resourcePlayer= MediaPlayer.create(this, Uri.parse(URL));

    //從一個Content Provider加載音頻
           MediaPlayerresourcePlayer = MediaPlayer.create(this,
            Settings.System.DEFAULT_RINGTONE_URI);
    //還可以setDataSource方法
           MediaPlayermediaPlayer = new MediaPlayer();
           mediaPlayer.setDataSource("/sdcard/123.mp3");
           mediaPlayer.prepare();

    常用方法

    mediaPlayer.start()

    mediaPlayer.stop()

    mediaPlayer.pause()


    //調節左右聲道音量  0~1之間的浮點數 0是靜音 1是最大

        mediaPlayer.setVolume(0.5f,0.5f)

    //強制屏幕常亮

        mediaPlayer.setScreenOnWhilePlaying(true)

    //循環播放

       If(!mediaPlayer.isLooping()){

          mediaPlayer.setLooping(true);

       }

    示例代码:

    播放音樂并震動:
    	mediaPlayer = new MediaPlayer();
    		vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
    		long[] pattern = { 1000, 200, 200, 200 };
    		vibrator.vibrate(pattern, 0);
    try {
    		mediaPlayer.setVolume(1.0f, 1.0f);
    		mediaPlayer.setDataSource(this,
    		Uri);
    		mediaPlayer.setAudioStreamType(AudioManager.STREAM_ALARM);
    		mediaPlayer.setLooping(true);
    		mediaPlayer.prepare();
    		mediaPlayer.start();
    	   } catch (Exception e) {
    		  mediaPlayer.release();
    }
    

    播放铃声RingStone:

    种类包括:

    RingtoneManager.TYPE_RINGTONE

    RingtoneManager.TYPE_NOTIFICATION

    RingtoneManager.TYPE_ALARM

    示例:

    Uri ringtoneUri = RingtoneManager
    	.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
    playRingtone(RingtoneManager.getRingtone(getApplicationContext(), ringtoneUri));
    
    // Shut off current Ringtone and play new one
    	private void playRingtone(Ringtone newRingtone) {
    	 	if (null != mCurrentRingtone && mCurrentRingtone.isPlaying())
    		 	   mCurrentRingtone.stop();
    		mCurrentRingtone = newRingtone;
    		    if (null != newRingtone) {
    			   mCurrentRingtone.play();
    		    }
    	}
    



  • 相关阅读:
    android高级UI之Paint Xfermode
    android高级UI之Paint滤镜
    常见文献管理软件
    linux下10款markdown软件
    markdown页面内跳转
    Ubuntu18.04配制阿里巴巴的源
    python中TAB补全
    word中手动添加endnote的加载项
    MarkDown添加图片的三种方式
    word前页与后页页码断开
  • 原文地址:https://www.cnblogs.com/krislight1105/p/3748289.html
Copyright © 2011-2022 走看看