|
网站内容均来自网络,本站只提供信息平台,如有侵权请联系删除,谢谢!
前言
已经快两个月没写博客了,最近换了工作,之前一直想研究研究音视频方面的东西,终于有机会实现了,所以最近会一直写这个系列。我也是刚刚摸索了一段时间,有什么问题大家一起讨论指正。
第一篇是概念扫盲篇,如果不知道一些常用的API之后必然很难下手。
正文
由于FFmpeg特别的火,所以我一直认为音视频和Android原生的API关系不大,其实这种理解是错误的,FFmpeg的优势是解决了Android不同版本的API性能差距和问题,尽量在不同机型上达到性能相近的效果,第三方库的更新肯定要比系统版本更新方便多了。
所以如果对原生的API有了熟练的掌握,过度到FFmpeg就都是小问题了。今天我们了解一些常用的API的概念。
MediaPlayer
音视频播放的上层API,可以用来播放音频和视频文件,特别常用的API。
- // 创建MediaPlayer val mediaPlayer = MediaPlayer() // 设置要播放的文件路径 mediaPlayer.setDataSource(path) // 准备 mediaPlayer.prepare() // 播放 mediaPlayer.start()
复制代码 还有一些暂停,停止的方法,这里就不介绍了,相信大家都用过。
MediaRecoder
音视频录制的上层API,通过一些简单的配置,就可以直接录制音视频保存到指定的文件路径。
- // 创建MediaRecorderval mediaRecorder = MediaRecorder()// 录制声音的来源,具体参考AudioSourcemediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);// 录制视频的来源mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE)// 输出的文件编码格式mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)// 保存的文件路径 mediaRecorder.setOutputFile(videoRecorderFile)// 设置录音编码器// 注意设置的录制音频编码格式与视频的编码格式是否匹配mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB)// 音频录制的其他设置mediaRecorder.setAudioEncodingBitRate(60)mediaRecorder.setAudioSamplingRate(14400)// 视频录制的其他设置mediaRecorder.setVideoSize(getScreenWidth(), getScreenHeight())mediaRecorder.setVideoEncodingBitRate(2 * getScreenWidth().times(getScreenHeight()))mediaRecorder.setVideoFrameRate(60)mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264)mediaRecorder.prepare()mediaRecorder.start()// 停止录制mediaRecorder!!.stop()mediaRecorder!!.release()
复制代码 都是基本的配置,不过如果是录制视频一般要和Surface一起使用,从摄像头中得到录制的内容,MediaRecorder也有对应的方法设置:
- // 设置摄像头mediaRecorder.setCamera(camera!!)// 设置录制的角度,如果与摄像头不符,会出现视频角度不对的问题mediaRecorder.setOrientationHint(90);// 设置录音和录制视频的来源mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER)mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA) // 设置录制的质量mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH))....
复制代码 网上有很多Demo,大家可以去搜索一下,之后我们也会自己写一写Demo。
AudioRecord
音频录制的API,通过流的形式输出的音频数据是未经过编码的,也就是PCM原数据,所以直接保存录制出的内容是无法直接使用播放器进行播放。
- // 创建AudioRecordAudioRecord( // 录制音频的来源,参数与MediaRecoder相同 AudioSource, // 采样率, sampleRateInH, // 声音的频道 CHANNEL, // 编码位数 ENCODING, // 录制一帧的最小Buffer大小 AudioRecord.getMinBufferSize( sampleRateInH, CHANNEL, ENCODING ) )
复制代码 可以看出,AudioRecorder相比MediaRecoder要更加细致,如果你有对音频有一些特殊的处理,例如变声,就需要使用到AudioRecorder,然后再自己编码保存。
然后我们再了解一下构造方法中的参数:
AudioSource:录制的声音来源,跟MediaRecoder是一样的。
·
sampleRateInH:采样率,通俗的讲采样频率是指计算机每秒钟采集多少个信号样本,单位是Hz。越高声音肯定是越清晰,常用的大小有:
8000Hz 电话所用采样率,对于人的说话已经足够
11025Hz 获得的声音称为电话音质,基本上能让你分辨出通话人的声音
22050Hz 无线电广播所用采样率,广播音质
32000Hz miniDV数码视频camcorder、DAT(LPmode)所用采样率
44100Hz 音频CD,也常用于MPEG-1音频(VCD,SVCD,MP3)所用采样率
47250Hz NipponColumbia(Denon)开发的世界上第一个商用PCM录音机所用采样率
48000Hz miniDV、数字电视、DVD、DAT、电影和专业音频所用的数字声音所用采样率
.
CHANNEL:就是视频的立体声,左声道,右声道
.
ENCODING:这个编码指的是保存的位数,一般使用16位。
.
AudioRecord.getMinBufferSize:每一帧的最小大小,如果是读操作,就要用到它。
MediaCodec
音视频的编码和解码器,应该是这个系列最重要的API了,为了配合他的使用,还得用到MediaFormat等其他的API。
- // 这里仅仅是一个简单的例子,MediaCodec的使用要更复杂一些// 创建一个avc格式的视频编码器mediaCodec = MediaCodec.createEncoderByType(MediaFormat.MIMETYPE_VIDEO_AVC)// 详细配置MediaFormatval mediaFormat = MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, width, height)mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, 125000)mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 15)mediaFormat.setInteger( MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface)mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 5)// 使用配置好的MediaFormatmediaCodec!!.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE)// 开始编码mediaCodec!!.start()
复制代码 在实际应用中,MediaCodec的使用要更加复杂一些,这里只是先简单了解,之后的案例中我们再慢慢分析。
MediaExtractor
音视频分提取器,例如把某视频文件中的音频提取出来保存成一个音频文件。
- // 创建一个分离器,还没有指定要分离的部分val mediaExtractor = MediaExtractor()// 文件路径mediaExtractor.setDataSource(file.absolutePath)// trackCount表示有多少可以分离的轨道,常用的音轨和视轨val trackNum = mediaExtractor.trackCountfor (i in 0 until trackNum) { // 对应轨道的格式 val mediaFormat = mediaExtractor.getTrackFormat(i) // 音频:“audio/”,视频:“video/” val format = mediaFormat.getString("mime") if (format.startsWith(prefix)) { // 选择需要的轨道,接下来就可以提取这个轨道的内容了 videoMediaExtractor.selectTrack(videoIndex) }}// 读取内容 val frameSize = mediaExtractor.readSampleData(mReadBuffer, 0)...// 释放资源mediaExtractor.release()
复制代码 MediaMuxer
音视频合成器,视频音频合成,视频合成等等,常用与刚才的MediaExtractor一起使用
- mediaMuxer = MediaMuxer(outPath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4)val mReadBuffer = ByteBuffer.allocate(MAX_BUFF_SIZE)// 选择音轨 val audioMediaExtractor = MediaExtractor()audioMediaExtractor.setDataSource(path)val audioIndex = findTrackIndex(audioMediaExtractor, "audio/")audioMediaExtractor.selectTrack(audioIndex)// 读取帧数据val frameSize = mediaExtractor.readSampleData(mReadBuffer, 0)mReadBuffer.rewind()// 将数据写入到合成文件中mediaMuxer!!.writeSampleData(outTrackIndex, mReadBuffer, bufferInfo)// 释放mediaMuxer!!.release()
复制代码 总结
今天我们了解了Android原生常用的API,这些API已经足够满足我们开发中的各种需要,接下来我们要完成以下任务:
- MediaRecoder录制音频和视频
- MediaPlayer播放音频和视频
- MediaCodec播放音频和视频
- AudioRecoder录制PCM音频和播放
- MediaCodec录制视频
- 音视频合成和抽取
- 断点录制以及视频合成
(以上任务不分先后,顺序可能会变)
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |
免责声明
1. 本论坛所提供的信息均来自网络,本网站只提供平台服务,所有账号发表的言论与本网站无关。
2. 其他单位或个人在使用、转载或引用本文时,必须事先获得该帖子作者和本人的同意。
3. 本帖部分内容转载自其他媒体,但并不代表本人赞同其观点和对其真实性负责。
4. 如有侵权,请立即联系,本网站将及时删除相关内容。
|