美文网首页
转载:裁剪正方形视频

转载:裁剪正方形视频

作者: 43d60efa37c7 | 来源:发表于2017-02-15 14:20 被阅读106次

转自:http://blog.csdn.net/coderyue/article/details/52830564 

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

1. 获取相机实例

/**    * 获取Camera实例

  *    *@return

*/

privateCameragetCamera(intid) {       

Camera camera =null;

try{           

camera = Camera.open(id);      

}catch(Exception e) {      

}

returncamera;    }

2.  开启预览

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

/**

* 预览相机

*/

privatevoidstartPreview(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();     

  }  

}

/**

* 设置

*/

privatevoidsetupCamera(Camera camera) {

if(camera !=null) {           

Camera.Parameters parameters = camera.getParameters();          

List 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 videoSiezes =null;if(parameters !=null) {                

              videoSiezes = parameters.getSupportedVideoSizes();

for(Camera.Size size : videoSiezes) {       

        }       

    }

if(videoSiezes !=null&& videoSiezes.size() >0) {        

                      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);     

      }           

            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才是surfaceView的高度

* 一般相机都是屏幕的宽度 这里设置为屏幕宽度 高度自适应 你也可以设置自己想要的大小

*/

FrameLayout.LayoutParams params =newFrameLayout.LayoutParams(screenWidth, (screenWidth * video_width) / video_height);         

              surfaceView.setLayoutParams(params);    

      RelativeLayout.LayoutParams layoutParams =newRelativeLayout.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)            //初始化一个MediaRecorder            if (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_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.AACprofile.audioChannels=1profile.audioSampleRate=16000profile.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() {                @Override                public 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() {                @Override                public void onInfo(MediaRecorder mr, int what, int extra) {                    //录制完成                }            })            // 准备、开始            mediaRecorder.prepare()            mediaRecorder.start()            new Thread(new Runnable() {                @Override                public void run() {                    for (int i =0try {                            Thread.currentThread().sleep(20)                            Message message = new Message()                            message.what=1message.obj= i                            handler.sendMessage(message)                        } catch (InterruptedException e) {                            e.printStackTrace()                        }                    }                }            }).start()        } catch (Exception e) {            e.printStackTrace()        }    }

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

使用

ffmpeg 对视频进行裁剪正方形, ffmpeg 使用Shell命令的方式进行视频操作, 执行效率也是非常好, 那首先你要集成FFmpeg

到Android 项目里面, 这里我下载好了一个library, 直接引入到项目即可, 感兴趣的伙伴可以自己编译一个库,

这里我把命令贴出来解释一下,

ffmpeg-threads4-y-i/storage/emulated/0/CustomCamera/temp/1476598263062.mp4-metadata:s:v rotate="0"-vftranspose=1, crop=width:height:x:y-presetultrafast-tunezerolatency-r25-vcodeclibx264-acodeccopy /storage/emulated/0/CustomCamera/VIDEO/1476598263062.mp4

1

1

-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,newShellUtils.ShellCallback() {                                @OverridepublicvoidshellOut(String shellLine) {                                }                                @OverridepublicvoidprocessComplete(intexitValue) {                                    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等等的格式转换类似的功能可以考虑使用

相关文章

网友评论

      本文标题:转载:裁剪正方形视频

      本文链接:https://www.haomeiwen.com/subject/ltjqwttx.html