您的位置:首页 > 移动开发 > Android开发

Android Multimedia实战(二)使用MediaRecorder实现分段录制视频,mp4parser合成视频功能

2017-04-26 16:00 633 查看

demo如下:

下载地址:http://download.csdn.net/detail/king1425/9763984

这个demo是很久以前我为了试一些小功能写的。现在回归整理的时候也记录一下吧,代码比较乱,是基于Eclipse的。但是这个demo不止实现了录像功能。拍照,录像,前后摄像头,闪光灯,预览比例,相片质量等。如果你要学Camera开发,从这里入手也比较好。



1.MediaRecorder类介绍:

MediaRecorder类是Android sdk提供的一个专门用于音视频录制,一般利用手机麦克风采集音频,摄像头采集图片信息。


MediaRecorder主要函数:

setAudioChannels(int numChannels) 设置录制的音频通道数

setAudioEncoder(int audio_encoder) 设置audio的编码格式

setAudioEncodingBitRate(int bitRate) 设置录制的音频编码比特率

setAudioSamplingRate(int samplingRate) 设置录制的音频采样率

setAudioSource(int audio_source) 设置用于录制的音源

setAuxiliaryOutputFile(String path) 辅助时间的推移视频文件的路径传递

setAuxiliaryOutputFile(FileDescriptor fd)在文件描述符传递的辅助时间的推移视频

setCamera(Camera c) 设置一个recording的摄像头

setCaptureRate(double fps) 设置视频帧的捕获率

setMaxDuration(int max_duration_ms) 设置记录会话的最大持续时间(毫秒)

setMaxFileSize(long max_filesize_bytes) 设置记录会话的最大大小(以字节为单位)

setOutputFile(FileDescriptor fd) 传递要写入的文件的文件描述符

setOutputFile(String path) 设置输出文件的路径

setOutputFormat(int output_format) 设置在录制过程中产生的输出文件的格式

setPreviewDisplay(Surface sv) 表面设置显示记录媒体(视频)的预览

setVideoEncoder(int video_encoder) 设置视频编码器,用于录制

setVideoEncodingBitRate(int bitRate) 设置录制的视频编码比特率

setVideoFrameRate(int rate) 设置要捕获的视频帧速率

setVideoSize(int width, int height) 设置要捕获的视频的宽度和高度

setVideoSource(int video_source) 开始捕捉和编码数据到setOutputFile(指定的文件)

setLocation(float latitude, float longitude) 设置并存储在输出文件中的地理数据(经度和纬度)

setProfile(CamcorderProfile profile) 指定CamcorderProfile对象

setOrientationHint(int degrees)设置输出的视频播放的方向提示

setOnErrorListener(MediaRecorder.OnErrorListener l)注册一个用于记录录制时出现的错误的监听器

setOnInfoListener(MediaRecorder.OnInfoListener listener)注册一个用于记录录制时出现的信息事件

getMaxAmplitude() 获取在前一次调用此方法之后录音中出现的最大振幅

prepare()准备录制。

release()释放资源

reset()将MediaRecorder设为空闲状态

start()开始录制

stop()停止录制

MediaRecorder主要配置参数:

1.)视频编码格式MediaRecorder.VideoEncoder

default,H263,H264,MPEG_4_SP,VP8


2.)音频编码格式MediaRecorder.AudioEncoder

default,AAC,HE_AAC,AAC_ELD,AMR_NB,AMR_WB,VORBIS


3.)视频资源获取方式MediaRecorder.VideoSource

default,CAMERA,SURFACE


4.)音频资源获取方式MediaRecorder.AudioSource

defalut,camcorder,mic,voice_call,voice_communication,voice_downlink,voice_recognition, voice_uplink


5.)资源输出格式MediaRecorder.OutputFormat

amr_nb,amr_wb,default,mpeg_4,raw_amr,three_gpp,aac_adif, aac_adts, output_format_rtp_avp, output_format_mpeg2ts ,webm


1.声明MediaRecorder

private MediaRecorder mMediaRecorder;


2.然后开始录制的时候初始化mMediaRecorder

private void initMediaRecoder(){
mCamera.unlock();
mMediaRecorder = new MediaRecorder();
mMediaRecorder.setCamera(mCamera);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mMediaRecorder.setVideoSize(1280,720);
mMediaRecorder.setVideoFrameRate(20);
mMediaRecorder.setVideoEncodingBitRate(1 * 1024 * 1024);
mMediaRecorder.setOrientationHint(cameraId>0?270:90);//前后置判断
mMediaRecorder.setPreviewDisplay(mHolder.getSurface());
fileName = "myVideo"+mTimeUtils.getYMDHMS() +".mp4";
mMediaRecorder.setOutputFile(MyThread.GetVideoFolder()+"/"+fileName);
}


上述Utils代码如下:

//--->mTimeUtils
public String getYMDHMS(){
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
//MyThread.GetVideoFolder()
public static String GetVideoFolder() {
String parentPath = Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/MyPicture/video";
File tempFile = new File(parentPath);
if (!tempFile.exists()) {
tempFile.mkdirs();
}
return parentPath;
}

}


停止与开始:

//停止
mMediaRecorder.stop();
mMediaRecorder.reset();
mMediaRecorder.release();
mMediaRecorder = null;


//开始
initMediaRecoder();
mMediaRecorder.prepare();
mMediaRecorder.start();


2.mp4parser

因为可以暂停再继续录制所以我们用mp4parser 进行视频合成

mp4parser :https://github.com/sannies/mp4parser

在每次暂停的时候我们用list保存下来

videoList.add(MyThread.GetVideoFolder()+"/"+fileName);


最终执行:

//@MyThread
private void appendVideos(){
try {
List<Track> videoTracks = new LinkedList<Track>();
List<Track> audioTracks = new LinkedList<Track>();
for (String fn :videoList) {
try {
Movie movie = MovieCreator.build(fn);
for (Track t : movie.getTracks()) {
if (t.getHandler().equals("soun")) {
audioTracks.add(t);
}
if (t.getHandler().equals("vide")) {
videoTracks.add(t);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
Movie result = new Movie();

if (audioTracks.size() > 0) {
result.addTrack(new AppendTrack(audioTracks
.toArray(new Track[audioTracks.size()])));
}
if (videoTracks.size() > 0) {
result.addTrack(new AppendTrack(videoTracks
.toArray(new Track[videoTracks.size()])));
}
Container out = new DefaultMp4Builder().build(result);
RandomAccessFile randomAccessFile = new RandomAccessFile(
String.format(getFinalVideoFileName()), "rw");
FileChannel fc = randomAccessFile.getChannel();
out.writeContainer(fc);
randomAccessFile.close();
fc.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐