使用FFMpeg实现视频录制与压缩

使用https://github.com/mabeijianxi/small-video-record项目来实现视频录制与压缩,博主博客:利用FFmpeg玩转Android视频录制与压缩(一) - CSDN博客 http://blog.csdn.net/mabeijianxi/article/details/63335722

下面主要讲解如何把此项目引进自己的工程并做适当修改为符合自身项目滴。

博主讲解了使用方法https://github.com/mabeijianxi/small-video-record使用方法中文文档,此处纯粹记录一下自己引进的具体步骤。

使用导入SmallVideoLib2的方法实现。

引进步骤:

1.下载源码GitHub - mabeijianxi/small-video-record: 利用FFmpeg视频录制微信小视频与其压缩处理 https://github.com/mabeijianxi/small-video-record下面的操作使用的是SmallVideoRecord2的源代码。

2.新建一个自己的项目,此处名为“TestDemo”, 使用Androidstudio2.3.3

3.把“SmallVideoRecord2”工程里的”all_lib”文件夹

拷进自己的工程“VideoDemo”中
这里写图片描述

4.为自己的工程引进module——SmallVideoLib2

5.把“SmallVideoRecord2”工程里的“sample”中的与界面布局、activity代码相关的东西全部复制进自己的工程,然后刷新运行程序,完成啦~~~,接下来就是研究理解源代码,为自己的项目定制功能啦

修改:

1.视频文件保存路径
博主原先是保存在SD卡DCIM文件下的,改为指定文件夹保存。
先添加两个方法,用于生成或获得指定的文件夹路径:

 /**
     * 获取SD卡路径
     *
     * @return
     */
    public static String getSDPath() {
        File sdDir = null;
        // 判断sd卡是否存在
        boolean sdCardExist = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
        if (sdCardExist) {
            sdDir = Environment.getExternalStorageDirectory();//获取根目录
            return sdDir.toString();
        }
        return null;
    }

    /**
     * 获取录制视频的路径
     * @return
     */
    public static String getVideoRecordDir(){
        String dirPath = getSDPath();
        dirPath += "/" + "videorecordcompress";
        File file = new File(dirPath);
        if(!file.exists()){
            file.mkdir();
        }
        dirPath +="/"+"videorecord";
        file = new File(dirPath);
        if(!file.exists()){
            file.mkdir();
        }
        return dirPath;
    }

private static File recordDir;//录制文件
在MainActivity中的initSmallVideo方法中进行接下来的修改:

 public static void initSmallVideo() {
        // 设置拍摄视频缓存文件夹的路径
//        File dcim = Environment
//                .getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
//        if (DeviceUtils.isZte()) {
//            if (dcim.exists()) {
//                JianXiCamera.setVideoCachePath(dcim + "/mabeijianxi/");
//            } else {
//                JianXiCamera.setVideoCachePath(dcim.getPath().replace("/sdcard/",
//                        "/sdcard-ext/")
//                        + "/mabeijianxi/");
//            }
//        } else {
//            JianXiCamera.setVideoCachePath(dcim + "/mabeijianxi/");
//        }
        recordDir = new File(getVideoRecordDir());        
        JianXiCamera.setVideoCachePath(recordDir.getAbsolutePath());       
        // 初始化拍摄
        JianXiCamera.initialize(false, null);
    }

2.为录制的视频指定名字

在MediaRecorderActivity中的initMediaRecorder方法里修改:
先添加此方法:

/**获取系统时间- 视频保存的时间*/
    public static String getCurrentDate() {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
        Date curDate = new Date(System.currentTimeMillis());
        String date = formatter.format(curDate);
        return date;
    }

再修改key的值:

        if (!FileUtils.checkFile(f)) {
            f.mkdirs();
        }
        //录制的视频名字、路径
        String key = getCurrentDate(); //String.valueOf(System.currentTimeMillis());
        mMediaObject = mMediaRecorder.setOutputDirectory(key,
                JianXiCamera.getVideoCachePath() + "/" + key);
        mMediaRecorder.setSurfaceHolder(mSurfaceView.getHolder());
        mMediaRecorder.prepare();
        //录制的视频名字、路径
        String key = getCurrentDate(); //String.valueOf(System.currentTimeMillis());
        mMediaObject = mMediaRecorder.setOutputDirectory(key,
                JianXiCamera.getVideoCachePath() + "/" + key);
        mMediaRecorder.setSurfaceHolder(mSurfaceView.getHolder());
        mMediaRecorder.prepare();

3.压缩指定路径下的视频
原先是打开文件选择对话框,进行选择任一视频。

 /**
     * 压缩指定视频文件
     * @param videoFilePath
     */
    private void compressVideo(String videoFilePath){

        File file = new File(videoFilePath);
        if(!file.exists()){
            Toast.makeText(this, "视频文件不存在,无法执行压缩操作", Toast.LENGTH_SHORT).show();
            return;
        }
        BaseMediaBitrateConfig compressMode = null;

        int compressModeCheckedId = rg_only_compress_mode.getCheckedRadioButtonId();

        if (compressModeCheckedId == R.id.rb_cbr) {
            String bitrate = et_only_compress_bitrate.getText().toString();
            if (checkStrEmpty(bitrate, "请输入压缩额定码率")) {
                return;
            }
            compressMode = new CBRMode(166, Integer.valueOf(bitrate));
        } else if (compressModeCheckedId == R.id.rb_auto) {
            String crfSize = et_only_compress_crfSize.getText().toString();
            if (TextUtils.isEmpty(crfSize)) {
                compressMode = new AutoVBRMode();
            } else {
                compressMode = new AutoVBRMode(Integer.valueOf(crfSize));
            }
        } else if (compressModeCheckedId == R.id.rb_vbr) {
            String maxBitrate = et_only_compress_maxbitrate.getText().toString();
            String bitrate = et_only_compress_bitrate.getText().toString();

            if (checkStrEmpty(maxBitrate, "请输入压缩最大码率") || checkStrEmpty(bitrate, "请输入压缩额定码率")) {
                return;
            }
            compressMode = new VBRMode(Integer.valueOf(maxBitrate), Integer.valueOf(bitrate));
        } else {
            compressMode = new AutoVBRMode();
        }

        if (!spinner_only_compress.getSelectedItem().toString().equals("none")) {
            compressMode.setVelocity(spinner_only_compress.getSelectedItem().toString());
        }

        String sRate = et_only_framerate.getText().toString();
        String scale = et_only_scale.getText().toString();
        int iRate = 0;
        float fScale = 0;
        if (!TextUtils.isEmpty(sRate)) {
            iRate = Integer.valueOf(sRate);
        }
        if (!TextUtils.isEmpty(scale)) {
            fScale = Float.valueOf(scale);
        }
        LocalMediaConfig.Buidler buidler = new LocalMediaConfig.Buidler();
        final LocalMediaConfig config = buidler
                .setVideoPath(videoFilePath)
                .captureThumbnailsTime(1)
                .doH264Compress(compressMode)
                .setFramerate(iRate)
                .setScale(fScale)
                .build();
        new Thread(new Runnable() {
            @Override
            public void run() {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        showProgress("", "压缩中...", -1);
                    }
                });
                OnlyCompressOverBean onlyCompressOverBean = new LocalMediaCompress(config).startCompress();
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        hideProgress();
                    }
                });
                Intent intent = new Intent(MainActivity.this, SendSmallVideoActivity.class);
                intent.putExtra(MediaRecorderActivity.VIDEO_URI, onlyCompressOverBean.getVideoPath());
                intent.putExtra(MediaRecorderActivity.VIDEO_SCREENSHOT, onlyCompressOverBean.getPicPath());
                startActivity(intent);
            }
        }).start();
    }

修改MainActivity中的choose方法:

public void choose(View v) {

//        Intent it = new Intent(Intent.ACTION_GET_CONTENT,
//                android.provider.MediaStore.Video.Media.EXTERNAL_CONTENT_URI);
//
//        it.setDataAndType(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, "video/*");
//        startActivityForResult(it, CHOOSE_CODE);

        String videoFilePath = recordDir.getAbsolutePath() + "/videorecord1519898039101/1519898039101.mp4";
        compressVideo(videoFilePath);

    }

4.为压缩视频指定保存的路径

  private static File compressDir;//压缩文件
/**
     * 获取SD卡路径
     *
     * @return
     */
    public static String getSDPath() {
        File sdDir = null;
        // 判断sd卡是否存在
        boolean sdCardExist = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
        if (sdCardExist) {
            sdDir = Environment.getExternalStorageDirectory();//获取根目录
            return sdDir.toString();
        }
        return null;
    }
/**
     * 获取压缩视频的路径
     * @return
     */
    public static String getVideoCompressDir(){
        String dirPath = getSDPath();
        dirPath += "/" + "videorecordcompress";
        File file = new File(dirPath);
        if(!file.exists()){
            file.mkdir();
        }
        dirPath +="/"+"videocompress";
        file = new File(dirPath);
        if(!file.exists()){
            file.mkdir();
        }
        return dirPath;
    }

在JianXiCamera里添加:

/** 视频压缩路径 */
    private static String mVideoCompressPath;
     /** 获取视频压缩文件夹 */
    public static String getVideoCompressPath() {
        return mVideoCompressPath;
    }
    /** 设置视频压缩路径 */
    public static void setVideoCompressPath(String path) {
        File file = new File(path);
        if (!file.exists()) {
            file.mkdirs();
        }
        mVideoCompressPath = path;
    }

现在MainActivity中的initSmallVideo方法就应该为:

public static void initSmallVideo() {
        // 设置拍摄视频缓存文件夹的路径
//        File dcim = Environment
//                .getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
//        if (DeviceUtils.isZte()) {
//            if (dcim.exists()) {
//                JianXiCamera.setVideoCachePath(dcim + "/mabeijianxi/");
//            } else {
//                JianXiCamera.setVideoCachePath(dcim.getPath().replace("/sdcard/",
//                        "/sdcard-ext/")
//                        + "/mabeijianxi/");
//            }
//        } else {
//            JianXiCamera.setVideoCachePath(dcim + "/mabeijianxi/");
//        }
        recordDir = new File(getVideoRecordDir());
        compressDir = new File(getVideoCompressDir());
        JianXiCamera.setVideoCachePath(recordDir.getAbsolutePath());
        JianXiCamera.setVideoCompressPath(compressDir.getAbsolutePath());
        // 初始化拍摄
        JianXiCamera.initialize(false, null);
    }

5.修改压缩视频的名字:
在LocalMediaCompress里的public OnlyCompressOverBean startCompress() 方法中进行修改key的值:

File f = new File(JianXiCamera.getVideoCachePath());
        if (!FileUtils.checkFile(f)) {
            f.mkdirs();
        }
        //压缩后的视频文件名字、路径
        String key = getCurrentDate();//String.valueOf(System.currentTimeMillis());
        mMediaObject = setOutputDirectory(key,
                JianXiCamera.getVideoCompressPath() + "/" + key);

        mMediaObject.setOutputTempVideoPath(mNeedCompressVideo);
/**
     * 获取系统时间- 视频保存的时间
     *
     * @return
     */
    public static String getCurrentDate() {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
        Date curDate = new Date(System.currentTimeMillis());
        String date = formatter.format(curDate);
        return date;
    }

6.其他一些修改就不写了,花时间慢慢研究肯定值得滴

推荐学习网址:

1.首先肯定是使用的源代码博主滴博客啦( ̄▽ ̄)/利用FFmpeg玩转Android视频录制与压缩(一) - CSDN博客 http://blog.csdn.net/mabeijianxi/article/details/63335722
2.在视频影音方面特别厉害的博主最简单的基于FFmpeg的移动端例子:Android HelloWorld - CSDN博客 http://blog.csdn.net/leixiaohua1020/article/details/47008825/

猜你喜欢

转载自blog.csdn.net/an_nal/article/details/79420308