Как загрузить файл Blob на локальный хостинг?

При записи с веб-камеры как загрузить файл Blob на локальный хостинг? Файлы грузятся, но видео не воспроизводится.

var mediaRecorder; //переменная
var recordedBlobs; //переменная

var gumVideo = document.querySelector("video#gum"); //переменная
var recordedVideo = document.querySelector("video#recorded"); //переменная

var recordButton = document.querySelector("button#record"); //переменная
var playButton = document.querySelector("button#play"); //переменная
var downloadButton = document.querySelector("button#download"); //переменная
var pushButton = document.querySelector("button#push"); //переменная

recordButton.onclick = toggleRecording;
playButton.onclick = play;
downloadButton.onclick = download;
pushButton.onclick = push;

navigator.mediaDevices
  .getUserMedia({ video: true, audio: false }) //получить пользовательские медиа
  .then((stream) => {
    recordButton.disabled = false;
    console.log("getUserMedia() got stream: ", stream);
    window.stream = stream;
    gumVideo.srcObject = stream;
  })
  .catch((error) => {
    console.log("navigator.getUserMedia error: ", error);
  });

function handleDataAvailable(event) {
  if (event.data && event.data.size > 0) {
    recordedBlobs.push(event.data);
  }
}

function handleStop(event) {
  console.log("Recorder stopped: ", event);
}

function toggleRecording() {
  if (recordButton.textContent === "Start Recording") {
    startRecording();
  } else {
    stopRecording();
    recordButton.textContent = "Start Recording";
    playButton.disabled = false;
    pushButton.disabled = false;
    downloadButton.disabled = false;
  }
}

function startRecording() {
  recordedBlobs = [];

  try {
    mediaRecorder = new MediaRecorder(window.stream);
  } catch (e) {
    console.error("Exception while creating MediaRecorder: " + e);
    return;
  }
  console.log("Created MediaRecorder", mediaRecorder);
  recordButton.textContent = "Stop Recording";
  playButton.disabled = true;
  downloadButton.disabled = true;
  pushButton.disabled = true;
  mediaRecorder.onstop = handleStop;
  mediaRecorder.ondataavailable = handleDataAvailable;
  mediaRecorder.start(10);
  console.log("MediaRecorder started", mediaRecorder);
}

function stopRecording() {
  mediaRecorder.stop();
  console.log("Recorded Blobs: ", recordedBlobs);
  recordedVideo.controls = true;
}

function play() {
  var superBuffer = new Blob(recordedBlobs, {
    type: "video/webm",
  });
  recordedVideo.src = window.URL.createObjectURL(superBuffer);
  console.log(superBuffer);
}

function download() {
  var blob = new Blob(recordedBlobs, {
    type: "video/webm",
  });
  var url = window.URL.createObjectURL(blob);
  var a = document.createElement("a");
  a.style.display = "none";
  a.href = url;
  a.download = "test.webm";
  document.body.appendChild(a);
  a.click();
  setTimeout(function () {
    document.body.removeChild(a);
    window.URL.revokeObjectURL(url);
  }, 100);
}

function push() {
  var fileName = getFileName("webm");
  console.log(fileName);
  var fileObject = new File([recordedBlobs], fileName, {
    type: "video/webm",
  });
  console.log(fileObject);
  //Собираются данные формы
  var formData = new FormData();
  console.log(formData);
  formData.append("video-blob", fileObject);
  formData.append("video-filename", fileObject.name);
  console.log(formData.append)
  document.getElementById("header").innerHTML =
    "Uploading to PHP using jQuery.... file size: (" +
    bytesToSize(fileObject.size) +
    ")";
  var upload_url = "RecordRTC-to-PHP/save.php";
  var upload_directory = "RecordRTC-to-PHP/uploads/";
  $.ajax({
    url: upload_url, // заменить на свой собственный URL сервера
    data: formData,
    cache: false,
    contentType: false,
    processData: false,
    type: "POST",
    success: function (response) {
      if (response === "success") {
        alert("successfully uploaded recorded blob");

        // путь к файлу на сервере
        var fileDownloadURL = upload_directory + fileObject.name;

        // Предварительный просмотр URL загруженного файла
        document.getElementById("header").innerHTML =
          '<a href="' +
          fileDownloadURL +
          '" target="_blank">' +
          fileDownloadURL +
          "</a>";

        // предварительный просмотр загруженного файла в элементе VIDEO
        document.getElementById("you-stream-id").srcObject = null;
        document.getElementById("you-stream-id").src = fileDownloadURL;

        // открыть загруженный файл в новой вкладке
        // window.open(fileDownloadURL);
      }
      // else {
      //   alert(response); // ошибка / отказ
      // }
    },
  });
}


//Создается FileName уникальное имя


function getFileName(fileExtension) {
  var d = new Date();
  var year = d.getUTCFullYear();
  var month = d.getUTCMonth();
  var date = d.getUTCDate();
  return (
    "Comment" +
    "-" +
    date +
    "." +
    month +
    "." +
    year +
    "-" +
    getRandomString() +
    "." +
    fileExtension
  );
}
function getRandomString() {
  if (
    window.crypto &&
    window.crypto.getRandomValues &&
    navigator.userAgent.indexOf("Safari") === -1
  ) {
    var a = window.crypto.getRandomValues(new Uint32Array(3)),
      token = "";
    for (var i = 0, l = a.length; i < l; i++) {
      token += a[i].toString(36);
    }
    return token;
  } else {
    return (Math.random() * new Date().getTime())
      .toString(36)
      .replace(/\./g, "");
  }
}

//скрипт переводит удобочитаемый формат байты в размеры
function bytesToSize(bytes) {
  var k = 1000;
  var sizes = ["Bytes", "KB", "MB", "GB", "TB"];
  if (bytes === 0) {
    return "0 Bytes";
  }
  var i = parseInt(Math.floor(Math.log(bytes) / Math.log(k)), 10);
  return (bytes / Math.pow(k, i)).toPrecision(3) + " " + sizes[i];
}
button {
    margin: 0 3px 10px 0;
    padding-left: 2px;
    padding-right: 2px;
    width: 99px;
}

button:last-of-type {
    margin: 0;
}

p.borderBelow {
    margin: 0 0 20px 0;
    padding: 0 0 20px 0;
}

video {
    height: 232px;
    margin: 0 12px 20px 0;
    vertical-align: top;
    width: calc(20em - 10px);
}


video:last-of-type {
    margin: 0 0 20px 0;
}

video#gumVideo {
    margin: 0 20px 20px 0;
}

@media screen and (max-width: 500px) {
    button {
        font-size: 0.8em;
        width: calc(33% - 5px);
    }
}

@media screen and (max-width: 720px) {
    video {
        height: calc((50vw - 48px) * 3 / 4);
        margin: 0 10px 10px 0;
        width: calc(50vw - 48px);
    }

    video#gumVideo {
        margin: 0 10px 10px 0;
    }
}
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <link rel="stylesheet" href="style.css">
    <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
</head>

<body>
    <div id="container">
    <h1 id="header">RecordRTC Upload to PHP</h1>
        <video id="gum" autoplay muted></video>
        <video id="recorded" loop controls></video>
        <video id="you-stream-id" loop controls></video>
        <div>
            <button id="record" disabled>Start Recording</button>
            <button id="play" disabled>Play</button>
            <button id="download" disabled>Download</button>
            <button id="push" disabled>PUSH</button>
        </div>

    </div>
    <script src="script.js"></script>
    <?php
header("Access-Control-Allow-Origin: *");
error_reporting(E_ALL);
ini_set('display_errors', 1);

set_error_handler("someFunction");

function someFunction($errno, $errstr) {
    echo '<h2>Upload failed.</h2><br>';
    echo '<p>'.$errstr.'</p>';
}

function selfInvoker()
{
    if (!isset($_POST['audio-filename']) && !isset($_POST['video-filename'])) {
        echo 'Empty file name.';
        return;
    }

    // НЕ разрешать пустые имена файлов
    if (empty($_POST['audio-filename']) && empty($_POST['video-filename'])) {
        echo 'Empty file name.';
        return;
    }

    // НЕ разрешать сторонние аудио загрузки
    if (false && isset($_POST['audio-filename']) && strrpos($_POST['audio-filename'], "RecordRTC-") !== 0) {
        echo 'File name must start with "RecordRTC-"';
        return;
    }

    // НЕ разрешать сторонние загрузки видео
    if (false && isset($_POST['video-filename']) && strrpos($_POST['video-filename'], "RecordRTC-") !== 0) {
        echo 'File name must start with "RecordRTC-"';
        return;
    }
    
    $fileName = '';
    $tempName = '';
    $file_idx = '';
    
    if (!empty($_FILES['audio-blob'])) {
        $file_idx = 'audio-blob';
        $fileName = $_POST['audio-filename'];
        $tempName = $_FILES[$file_idx]['tmp_name'];
    } else {
        $file_idx = 'video-blob';
        $fileName = $_POST['video-filename'];
        $tempName = $_FILES[$file_idx]['tmp_name'];
    }
    
    if (empty($fileName) || empty($tempName)) {
        if(empty($tempName)) {
            echo 'Invalid temp_name: '.$tempName;
            return;
        }

        echo 'Invalid file name: '.$fileName;
        return;
    }

    /*
    $upload_max_filesize = return_bytes(ini_get('upload_max_filesize'));
    if ($_FILES[$file_idx]['size'] > $upload_max_filesize) {
       echo 'upload_max_filesize exceeded.';
       return;
    }
    $post_max_size = return_bytes(ini_get('post_max_size'));
    if ($_FILES[$file_idx]['size'] > $post_max_size) {
       echo 'post_max_size exceeded.';
       return;
    }
    */

    $filePath = 'uploads/' . $fileName;
    
    // убедитесь, что можно загружать только разрешенные аудио / видео файлы
    $allowed = array(
        'webm',
        'wav',
        'mp4',
        'mkv',
        'mp3',
        'ogg'
    );
    $extension = pathinfo($filePath, PATHINFO_EXTENSION);
    if (!$extension || empty($extension) || !in_array($extension, $allowed)) {
        echo 'Invalid file extension: '.$extension;
        return;
    }
    
    if (!move_uploaded_file($tempName, $filePath)) {
        if(!empty($_FILES["file"]["error"])) {
            $listOfErrors = array(
                '1' => 'The uploaded file exceeds the upload_max_filesize directive in php.ini.',
                '2' => 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.',
                '3' => 'The uploaded file was only partially uploaded.',
                '4' => 'No file was uploaded.',
                '6' => 'Missing a temporary folder. Introduced in PHP 5.0.3.',
                '7' => 'Failed to write file to disk. Introduced in PHP 5.1.0.',
                '8' => 'A PHP extension stopped the file upload. PHP does not provide a way to ascertain which extension caused the file upload to stop; examining the list of loaded extensions with phpinfo() may help.'
            );
            $error = $_FILES["file"]["error"];

            if(!empty($listOfErrors[$error])) {
                echo $listOfErrors[$error];
            }
            else {
                echo 'Not uploaded because of error #'.$_FILES["file"]["error"];
            }
        }
        else {
            echo 'Problem saving file: '.$tempName;
        }
        return;
    }
    
    echo 'success';
}

/*
function return_bytes($val) {
    $val = trim($val);
    $last = strtolower($val[strlen($val)-1]);
    switch($last) {
        // The 'G' modifier is available since PHP 5.1.0
        case 'g':
            $val *= 1024;
        case 'm':
            $val *= 1024;
        case 'k':
            $val *= 1024;
    }
    return $val;
}
*/

selfInvoker();
?>
</body>

</html>


Ответы (0 шт):