到目前为止 Android 中还不能直接录制正方形的视频, 虽然不能直接录但是我们也有一些方式来处理录制后的视频, 之前我写过一篇文章 Android 自定义Camera(一), 可以先了解一下如何做一个简单的自定义相机demo, 那录制视频也要开启相机预览, 有以下几个步骤和需要注意的地方:

1. 获取相机实例

/*** 获取Camera实例** @return*/private Camera getCamera(int id) {Camera camera = null;try {camera = Camera.open(id);} catch (Exception e) {}return camera;}

2. 开启预览
要注意, 开启预览要在 Activity 的 onResume 方法里面开启, 然后在 onPause 方法里面释放相机资源, 举一个简单的例子, 如果你在预览的时候按下了home键, 此时再次打开程序, 如果你是在 Oncreate 方法里面开启相机, 那么再次打开预览界面应该会卡住。

/*** 预览相机*/private void startPreview(Camera camera, SurfaceHolder holder) {try {setupCamera(camera);camera.setPreviewDisplay(holder);//获取相机预览角度, 后面录制视频需要用recorderRotation = CameraUtil.getInstance().getRecorderRotation(mCameraId);CameraUtil.getInstance().setCameraDisplayOrientation(this, mCameraId, camera);camera.startPreview();} catch (IOException e) {e.printStackTrace();}}/*** 设置*/private void setupCamera(Camera camera) {if (camera != null) {Camera.Parameters parameters = camera.getParameters();List<String> focusModes = parameters.getSupportedFocusModes();if (focusModes != null && focusModes.size() > 0) {if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {//设置自动对焦parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);}}List<Camera.Size> videoSiezes = null;if (parameters != null) {//获取相机所有支持尺寸videoSiezes = parameters.getSupportedVideoSizes();for (Camera.Size size : videoSiezes) {}}if (videoSiezes != null && videoSiezes.size() > 0) {//拿到一个预览宽度最小为720像素的预览值 Camera.Size videoSize = CameraUtil.getInstance().getPropVideoSize(videoSiezes, 720);video_width = videoSize.width;video_height = videoSize.height;LogUtils.i("video_width===" + video_width);LogUtils.i("video_height===" + video_height);}//这里第三个参数为最小尺寸 getPropPreviewSize方法会对从最小尺寸开始升序排列 取出所有支持尺寸的最小尺寸Camera.Size previewSize = CameraUtil.getInstance().getPropPreviewSize(parameters.getSupportedPreviewSizes(), video_width);parameters.setPreviewSize(previewSize.width, previewSize.height);Camera.Size pictrueSize = CameraUtil.getInstance().getPropPictureSize(parameters.getSupportedPictureSizes(), video_width);parameters.setPictureSize(pictrueSize.width, pictrueSize.height);camera.setParameters(parameters);/*** 设置surfaceView的尺寸 因为camera默认是横屏,所以取得支持尺寸也都是横屏的尺寸* 我们在startPreview方法里面把它矫正了过来,但是这里我们设置设置surfaceView的尺寸的时候要注意 previewSize.height<previewSize.width* previewSize.width才是surfaceView的高度* 一般相机都是屏幕的宽度 这里设置为屏幕宽度 高度自适应 你也可以设置自己想要的大小*/FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(screenWidth, (screenWidth * video_width) / video_height);//这里当然可以设置拍照位置 比如居中 我这里就置顶了surfaceView.setLayoutParams(params);RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(screenWidth, screenheight - screenWidth);layoutParams.addRule(RelativeLayout.BELOW, surfaceView.getId());layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);bottomLayout.setLayoutParams(layoutParams);}}

3. 开始录制

这里要注意的是 MediaRecorder 的相关方法的调用顺序时候不能乱的, 详细可以看官网api说明

接下来开启录制:

protected void start() {try {pathName = System.currentTimeMillis() + "";//视频存储路径file = new File(MyApplication.getInstance().getTempPath() + File.separator + pathName + AppConfig.MP4);//如果没有要创建BitmapUtils.makeDir(file);//初始化一个MediaRecorderif (mediaRecorder == null) {mediaRecorder = new MediaRecorder();} else {mediaRecorder.reset();}mCamera.unlock();mediaRecorder.setCamera(mCamera);//设置视频输出的方向 很多设备在播放的时候需要设个参数 这算是一个文件属性mediaRecorder.setOrientationHint(recorderRotation);//视频源类型mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);mediaRecorder.setAudioChannels(2);// 设置视频图像的录入源// 设置录入媒体的输出格式
//            mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);// 设置音频的编码格式
//            mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);// 设置视频的编码格式
//            mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);if (CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_720P)) {profile = CamcorderProfile.get(CamcorderProfile.QUALITY_720P);} /*else if (CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_720P)) {profile = CamcorderProfile.get(CamcorderProfile.QUALITY_720P);} */ else if (CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_1080P)) {profile = CamcorderProfile.get(CamcorderProfile.QUALITY_1080P);} else if (CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_HIGH)) {profile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);} else if (CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_LOW)) {profile = CamcorderProfile.get(CamcorderProfile.QUALITY_LOW);}if (profile != null) {profile.audioCodec = MediaRecorder.AudioEncoder.AAC;profile.audioChannels = 1;profile.audioSampleRate = 16000;profile.videoCodec = MediaRecorder.VideoEncoder.H264;mediaRecorder.setProfile(profile);}//视频尺寸mediaRecorder.setVideoSize(video_width, video_height);//数值越大 视频质量越高mediaRecorder.setVideoEncodingBitRate(5 * 1024 * 1024);// 设置视频的采样率,每秒帧数
//            mediaRecorder.setVideoFrameRate(5);// 设置录制视频文件的输出路径mediaRecorder.setOutputFile(file.getAbsolutePath());mediaRecorder.setMaxDuration(2000);// 设置捕获视频图像的预览界面mediaRecorder.setPreviewDisplay(surfaceView.getHolder().getSurface());mediaRecorder.setOnErrorListener(new MediaRecorder.OnErrorListener() {@Overridepublic void onError(MediaRecorder mr, int what, int extra) {// 发生错误,停止录制if (mediaRecorder != null) {mediaRecorder.stop();mediaRecorder.release();mediaRecorder = null;LogUtils.i("Error");}}});mediaRecorder.setOnInfoListener(new MediaRecorder.OnInfoListener() {@Overridepublic void onInfo(MediaRecorder mr, int what, int extra) {//录制完成}});// 准备、开始mediaRecorder.prepare();mediaRecorder.start();new Thread(new Runnable() {@Overridepublic void run() {for (int i = 0; i < PROGRESS_MAX; i++) {try {Thread.currentThread().sleep(20);Message message = new Message();message.what = 1;message.obj = i;handler.sendMessage(message);} catch (InterruptedException e) {e.printStackTrace();}}}}).start();} catch (Exception e) {e.printStackTrace();}}

4. 录制成功后接下来的重点来了

使用 ffmpeg 对视频进行裁剪正方形, ffmpeg 使用Shell命令的方式进行视频操作, 执行效率也是非常好, 那首先你要集成FFmpeg 到Android 项目里面, 这里我下载好了一个library, 直接引入到项目即可, 感兴趣的伙伴可以自己编译一个库, 这里我把命令贴出来解释一下,

ffmpeg -threads 4 -y -i /storage/emulated/0/CustomCamera/temp/1476598263062.mp4 -metadata:s:v rotate="0" -vf transpose=1, crop=width:height:x:y -preset ultrafast -tune zerolatency -r 25 -vcodec libx264 -acodec copy /storage/emulated/0/CustomCamera/VIDEO/1476598263062.mp4

-y: 如果文件存在那么覆盖掉

-i: 输入

metadata:s:v rotate=”0” : 重新编码 除去rotate, 因为默认录制出来的是横屏视频, 这里重新编码

transpose=1 :
0 = 90CounterCLockwise and Vertical Flip (default) 逆时针旋转90度并且垂直翻转, 下面类推
1 = 90Clockwise
2 = 90CounterClockwise
3 = 90Clockwise and Vertical Flip

crop=width:height:x:y,其中 width 和 height 表示裁剪后的尺寸,x:y 表示裁剪区域的左上角坐标

-preset ultrafast -tune zerolatency: 加快效率

r 25:帧率

-vcodec libx264 -acodec: 编码方式libx264
如果想知道更多关于ffmpeg的东西可以访问官网 https://ffmpeg.org/

再贴一下我的代码调用:

try {fc.compress_clipVideo(file.getAbsolutePath(),file2.getAbsolutePath(), mCameraId, video_width, video_height, 0, 0,new ShellUtils.ShellCallback() {@Overridepublic void shellOut(String shellLine) {}@Overridepublic void processComplete(int exitValue) {dialog.dismiss();if (exitValue != 0) {ToastFactory.showLongToast(context, getResources().getString(R.string.state_compress_error));mHandler.sendEmptyMessage(R.string.state_compress_error);} else {mHandler.sendEmptyMessage(R.string.state_compress_end);}}});} catch (Exception e) {e.printStackTrace();}

FFmpeg编译出来的Android 库还是很大的, 大约15M左右, 无疑增加了apk的大小, 如果你的产品方向是视频图片gif等等的格式转换类似的功能可以考虑使用

如果你对这样的功能感兴趣可以详细查看源码:

github 地址

https://github.com/jinguangyue/Android-CustomCamera

Android 使用FFmpeg 裁剪出正方形视频相关推荐

  1. ffmpeg 裁剪、合并视频的多个部分

    我需要裁剪视频文件的多个部分,并将其合并成一个新的视频. 如果我只想剪下一部分,我会做: ffmpeg -i video.mp4 -ss 00:00:03.500 -to 00:00:08.500 - ...

  2. 使用ffmpeg裁剪和合并视频

    剪切视频 使用 -ss 和 -t 选项,从第0秒开始,向后截取31秒视频,并保存 ffmpeg -ss 00:00:00 -i video.mp4 -vcodec copy -acodec copy ...

  3. android视频剪辑处理第三方,Android 中通过 FFmpeg 命令对音视频编辑处理

    以下文章来源于DevYk ,作者DevYK 音视频编辑器 前言 有时候我们想对音视频进行加工处理,比如视频编辑.添加字幕.裁剪等功能处理,虽然 Github 上开源了一些比较不错的项目,但是如果我们想 ...

  4. Android 中通过 FFmpeg 命令对音视频编辑处理(已开源)

    视音频编辑器 前言 有时候我们想对音视频进行加工处理,比如视频编辑.添加字幕.裁剪等功能处理,虽然 Github 上开源了一些比较不错的项目,但是如果我们想在此项目上进行二次开发,比如我想拿到该项目的 ...

  5. android音视频工程师,音视频学习 (十三) Android 中通过 FFmpeg 命令对音视频编辑处理(已开源)...

    ## 音视频学习 (十三) Android 中通过 FFmpeg 命令对音视频编辑处理(已开源) ## 视音频编辑器 ## 前言 有时候我们想对音视频进行加工处理,比如视频编辑.添加字幕.裁剪等功能处 ...

  6. 【ffmpeg裁剪视频faster rcnn自动检测 via】全自动实现ffmpeg将视频切割为图片帧,再使用faster rcnn将图片中的人检测出来,最后将检测结果转化为via可识别的csv格式

    目录 前言 一,ffmpeg 自动裁剪 1.1 目录结构 1.2 cutVideoToImage.sh 1.2 myVideo 1.3 myVideo15mins 1.5 myFrames 1.6 运 ...

  7. ffmpeg裁剪合并视频

    ffmpeg提供简单的命令参数: ffmpeg -ss START -t DURATION -i INPUT -vcodec copy -acodec copy OUTPUT 对上面的命令稍做个解释. ...

  8. android基于ffmpeg本地视频、在线视频、直播播放器 支持rtmp、rtsp、http等协议

    最近做了一个支持onvif标准的摄像头管理程序,主要就是在局域网中通过程序控制摄像头获取摄像头视频流分发给广域网中的客户端设备:这里面用了onvif协议相关知识和ffmpeg视频流处理的相关知识. o ...

  9. 【Android FFMPEG 开发】音视频基础 和 FFMPEG 编译 ( 音视频基础 | MPEG-4 标准 | Android 开发环境 | FFMPEG 交叉编译 | 安卓项目导入配置 )

    本篇博客代码及资源下载 : https://download.csdn.net/download/han1202012/10382762 文章目录 一. 音视频基础 1. 音频基础 (1) 声音要素 ...

最新文章

  1. 大数据量txt文本数据分块去重
  2. oracle10g提权,Oracle 10g提权测试
  3. mac电脑Git提交代码到Github提示git-credential-osxkeychain 验证解决方案
  4. 软件测试面试问答大全(2)
  5. C语言再学习-- assert 断言宏
  6. 曹大带我学 Go(12)—— 面向火焰图编程
  7. 常见操作系统调度算法研究(2)
  8. Linux中的Diff和Patch
  9. Android必学之数据适配器BaseAdapter
  10. 运用CSS3制作3D盒子骰子
  11. 地线与接地螺丝_28个配电接地的基本要求,最容易忽略的往往是最重要的
  12. 餐巾(cogs 461)
  13. python批量下载文件
  14. 电子政务互联互通软件平台的体系架构
  15. 18650锂电池保护板接线图_锂电池保护板几种接线方法介绍
  16. 阿里云,AWS,HTTPS和企业支付宝配置
  17. mac mysql 1055_Mysql 错误“1055”
  18. Could not publish server configuration for Apache Tomcat v7.0.22 at localhos
  19. 在线免费一键将头像转换卡通形象
  20. 专访阿里巴巴量子实验室:最强量子电路模拟器“太章”到底强在哪? 1

热门文章

  1. StarUML用户手册
  2. 途牛:一直被唱衰,就是没倒下
  3. expdp异地备份 (expdp导出数据到其他服务器)
  4. 天池精准医疗大赛——人工智能辅助糖尿病遗传风险预测
  5. js 通讯录(多音字)
  6. 如何修改aix服务器lv的名称,aix 更改lv的大小 smitty extendlv
  7. 14位IT高管及技术大牛谈Java的生态系统
  8. Python “最短”挑战(12.21)
  9. FPS游戏开发(3)
  10. 一部手机失窃引发的惊心动魄的战争