基于知乎matisse增强 拍摄视频并压缩

//单机拍找,长按录制              44star
implementation 'com.lxj:matisse:+'

https://github.com/li-xiaojun/Matisse

1 开启拍摄视频

    private void startREC() {
        Matisse.from(activity)
                .jumpCapture()
                .isCrop(false)//是否对拍照结果进行裁剪
                .forResult(Constans.REQUEST_CODE_CHOOSE);
    }

2 视频完返回

  @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == Constans.REQUEST_CODE_CHOOSE && resultCode == RESULT_OK) {
            //获取拍摄的图片路径,如果是录制视频则是视频的第一帧图片路径
            String captureImagePath = Matisse.obtainCaptureImageResult(data);

            //获取拍摄的视频路径
            String captureVideoPath = Matisse.obtainCaptureVideoResult(data);

            if (TextUtils.isEmpty(captureVideoPath)) {
                ArrayList<String> images = new ArrayList<>();
                images.add(captureImagePath);
                PublishCountrySideDynamicActivity2.create(this, images, null, null);//不是视频
            } else {
                //    PublishCountrySideDynamicActivity2.create(this, null, captureImagePath, captureVideoPath);
                VideoTrimmerActivity.call(this, captureVideoPath, true);//视频-转入详情压缩界面
            }
        } else if (requestCode == Constans.REQUSET) {
            initView();
        }

    }

3 压缩界面

public class VideoTrimmerActivity extends BaseActivity implements VideoTrimListener {

    private static final String TAG = "jason";
    private static final String VIDEO_PATH_KEY = "video-file-path";
    private static final String COMPRESSED_VIDEO_FILE_NAME = "compress.mp4";
    public static final int VIDEO_TRIM_REQUEST_CODE = 0x001;
    @BindView(R.id.trimmer_view)
    VideoTrimmerView trimmerView;
    private ProgressDialog mProgressDialog;
    private boolean isStartActivity;

    public static void call(FragmentActivity from, String videoPath, boolean isStartActivity) {
        if (!TextUtils.isEmpty(videoPath)) {
            Bundle bundle = new Bundle();
            bundle.putString(VIDEO_PATH_KEY, videoPath);
            bundle.putBoolean("isStartActivity", isStartActivity);
            Intent intent = new Intent(from, VideoTrimmerActivity.class);
            intent.putExtras(bundle);
            from.startActivityForResult(intent, VIDEO_TRIM_REQUEST_CODE);
        }
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_video_trim);
        ButterKnife.bind(this);
        Bundle bd = getIntent().getExtras();
        String path = "";
        if (bd != null) path = bd.getString(VIDEO_PATH_KEY);
        isStartActivity = bd.getBoolean("isStartActivity", true);
        if (trimmerView != null) {
            trimmerView.setOnTrimVideoListener(this);
            trimmerView.initVideoByURI(Uri.parse(path));
        }
    }

    @Override
    public void onResume() {
        super.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();
        trimmerView.onVideoPause();
        trimmerView.setRestoreState(true);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        trimmerView.onDestroy();
    }

    @Override
    public void onStartTrim() {
        buildDialog(getResources().getString(R.string.trimming)).show();
    }

    @Override
    public void onFinishTrim(final String in) {
        if (mProgressDialog.isShowing()) mProgressDialog.dismiss();
        //  ToastUtils.showToast(this, getString(R.string.trimmed_done));

        //TODO: please handle your trimmed video url here!!!
        //   String out = StorageUtil.getCacheDir() + File.separator + COMPRESSED_VIDEO_FILE_NAME;
        System.out.println(in);
        //  compressVideo(this, in, out);
        /*Intent intent = new Intent(this,PublishCountrySideDynamicActivity2.class);
        intent.putExtra("vedioPath",out);
        startActivity(intent);*/
        //buildDialog(getResources().getString(R.string.compressing)).show();
        //VideoCompressor.compress(this, in, out, new VideoCompressListener() {
        //  @Override public void onSuccess(String message) {
        //  }
        //
        //  @Override public void onFailure(String message) {
        //  }
        //.
        //  @Override public void onFinish() {
        //    if (mProgressDialog.isShowing()) mProgressDialog.dismiss();
        //    finish();
        //  }
        //});

        // 选择本地视频压缩
        LocalMediaConfig.Buidler buidler = new LocalMediaConfig.Buidler();
        final LocalMediaConfig config = buidler
                .setVideoPath(in)
                //  .captureThumbnailsTime(1)
                .doH264Compress(new AutoVBRMode())
                .setFramerate(15)
                .setScale(1.0f)
                .build();
        new Thread(new Runnable() {
            @Override
            public void run() {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        buildDialog("压缩中...").show();
                        //   showProgress("", "压缩中...", -1);
                        //  DialogShow.showRoundProcessDialog(VideoTrimmerActivity.this,"压缩中...");
                    }
                });
                final OnlyCompressOverBean onlyCompressOverBean = new LocalMediaCompress(config).startCompress();
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        //hideProgress();
                        if (mProgressDialog.isShowing()) mProgressDialog.dismiss();

                        Message msg = Message.obtain();
                        msg.what = Constans.ACTIVITY_FINISH;
                        EventBus.getDefault().post(msg);

                        if (isStartActivity) {
                            Intent intent = new Intent(VideoTrimmerActivity.this, PublishCountrySideDynamicActivity2.class);
                            intent.putExtra("videoPath", onlyCompressOverBean.getVideoPath());
                            intent.putExtra("videoPicPath", onlyCompressOverBean.getPicPath());
                            startActivity(intent);
                        } else {
                            Message msg2 = Message.obtain();
                            msg2.what = Constans.SELECTED_VEDIO;
                            Bundle bundle = new Bundle();
                            bundle.putString("videoPath", onlyCompressOverBean.getVideoPath());
                            bundle.putString("videoPicPath", onlyCompressOverBean.getPicPath());
                            msg2.obj = bundle;
                            EventBus.getDefault().post(msg2);
                        }

                        finish();

                    }
                });

            }
        }).start();

    }


    private void showProgress(String title, String message, int theme) {
        if (mProgressDialog == null) {
            if (theme > 0)
                mProgressDialog = new ProgressDialog(this, theme);
            else
                mProgressDialog = new ProgressDialog(this);
            mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
            mProgressDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
            mProgressDialog.setCanceledOnTouchOutside(false);// 不能取消
            mProgressDialog.setCancelable(false);
            mProgressDialog.setIndeterminate(true);// 设置进度条是否不明确
        }

        if (!TextUtils.isEmpty(title))
            mProgressDialog.setTitle(title);
        mProgressDialog.setMessage(message);
        mProgressDialog.show();
    }

    private void hideProgress() {
        if (mProgressDialog != null) {
            mProgressDialog.dismiss();
        }
    }

    @Override
    public void onCancel() {
        trimmerView.onDestroy();
        finish();
    }

    private ProgressDialog buildDialog(String msg) {
        if (mProgressDialog == null) {
            mProgressDialog = ProgressDialog.show(this, "", msg);
        }
        mProgressDialog.setMessage(msg);
        return mProgressDialog;
    }
}
public interface VideoTrimListener {
    void onStartTrim();
    void onFinishTrim(String url);
    void onCancel();
}

之后用七牛上传到七牛服务器,url上传服务器

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
视频的处理和播放主要是视频的清晰度、观看流畅度方面的体验。在这方面来讲,可以采用“窄带高清”技术,在节省码率的同时能够提供更加清晰的观看体验,经过测试,同等视频质量下最高可以节省20-40%带宽。除了带宽之外,短视频内容的存储和CDN优化也尤为重要,通常我们需要上传到云存储服务器的内容是短视频内容和封面内容。 而CDN优化带给短视频平台的则是进一步的短视频首次载入和循环播放方面的体验。比如针对首播慢的问题,像阿里云播放器支持QUIC协议,基于CDN的调度,可以使短视频首次播放秒开的成功率达到98%,此外在循环播放时还可以边播放边缓存,用户反复观看某一短视频时就不用耗费流量了。 在Android系统当中,如果需要一台Android设备来获取到一个MP4这样的视频文件的话,主流的方式一共与三种:MediaRecorder、MediaCodec+MediaMuxer、FFmpeg。 MediaRecorder:是Android系统直接提供给我们的录制类,用于录制音频和视频的一个类,简单方便,不需要理会中间录制过程,结束录制后可以直接得到音频文件进行播放,录制的音频文件是经过压缩的,需要设置编码器,录制的音频文件可以用系统自带的播放器播放。 优点:大部分以及集成,直接调用相关接口即可,代码量小,简单稳定; 缺点:无法实时处理音频;输出的音频格式不是很多。 MediaCodec+MediaMuxer: MediaCodec 与 MediaMuxer结合使用同样能够实现录制的功能。MediaCodec是Android提供的编解码类,MediaMuxer则是复用类(生成视频文件)。从易用性的角度上来说肯定不如MediaRecorder,但是允许我们进行更加灵活的操作,比如需要给录制的视频添加水印等各种效果。 优点: 与MediaRecorder一样低功耗速度快,并且更加灵活 缺点: 支持的格式有限,兼容性问题 FFmpeg: FFmpeg(Fast forword mpeg,音视频转换器)是一个开源免费跨平台的视频和音频流方案,它提供了录制/音视频编解码、转换以及流化音视频的完整解决方案。主要的作用在于对多媒体数据进行解协议、解封装、解码以及转码等操作 优点:格式支持非常的强,十分的灵活,功能强大,兼容性好; 缺点:C语言些的音视频编解码程序,使用起来不是很方便。
qt ffmpeg是一款基于Qt框架和FFmpeg库开发的音视频播放器。Qt是一种跨平台的应用程序开发框架,它提供了丰富的图形界面和多媒体功能的支持,使得开发者可以快速开发出功能强大、界面友好的应用程序。而FFmpeg是一种强大的开源多媒体框架,它可以处理音频和视频文件的编码、解码、转码等操作。 在qt ffmpeg音视频播放器中,通过集成Qt框架和FFmpeg库,我们可以实现以下功能:首先,播放各种格式的音频和视频文件,包括常见的MP3、MP4、AVI等格式,同时支持流媒体的播放。其次,提供播放控制功能,如暂停、播放、快进、快退等,使用户可以方便地操作音视频内容。此外,还可以实现音视频文件的截图功能,将当前画面保存为图片文件。 对于开发者而言,使用qt ffmpeg音视频播放器可以大大简化开发流程,因为Qt框架提供了丰富的图形界面组件和多媒体处理功能,开发者无需从零开始编写播放器的各种功能,只需进行简单的集成和配置即可。而FFmpeg库提供了强大的音视频处理能力,可以方便地实现各种编码、解码、转码等操作。 对于用户而言,qt ffmpeg音视频播放器提供了良好的用户体验。通过友好的界面和丰富的功能,用户可以方便地播放各种格式的音视频文件,同时还可以对音视频内容进行自定义设置和调整。因此,qt ffmpeg音视频播放器在乎等社区中也受到了一些开发者和用户的关注和讨论。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值