首页 > 解决方案 > 从 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();
}
?>

标签: javascriptphpgoogle-chromechromiumwebcam

解决方案


推荐阅读