如何将视频保存为WebM格式而不是MKV格式

3
我需要帮助。我的网站上有一段JavaScript代码,可以录制视频并将其保存在服务器上。视频的保存格式取决于我使用的浏览器,如果我使用Opera或Chrome浏览器,则视频会以MKV格式保存,而如果我使用Firefox浏览器,则视频会以WEBM格式保存。问题是,我使用Opera和Chrome浏览器保存的视频(即MKV格式)无法在Firefox浏览器中播放,而Opera和Chrome浏览器可以轻松读取由Firefox生成的WEBM视频。 如何使Opera和Chrome也能将视频保存为WEBM格式,以避免这个问题? JavaScript代码:
let constraintObj = { 
    audio: true, 
    video: { 
        facingMode: "user", 
        width: { min: 640, ideal: 1280, max: 1920 },
        height: { min: 480, ideal: 720, max: 1080 } 
    } 
}; 
// width: 1280, height: 720  -- preference only
// facingMode: {exact: "user"}
// facingMode: "environment"

//handle older browsers that might implement getUserMedia in some way
if (navigator.mediaDevices === undefined) {
    navigator.mediaDevices = {};
    navigator.mediaDevices.getUserMedia = function(constraintObj) {
        let getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
        if (!getUserMedia) {
            return Promise.reject(new Error('getUserMedia is not implemented in this browser'));
        }
        return new Promise(function(resolve, reject) {
            getUserMedia.call(navigator, constraintObj, resolve, reject);
        });
    }
}else{
    navigator.mediaDevices.enumerateDevices()
    .then(devices => {
        devices.forEach(device=>{
            console.log(device.kind.toUpperCase(), device.label);
            //, device.deviceId
        })
    })
    .catch(err=>{
        console.log(err.name, err.message);
    })
}

navigator.mediaDevices.getUserMedia(constraintObj)
.then(function(mediaStreamObj) {
    //connect the media stream to the first video element
    let video = document.querySelector('video');
    if ("srcObject" in video) {
        video.srcObject = mediaStreamObj;
    } else {
        //old version
        video.src = window.URL.createObjectURL(mediaStreamObj);
    }
    
    video.onloadedmetadata = function(ev) {
        //show in the video element what is being captured by the webcam
        video.play();
    };
    
    //add listeners for saving video/audio
    let start = document.getElementById('btnStart');
    let stop = document.getElementById('btnStop');
    let save = document.getElementById('btnSave');
    let vidSave = document.getElementById('vid2');
    let mediaRecorder = new MediaRecorder(mediaStreamObj);
    let chunks = [];
    var blob = null;
    document.getElementById("vid2").style.visibility = "hidden";
    document.getElementById("btnSave").style.visibility = "hidden";
    
    var contatore=0;
    var dontstop=0;
    

    save.addEventListener('click', (ev)=>{
        
     contatore = 0;
    const formData = new FormData();
     formData.append('video', blob);
     fetch('videoRec', {
        method: 'POST',
        body: formData
        })
        .then(response => { console.log('upload success, ');
        document.getElementById('response').innerHTML="Video salvato con successo, ";
        })
    .catch(error => {console.log('error');
        document.getElementById('response').innerHTML="Errore durante il caricamento del video. Riprova.";
    })
    
    });

    
    start.addEventListener('click', (ev)=>{
        
        dontstop=1;
        //if user already started video before, ask him if want to save that video before 
        //recording another video
        if(contatore!=0){
            var domanda=confirm("Il video appena registrato andrà eliminato. Vuoi Procedere?");
            if (domanda === false) {
            exit;
            }    
        }

        //when user's recording, vid2 must be hidden
        if(document.getElementById("vid2").style.visibility=="visible"){
            document.getElementById("vid2").style.visibility="hidden";
            document.getElementById("btnSave").style.visibility="hidden";
            document.getElementById('response').innerHTML=" ";
        }

        //start recording
        mediaRecorder.start();
        console.log(mediaRecorder.state);

        //disable start button and enable stop button
        document.getElementById('btnStart').disabled=true;
        document.getElementById('btnStop').disabled=false;

        //contatore increments when user records, so if he starts another rec without stopping before
        //ask him if want to save the last video
        contatore++;
        var timeleft = 5; //video must be 120 seconds

        downloadTimer = setInterval(function(){
        if(timeleft <= 0){ 

            //after 120 seconds record will stops automatically
            clearInterval(downloadTimer); //the countdown disappared
            document.getElementById("countdown").innerHTML = "Finished";
            mediaRecorder.stop();
            console.log(mediaRecorder.state);

            document.getElementById('btnStart').disabled=false;
            document.getElementById('btnStop').disabled=true;


            video.onloadedmetadata = function(ev) {
        
            chunks.push(ev.data);
            };

            
            // vid2 appears
            document.getElementById("vid2").style.visibility = "visible";
            document.getElementById("btnSave").style.visibility = "visible";
             blob = new Blob(chunks, { 'type' : 'video/webm;' });
            chunks = [];
            let videoURL = window.URL.createObjectURL(blob);
            vidSave.src = videoURL;
            

            } else {
                //else countdown continues
        document.getElementById("countdown").innerHTML = timeleft + " seconds remaining";
            }
        timeleft -= 1;
        }, 1000)
                     
    })

    stop.addEventListener('click', (ev)=>{
        if(dontstop!=1){
            exit;
        }
        mediaRecorder.stop();
        console.log(mediaRecorder.state);
        document.getElementById('btnStart').disabled=false;
        document.getElementById('btnStop').disabled=true;
        clearInterval(downloadTimer);
        document.getElementById("countdown").innerHTML = "Finished";
        document.getElementById("vid2").style.visibility = "visible";
        document.getElementById("btnSave").style.visibility = "visible";
    });
    mediaRecorder.ondataavailable = function(ev) {
        chunks.push(ev.data);
    }
    mediaRecorder.onstop = (ev)=>{
        blob = new Blob(chunks, { 'type' : 'video/webm;' });
        chunks = [];
        let videoURL = window.URL.createObjectURL(blob);
        vidSave.src = videoURL;
        
    } 
})
.catch(function(err) { 
    console.log(err.name, err.message); 
});

非常感谢!Gennaro

很可能你弄错了。从你提供的代码来看,格式取决于服务器提供的格式。也许不同的浏览器,服务器会检测要提供哪种格式...好吧,忘了我说的那些。难道你引用的mkv网站(没有链接)阻止了你的黑客攻击/请求? - GetSet
你好GetSet!感谢回答我的问题。很抱歉我没有理解你所说的话。我通过JavaScript代码将webm格式传递给服务器,但是当我使用Chrome或Opera时,视频保存为mkv格式。该网站在我的个人电脑上本地运行,尚未上线。 - Gennaro Abategiovanni
我在Mac上使用最新版本的Chrome遇到了完全相同的问题(但在Windows上没有)。几个月前它还能正常工作。 我认为这是一个Chromium的bug,肯定与这个有关:https://bugs.chromium.org/p/chromium/issues/detail?id=980822 - Pierre Fiorelli
1个回答

1
你可以尝试将MIME类型更改为video/webm;codecs=VP8,这样它就可以在支持MediaRecorder的任何浏览器上运行。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接