这里写代码片
网上差值视频压缩,大多说都是说使用FFmpeg。于是就找例子,找来找去发现他们所用的代码都是一样的:
例如这个:这里写链接内容
看完代码,依然一脸懵逼,里面的参数不知道什么意思,根据代码可以知道,最主要的一段话是:
"-y -i /mnt/sdcard/kaishi.mp4 -strict -2 -vcodec libx264 -preset ultrafast -crf 24 -acodec aac -ar 44100 -ac 2 -b:a 96k -s 640x352 -aspect 16:9 /mnt/sdcard/jieshu.mp4";
这个个转码命令例如:
将input.avi转码成output.ts,并设置视频的码率为640kbps
ffmpeg -i input.avi -b:v 640k output.ts
参照雷神给的文档:这里写链接内容
-I filename 输入文件
strict strictness 跟标准的严格性
-vcodec codec 强制使用codec编解码方式。如果用copy表示原始编解码数据必须被拷贝。
-acodec codec 使用codec编解码
-ar freq 设置音频采样率
-ac channels 设置通道 缺省为1
-b bitrate 设置比特率,缺省200kb/s
-s size 设置帧大小 格式为WXH 缺省160X128.下面的简写也可以直接使用
-aspect aspect 设置横纵比 4:3 16:9 或 1.3333 1.7777
压缩的回调
@Override
public void onExecSuccess(String message) {
Log.e("压缩成功",message);
Toast.makeText(getApplicationContext(), message, 1).show();
}
@Override
public void onExecFail(String reason) {
Log.i("fail",reason);
}
@Override
public void onExecProgress(String message) {}
按照以往的作法,应该会在onexecprogerss里面获得压缩进度,但是根据打印的数据,他的内容是这样的。并且并不是所有的数据都是这样。
frame= 337 fps= 14 q=22.0 size= 2071kB time=00:00:11.74 bitrate=1444.2kbits/s dup=1 drop=0
于是我想了一个比较笨的方法,截取字符串。size后面的数据是指压缩的大小,那么如果我们计算出压缩比例,也就是说压缩后视频的大小。然后相除,就会得到压缩的比例。
-b bitrate 设置比特率,缺省200kb 比特率乘以时长应该就是压缩后视频的大小,这样似乎就行的通了。
MediaCodec硬编码
首先,要获取到CAMERA的回掉回来的YUV数据。
其次,将获得到的数据用MEDIACODEC编码为H264。
最后,将H264写入文件,程序结束后,可用VLC等支持播放H264的播放器查看效果。
android摄像头模块不仅预览,拍照这么简单,而是需要在预览视频的时候,能够做出一些检测,比如最常见的人脸检测。在未按下拍照按钮前,就检测出人脸然后矩形框标示出来,再按拍照。那么如何获得预览帧视频么?
只需要在Activity里继承PreviewCallback这个接口就行了
queueInputBuffer和dequeueInputBuffer是一对方法,两个要在一起使用哦。
首先,这一对函数的应用场合是对输入的数据流进行编码或者解码处理的时候,你会通过各种方法获得一个ByteBuffer的数组,这些数据就是准备处理的数据。
你要通过自己的方法找到你要处理的部分,然后调用dequeueInputBuffer方法提取出要处理的部分(也就是一个ByteBuffer数据流),把这一部分放到缓存区。
接下来就是你自己对于这个数据流的处理了。
然后在处理完毕之后,一定要调用queueInputBuffer把这个ByteBuffer放回到队列中,这样才能正确释放缓存区。
这个方法的意思是看是否支持 avc,也就是 H.248
private boolean SupportAvcCodec(){
if(Build.VERSION.SDK_INT>=18){
for(int j = MediaCodecList.getCodecCount() - 1; j >= 0; j--){
MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(j);
String[] types = codecInfo.getSupportedTypes();
for (int i = 0; i < types.length; i++) {
if (types[i].equalsIgnoreCase("video/avc")) {
return true;
}
}
}
}
return false;
}