从网络摄像头录制视频流并将 blob 上传到服务器
Record video stream from webcam and upload blob to server
所以我有一个网站可以从用户网络摄像头录制视频流并使用 getUserMedia()
将其转换为 blob。我现在想将此 blob 发送到服务器,以便可以保存和处理视频。我在通过 ajax 发送 blob 文件时遇到问题,我尝试使用 formData + XMLHttpRequest() 方法以及纯 ajax。对于我的应用程序来说,用户可以录制视频并立即将此视频发送到我的服务器是必要的。
如有任何帮助,我们将不胜感激。
所以HTML:
<div class="demo">
<video id="preview" autoplay width="400" height="300"></video>
<video id="recording" width="400" height="300" style="display:none;" controls></video>
<div class="progress">
<div class="progress-bar"></div>
<span>01:00</span>
</div>
<button class="record">Record</button>
<button class="upload">Upload</button>
</div>
相关JS函数:
function captureVideo () {
const preview = document.querySelector('video#preview');
const recording = document.querySelector('video#recording');
navigator.mediaDevices.getUserMedia({video: true}).then((stream) => {
preview.srcObject = stream;
preview.captureStream = preview.captureStream || preview.mozCaptureStream;
return new Promise(resolve => preview.onplaying = resolve);
}).then(() => {
let recorder = new MediaRecorder(preview.captureStream());
let data = [];
recorder.ondataavailable = event => data.push(event.data);
recorder.start();
log(recorder.state + " for " + (60000/1000) + " seconds...");
let stopped = new Promise((resolve, reject) => {
recorder.onstop = resolve;
recorder.onerror = event => reject(event.name);
});
$('button.stop').click(function () {
recorder.stop();
});
return Promise.all([ stopped ]).then(() => data);
}).then ((recordedChunks) => {
let recordedBlob = new Blob(recordedChunks, {
type: "video/webm"
});
recording.src = URL.createObjectURL(recordedBlob);
$('#preview').hide();
$('#recording').show();
log("Successfully recorded " + recordedBlob.size + " bytes of " +
recordedBlob.type + " media.");
$('button.upload').click(function() {
sendVideoToAPI(recordedBlob);
});
}).catch(log);
}
function sendVideoToAPI (blob) {
let fd = new FormData();
let file = new File([blob], 'recording');
fd.append('data', file);
console.log(fd); // test to see if appending form data would work, it didn't this is completely empty.
let form = new FormData();
let request = new XMLHttpRequest();
form.append("file",file);
request.open("POST", "/demo/upload", true);
request.send(form); // hits the route but doesn't send the file
console.log(request.response) // returns nothing
// I have also tried this method which hits the route and gets a response however the file is not present in the request when it hits the server.
// $.ajax({
// url: Routing.generate('upload'),
// data: file,
// contentType: false,
// processData: false,
// error: function (res) {
// console.log(res);
// },
// success: function(res) {
// console.log(res);
// }
// });
}
您正在发送一个 ajax 请求,您不会在 send() 命令后立即收到响应。您可以使用请求 onload 事件访问响应值
request.onload = function () {
if (request.readyState === request.DONE) {
if (request.status === 200) {
console.log(request.response);
}
}
};
所以我有一个网站可以从用户网络摄像头录制视频流并使用 getUserMedia()
将其转换为 blob。我现在想将此 blob 发送到服务器,以便可以保存和处理视频。我在通过 ajax 发送 blob 文件时遇到问题,我尝试使用 formData + XMLHttpRequest() 方法以及纯 ajax。对于我的应用程序来说,用户可以录制视频并立即将此视频发送到我的服务器是必要的。
如有任何帮助,我们将不胜感激。
所以HTML:
<div class="demo">
<video id="preview" autoplay width="400" height="300"></video>
<video id="recording" width="400" height="300" style="display:none;" controls></video>
<div class="progress">
<div class="progress-bar"></div>
<span>01:00</span>
</div>
<button class="record">Record</button>
<button class="upload">Upload</button>
</div>
相关JS函数:
function captureVideo () {
const preview = document.querySelector('video#preview');
const recording = document.querySelector('video#recording');
navigator.mediaDevices.getUserMedia({video: true}).then((stream) => {
preview.srcObject = stream;
preview.captureStream = preview.captureStream || preview.mozCaptureStream;
return new Promise(resolve => preview.onplaying = resolve);
}).then(() => {
let recorder = new MediaRecorder(preview.captureStream());
let data = [];
recorder.ondataavailable = event => data.push(event.data);
recorder.start();
log(recorder.state + " for " + (60000/1000) + " seconds...");
let stopped = new Promise((resolve, reject) => {
recorder.onstop = resolve;
recorder.onerror = event => reject(event.name);
});
$('button.stop').click(function () {
recorder.stop();
});
return Promise.all([ stopped ]).then(() => data);
}).then ((recordedChunks) => {
let recordedBlob = new Blob(recordedChunks, {
type: "video/webm"
});
recording.src = URL.createObjectURL(recordedBlob);
$('#preview').hide();
$('#recording').show();
log("Successfully recorded " + recordedBlob.size + " bytes of " +
recordedBlob.type + " media.");
$('button.upload').click(function() {
sendVideoToAPI(recordedBlob);
});
}).catch(log);
}
function sendVideoToAPI (blob) {
let fd = new FormData();
let file = new File([blob], 'recording');
fd.append('data', file);
console.log(fd); // test to see if appending form data would work, it didn't this is completely empty.
let form = new FormData();
let request = new XMLHttpRequest();
form.append("file",file);
request.open("POST", "/demo/upload", true);
request.send(form); // hits the route but doesn't send the file
console.log(request.response) // returns nothing
// I have also tried this method which hits the route and gets a response however the file is not present in the request when it hits the server.
// $.ajax({
// url: Routing.generate('upload'),
// data: file,
// contentType: false,
// processData: false,
// error: function (res) {
// console.log(res);
// },
// success: function(res) {
// console.log(res);
// }
// });
}
您正在发送一个 ajax 请求,您不会在 send() 命令后立即收到响应。您可以使用请求 onload 事件访问响应值
request.onload = function () {
if (request.readyState === request.DONE) {
if (request.status === 200) {
console.log(request.response);
}
}
};