Android多媒体(1)——基础知识与音频

Android多媒体框架支持播放各种常见格式的视频,大大降低了在应用中整合音频,视频和照片的难度。通过MediaRecorder提供的SDK,可以播放标准文件系统中的原始文件,同样也可以播放网络上的视频流。下面先简单过一遍视频/音频共通的基础知识,接着跟着代码看如何选择和使用Android内置的视频和音频SDK,内容参考官方文档。

权限声明

访问互联网权限

唤醒锁权限

调用 MediaPlayer.setScreenOnWhilePlaying()或者MediaPlayer.setWakeMode()

 同时需要添加权限


使用MediaPlayer

支持的源:
- 本地资源
- 内部url(ContentRecolver
- 外部url(流)

异步准备

调用 prepare()方法是耗时的,所以不建议在UI线程直接调用,可以调用 prepareAsync(),例如

mMediaPlayer.setDataSource(mAudioPath);
mMediaPlayer.prepareAsync();
mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
    @Override
    public void onPrepared(MediaPlayer mp) {
        mMediaPlayer.start();
    }
});

释放资源

MediaPlayer非常耗费系统资源,所以不使用时需要释放。一般不需要后台播放时,可以在 onStop()方法中释放

mediaPlayer.release();
mediaPlayer = null;

音频相关

编码和解码支持的格式可以查看Android Core Media Formats。

而我自己经过测试得出的结论是:

Android多媒体(1)——基础知识与音频_第1张图片

专业术语
  • 比特率
    每秒传送的比特数,比特率越高,音质越好,文件越大。
  • 采样率
    从声源中提取的频率,采样率越大,越接近原生,但是并不是越大越好。
    更多相关知识可以参考维基百科或者其他科普文章。
格式选择

AAC是苹果也支持的格式,所以Android录制出来的音频不需要进行转码,iOS也可以直接播放。AAC是一个大家族,有很多以最简单的AAC协议为基础,增加新特性的格式,这里不一一介绍。
AMR格式则是兼容性最好的格式(微信就是用它录的音频),上至各种名牌手机,下至各种山寨手机,都能播放出来,但是需要服务器或者iOS进行多一步编解码。

示例代码

示例代码只是讲述如何使用SDK的一个Demo,运用到实际项目中还需要根据需求进行修改和适配。

MediaPlayer封装成了播放按钮和录制按钮。
下面是播放音频的核心代码。

初始化

  mMediaPlayer = new MediaPlayer();
  mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);

点击播放

   @Override
    public void onClick(View v) {
        if (!TextUtils.isEmpty(mAudioPath) && isLegalFile(new File(mAudioPath))) {
            mPlaying = !mPlaying;
            if (!mPlaying) {
                try {
                    mMediaPlayer.setDataSource(mAudioPath);
                    mMediaPlayer.prepareAsync();
                    mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                        @Override
                        public void onPrepared(MediaPlayer mp) {
                            mMediaPlayer.start();
                        }
                    });

                } catch (IOException e) {
                    e.printStackTrace();
                }
            } else {
                mMediaPlayer.stop();
            }
        }
    }

销毁资源

@Override
protected void onDetachedFromWindow() {
    super.onDetachedFromWindow();
    if(mMediaPlayer != null) {
        mMediaPlayer.stop();
    }
}

public void release() {
    if (mMediaPlayer != null) {
        mMediaPlayer.release();
    }
}

下面是录制音频的核心代码

初始化

    mRecorder = new MediaRecorder();
    mRootDir = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "Movies" + File.separator;
    mName = "audio_test_44k_44k_16b.mp4";
    mPath = mRootDir + mName;
    mRecorder.setOutputFile(mPath);

开始录制

private void statRecord() {
    mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
    mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
    mRecorder.setAudioChannels(2);
    mRecorder.setAudioEncodingBitRate(44100);
    mRecorder.setAudioSamplingRate(44100);
    try {
        mRecorder.prepare();
    } catch (IOException e) {
        e.printStackTrace();
    }
    mRecorder.start();
}

上面的配置是根据调研信息进行配置的,也可以根据自己需求进行定制。
AudioChannel是声道,分为单声道和双声道,会影响录制出来的音频文件大小,有兴趣深入研究的可以查阅相关资料。

停止录制

public void stopRecord() {
    if (mRecorder != null) {
        mRecorder.stop();
        mRecorder.reset();
        mIsRecording = false;
    }
}

释放资源

@Override
protected void onDetachedFromWindow() {
    super.onDetachedFromWindow();
    if (mRecorder != null) {
        mRecorder.reset();
    }
}

public void release() {
    if (mRecorder != null) {
        mRecorder.release();
        mRecorder = null;
    }
}

总结

音频的录制与播放相对于视频来说是很简单的,只要配置正确的参数,记得在不再需要时释放资源,就能很快写出令人满意的代码。

下一章预告

视频的录制和播放,软件解码与硬件解码,视频流的简单处理…

TO BE CONTINUE…

你可能感兴趣的:(Android)