Sow nothing reap nothing

前端获取摄像头视频、录制视频、下载视频

已有3,567次关注

效果截图:
前端录制下载视频.gif

HTML代码:

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="author" content="Angbike"/>
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>视频录制</title>
    <style type="text/css">
        .btn{
            position: relative;    
            background: #fff;
            border: 1px solid #fff;
            padding: 5px 20px;
            border-radius: 5px;
        }
        #theirs{
            position: absolute;
            top: 0; 
            bottom: 0;
            left: 0; 
            right: 0;
            display: block;
            width: 100%; 
            height: 100%;
            background: #000;
        }
    </style>
</head>
<body>
    <video id="theirs" autoplay></video>
    <button class="btn" id="startRecordVideo">视频录制</button>
    <button class="btn" id="endRecordVideo" disabled="disabled">结束录制</button>
    <button class="btn" id="videoDownload" disabled="disabled">视频下载</button>
</body>
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" src="js/videoRecording.js"></script>
</html>

JS代码(videoRecording.js):

/**
 * 视频录制及下载
 * @param {Object} window
 * @param {Object} $
 */
(function(window,$){
    
    var mediaSource,
        sourceBuffer,
        recordedBlobs,
        mediaRecorder,
        localStream;
        
    videoRecord = {
        
        init: function(){
            
            //兼容写法 获取URL
            window.URL = window.URL || window.webkitURL || window.mozURL || window.msURL;
            
            //媒体资源对象
            mediaSource = new MediaSource();
            
            //监听媒体资源开启
            mediaSource.addEventListener("sourceopen", videoRecord.handleSourceOpen, false);
            
            //音视频配置
            var constraints = {audio: true,video: true};
            
            //获取摄像头视频
            navigator.mediaDevices.getUserMedia(constraints).then(videoRecord.handleSuccess).catch(videoRecord.handleError);
            
        },
        
        //获取当前时间
        getTime: function(){
            return new Date().getTime();
        },
        
        //创建buffer
        handleSourceOpen: function(){
            console.log("MediaSource opened");
            sourceBuffer = mediaSource.addSourceBuffer("video/webm; codecs='vp8'");
            console.log("Source buffer: ", sourceBuffer);
        },
        
        //视频流添加到dom
        handleSuccess: function(stream){
            localStream = stream; // 本地视频流
            var yoursVideo = document.getElementById("theirs");
              if ("srcObject" in yoursVideo) {
                yoursVideo.srcObject = stream;
              } else {
                yoursVideo.src = window.URL.createObjectURL(stream);
              }
        },
        
        //获取视频时异常打印
        handleError: function(error){
               console.log("摄像头视频获取异常: ", error);
        },
        
        //视频录制
        startRecording: function(){
            recordedBlobs = [];
            var options = {mimeType: "video/webm;codecs=vp9"};
            if (!MediaRecorder.isTypeSupported(options.mimeType)){
                options = {mimeType: "video/webm;codecs=vp8"};
                if (!MediaRecorder.isTypeSupported(options.mimeType)){
                    options = {mimeType: "video/webm"};
                    if (!MediaRecorder.isTypeSupported(options.mimeType)){
                        options = {mimeType: ""};
                    }
                }
            }
            try {
                mediaRecorder = new MediaRecorder(localStream, options);
            } catch (e) {
                console.error("创建MediaRecorder时出现异常: " + e);
                return;
            }
            
            mediaRecorder.ondataavailable = videoRecord.handleDataAvailable;
            mediaRecorder.start(10);
            
            console.log("开始录制", mediaRecorder);
            
            $("#startRecordVideo").text("录制中...").attr("disabled","disabled");
            $("#endRecordVideo").removeAttr("disabled");
            
        },
        
        //停止视频录制
        stopRecording: function(){
            mediaRecorder.stop();
            $("#videoDownload").removeAttr("disabled");
            $("#startRecordVideo").text("开始录制");
            $("#endRecordVideo").attr("disabled","disabled");
            console.log("录制停止, recordedBlobs length: " + recordedBlobs.length);
        },
        
        //存储视频blob
        handleDataAvailable: function(e){
            if(e.data && e.data.size > 0){
                recordedBlobs.push(e.data);
            }
            console.log("视频录制: " + recordedBlobs.length);
        },
        
        //录制后的视频下载
        downloadMp4: function(){
            var time = videoRecord.getTime();
            var blob = new Blob(recordedBlobs, {type: "video/mp4"});
            var url = window.URL.createObjectURL(blob);
            var hyperlink = document.createElement("a");
            hyperlink.style.display = "none";
            hyperlink.href = url;
            hyperlink.download = time + ".mp4";
            document.body.appendChild(hyperlink);
            hyperlink.click();
            setTimeout(function() {
                document.body.removeChild(hyperlink);
                window.URL.revokeObjectURL(url);
            }, 100);
            
            $("#startRecordVideo").removeAttr("disabled");
            $("#videoDownload").attr("disabled","disabled");
            console.log("下载录制视频");
            recordedBlobs = [];
        },
        
    }
    
    $(function(){
        
        videoRecord.init();
        $("#startRecordVideo").on("click",videoRecord.startRecording); // 开始视频录制
        $("#endRecordVideo").on("click",videoRecord.stopRecording);    // 结束录制视频
        $("#videoDownload").on("click",videoRecord.downloadMp4); // 下载录制视频
        
    })
    
})(window,$)

已自动关闭评论