H5+springboot(集成ffmpeg)实现前端视频录制以及webm格式转mp4

H5+springboot(集成ffmpeg)实现前端视频录制以及webm格式转mp4

1、前端实现(仅供参考)

献上代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <title>视频流采集</title>
    <script src="../js/jquery/jquery-3.5.1.min.js"></script>
    <script src ="../js/file/FileSaver.js"></script>
<!--    video适配浏览器-->
    <script src = "https://webrtc.github.io/adapter/adapter-latest.js"></script>
    <script src="../js/mediaStreamRecorder/MediaStreamRecorder.js"></script>

<!--    css-->
    <style type="text/css">
        body {
            width: 100%;
            height: 100%;
        }
        .container {
            position: absolute;
            display: flex;
            flex-direction: row;
            left: 0px;
            width: 100%;
            height: 100%;
        }
        .container .left {
            width: 50%;
            height: 100%;
            background: #b5e3ad;
        }
        .left video {
            width: 100%;
            height: 100%;
            left: 0px;
            bottom: 0px;
        }
        .container .right {
            width: 50%;
            height: 100%;
        }
        .right .btn_block {
            display: flex;
            flex-direction: row;
            justify-content: center;
            align-items: center;
            background: #898c8c;
            margin-top: 0px;
            width: 100%;
            height: 50px;
        }
        .btn_block button {
            width: 90px;
            height: 40px;
            margin-right: 20px;
            margin-left: 20px;
            font-size: 12px;
            font-weight: bold;
        }
        .right .remark {
            width: 100%;
            height: 100%;
            background: #d99540;
            margin-bottom: 0px;
        }
    </style>
<!--    js-->
    <script type="application/javascript">
        $(function (){
            console.log('音视频采集');
            let videoPlayer = document.getElementById('player');
            //开始录制
            let mediaRecorder;
            $('#beginAction').click(function (){
                console.log('开始录制');
                if(!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia){
                    console.log('getUserMedia is not supported');
                }else{
                    const constraints = {
                        video: true,
                        audio: true
                    };
                    navigator.getUserMedia(constraints, onMediaSuccess, onMediaError);
                }
            });
            function onMediaSuccess(stream){
                videoPlayer.srcObject=stream;
                videoPlayer.play();
                //
                mediaRecorder = new MediaStreamRecorder(stream);
                mediaRecorder.mimeType = 'video/webm';
                let _blob;
                mediaRecorder.ondataavailable = function (blob) {
                    console.log('获取视频流数据... ...'+blob);
                    _blob=blob;
                };
                mediaRecorder.onstop=function (err){
                    console.log("已下载至本地")
                    let fileName='video-'+Math.floor(Math.random()*100000)+'.webm';
                    let file = new File([_blob], fileName, {
                        type: 'video/webm'
                    });
                    saveAs(file);
                };
                mediaRecorder.start(100);

            }
            function onMediaError(e){
                console.error('media error', e);
            }
            //停止
            $('#stopAction').click(function (){
                mediaRecorder.stop();
                if(!videoPlayer.srcObject){
                    return;
                }
                let player = videoPlayer.srcObject;
                let tracks = player.getTracks();
                tracks.forEach(track => {
                    track.stop()
                });

            });

            //查看当前浏览器支持媒体类型
            const types = ["video/webm",
                "audio/webm",
                "video/webm\;codecs=vp8",
                "video/webm\;codecs=daala",
                "video/webm\;codecs=h264",
                "audio/webm\;codecs=opus",
                "video/mpeg"];

            for (let i in types) {
                console.log( "Is " + types[i] + " supported? " + (MediaRecorder.isTypeSupported(types[i]) ? "Maybe!" : "Nope :("));
            }

        });
    </script>
</head>
<body>
    <div class="container">
        <div class="left">
            <video autoplay playsinline id = "player" width="400" height="350"></video>
        </div>
        <div class="right">
            <div class="btn_block">
                <button id="beginAction">开始录制</button>
                <button id="stopAction">停止录制</button>
            </div>
            <div class="remark">

            </div>
        </div>
    </div>
</body>
</html>

引入文件解释:

FileSaver.js 文件保存本地js,这个js是在网上查找的,如果客观找不到或者嫌弃,可以直接使用a 标签,下载本地。
adapter-latest.js video标签适配浏览器。
MediaStreamRecorder.js 这个js文件是二次封装,参考GitHub  https://github.com/streamproc/MediaStreamRecorder 直接找到源文件 放在自己工程中。
jquery-3.5.1.min.js 这个就不多说了。

备注:前端目前支持webm格式视频,如果要使用mp4格式需要自己转换,在前端去转换格式会消耗很大的cpu,所以视频格式转换放在后台。客官可以在保存本地视频文件地方自己发送ajax或者其他请求方式上传至后台服务,这里就不多说了。

2、后台springboot 简略代码(仅供参考)

献上代码:

public static void main(String[] args) {
        System.out.println("测试======");
        String filePath="/Users/dongxr/Desktop/video-5322.webm";
        File file=new File(filePath);
        FFmpegFrameGrabber frameGrabber = new FFmpegFrameGrabber(file);
        String fileName = null;
        Frame captured_frame = null;
        FFmpegFrameRecorder recorder = null;
        try {
            frameGrabber.start();
            fileName = file.getAbsolutePath() + "__.mp4";
            recorder = new FFmpegFrameRecorder(fileName, frameGrabber.getImageWidth(), frameGrabber.getImageHeight(), frameGrabber.getAudioChannels());
            recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
            recorder.setFormat("mp4");
            recorder.setSampleRate(frameGrabber.getSampleRate());
            recorder.setFrameRate(frameGrabber.getFrameRate());
            recorder.setVideoBitrate(10 * 1024 * 1024);
            recorder.start();
            boolean bool=false;
            while ((captured_frame = frameGrabber.grabFrame()) != null) {
                try {
                    System.out.println("时长2==="+captured_frame.timestamp);
                    recorder.setTimestamp(frameGrabber.getTimestamp());
                    recorder.record(captured_frame);
                } catch (Exception e) {
                    System.out.println(e);
                }
            }
            recorder.stop();
            recorder.release();
            frameGrabber.stop();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

maven依赖引入:

<dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacv-platform</artifactId>
            <version>1.5</version>
        </dependency>

因为我是mac,引入最新的javac 一直提示opencv依赖下载失败,所以这里我就选择了低版本的依赖。

备注:这里只是把前端生成本地的webm格式的视频文件转换为mp4格式的。

嘻哈---我认为写博客还是直接点比较好,毕竟大家都喜欢ctrl+c. ctrl+v,哈哈哈哈哈哈哈。

 

 

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值