javascript - 从 Chrome 浏览器发送到服务器的网络摄像头视频 blob 损坏,而从 Mozilla Firefox 发送时工作正常
问题描述
我正在尝试使用 ajax 将录制的视频从客户端浏览器发送到我的服务器。为此,我在 ajax 数据中附加了视频 blob。从 Firefox 浏览器发送的视频 blob 可以正常工作,但不能从 Chrome/Chromium 浏览器发送,即可以播放从 Mozilla Firefox 发送的视频,但不能播放来自 Chromium 浏览器的视频。
客户端页面 -> upload.php
:这里用户单击start recording
按钮开始视频录制。stop recording
按钮停止录制视频。upload
上传视频服务器。(暂时上传视频之前需要按下停止录制按钮)
后端服务 -> vidToServer.php
:此端点从请求中收集视频并将其保存到预先创建的vids
文件夹中。(请记住vids
手动创建与此文件相同级别的文件夹:))。
代码:
上传.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>MediaCapture and Streams API</title>
<meta name="viewport" content="width=device-width" />
</head>
<body>
<header><h1>MediaCapture, MediaRecorder and Streams API</h1></header>
<main>
<button id="btnStart">START RECORDING</button><br />
<button id="btnStop">STOP RECORDING</button><br />
<button id="upload">Upload</button><br />
<span id="uploadStatus"></span><br />
<video controls></video>
<video id="vid2" controls></video>
</main>
<script>
let constraintObj = {
audio: false,
video: {
facingMode: "user",
width: { min: 640, ideal: 1280, max: 1920 },
height: { min: 480, ideal: 720, max: 1080 }
}
};
let blob; // VARIABLE TO STORE BLOB TO SEND TO SERVER
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);
});
})
.catch(err => {
console.log(err.name, err.message);
});
}
navigator.mediaDevices
.getUserMedia(constraintObj)
.then(function(mediaStreamObj) {
let video = document.querySelector("video");
if ("srcObject" in video) {
video.srcObject = mediaStreamObj;
} else {
video.src = window.URL.createObjectURL(mediaStreamObj);
}
video.onloadedmetadata = function(ev) {
video.play();
};
//add listeners for saving video/audio
let start = document.getElementById("btnStart");
let stop = document.getElementById("btnStop");
let vidSave = document.getElementById("vid2");
let mediaRecorder = new MediaRecorder(mediaStreamObj);
let chunks = [];
start.addEventListener("click", ev => {
mediaRecorder.start();
console.log(mediaRecorder.state);
});
stop.addEventListener("click", ev => {
mediaRecorder.stop();
console.log(mediaRecorder.state);
});
mediaRecorder.ondataavailable = function(ev) {
chunks.push(ev.data);
};
mediaRecorder.onstop = ev => {
blob = new Blob(chunks, { type: "video/mp4;" }); // On video stop blob storedd in the variable
console.log("blob when generated ", blob);
chunks = [];
let videoURL = window.URL.createObjectURL(blob);
vidSave.src = videoURL;
};
})
.catch(function(err) {
console.log(err.name, err.message);
});
/***UPLOAD************/
let upload = document.getElementById("upload");
upload.addEventListener("click", async ev => {
var data = new FormData();
data.append("file", blob); //appedning blob to ajax data
console.log("Upload started");
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else {
// code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("uploadStatus").style.display = "block";
document.getElementById(
"uploadStatus"
).innerHTML = this.responseText;
}
};
xmlhttp.open("POST", "vidToServer.php", true);
xmlhttp.send(data);
});
</script>
</body>
</html>
vidToServer.php
<?php
print_r($_FILES['file']);
$t = time();
$target_dir = "vids/";
$target_file = $target_dir . $t . '.mp4';
echo $target_file;
try
{
move_uploaded_file($_FILES["file"]["tmp_name"], $target_file);
echo "Uploaded succesfully!!";
}
catch(Exception $e)
{
echo 'Error Message: ' . $e->getMessage();
}
?>
解决方案
推荐阅读
- php - 读取 docx(从 googledocs 下载)时,PhpWord 会清除所有列表项。问题
- javascript - 无需表单操作即可从 php 发布到 Javascript
- reactjs - 如何在地图功能中从 Firestore 获取数据
- ffmpeg - 从 rtmp 到 DASH 的直播网络研讨会
- c# - 如何在 MVC asp.net core 中上传文件 + 在 sql server 上更新?
- jpa - 如何从多对多关系中的连接表中过滤
- javascript - DHtmlX 调度程序事件未在 Safari 和 Internet Explorer 中显示
- python - 为自动驾驶汽车寻找车道,代码问题
- python - IndexError : 用作索引的数组必须是整数(或布尔)类型
- r - ggplot2中的自定义日期轴