【发布时间】:2020-06-27 19:40:20
【问题描述】:
我需要帮助。我的网站中有一个 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);
});
非常感谢! 热纳罗
【问题讨论】:
-
您可能弄错了。您提供的代码的格式取决于服务器提供的格式。可能是不同的浏览器,服务器会检测要服务的格式......好吧,忘了我说过了。可能是您引用的 mkv 网站(没有链接)阻止了您的黑客/请求?
-
你好GetSet!谢谢你回答我。对不起,我没听懂你说的。我通过 javaScript 代码传递给服务器 webm 格式,但是当我使用 Chrome 或 Opera 时,视频保存在 mkv 中。该网站在我的电脑上的本地尚未上线
-
我在 mac 上的最新 chrome 版本(但在 windows 上没有)有完全相同的问题。几个月前它工作正常。我认为这是一个铬错误,肯定与这个有关:bugs.chromium.org/p/chromium/issues/detail?id=980822
标签: javascript php webm mkv web-mediarecorder