Захват HTML5 и сохранить видео

Я создаю сайт для петь-alongs, где пользователь может захватить видео себя петь вместе с mp3. Я дошел до того, что могу получить доступ к камере и отобразить живой поток, но как я могу сохранить видео, чтобы пользователь мог загрузить и сохранить его?

мой код:

<!DOCTYPE html>
<head>
<link href="css/bootstrap.css" rel="stylesheet"">
<style>
#container {
margin: 0px auto;
width: 500px;
height: 375px;
border: 10px #333 solid;
}
#videoElement {
width: 500px;
height: 375px;
background-color: #666;
}
</style>
</head>
<body>

<button class="btn" onclick="show();">Record!</button>


<div id="record" style="display:none; text-align:center;">
<div id="container">
<video autoplay="false" id="videoElement">
</video>
</div>
<button id="play" class="btn" onclick="play()">Start Recording!</button>
<audio id="song" style="hidden">
<source src="love.mp3" type="audio/mpeg">
Your browser does not support the audio element.
</audio>
</div>



<script src="http://code.jquery.com/jquery.js"></script>
<script src="js/bootstrap.js"></script>
<script>

var video = document.querySelector("#videoElement");

navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia ||    navigator.mozGetUserMedia || navigator.msGetUserMedia || navigator.oGetUserMedia;

if (navigator.getUserMedia) {       
navigator.getUserMedia({video: true, audio: true}, handleVideo, videoError);
}

function handleVideo(stream) {
video.src = window.URL.createObjectURL(stream);
document.getElementById("videoElement").pause();
}

function videoError(e) {
alert("There was an error with the video stream.nCheck that your webcam is connected.");
}

function play()
{
var video = document.getElementById("videoElement");
var music = document.getElementById("song");
   var button = document.getElementById("play");
   if (video.paused) {
      video.play();
      music.play();
      button.textContent = "Stop Recording";
   } else {
      video.pause();
      music.pause();
      button.textContent = "Continue Recording";
   }
}

function show()
{
document.getElementById("record").style.display="block";
}
</script>
</body>

есть ли способ в handleVideo я могу сохранить поток, как он приходит или что-то еще?

2 ответов


обновление 12/2014 FYI, есть новый API на своем пути под названием MediaRecorder. В настоящее время поддерживается только в Firefox, и в раннем состоянии, но что-то иметь в виду.

mediaStream и локальное хранилище

в чистой локальной среде вы не можете и не получите очень хороший результат. Вы можете сохранить кадры с помощью элемента canvas, рисуя на нем и хранить изображения jpeg в локальном хранилище из видеопоток вместе со звуком (который должен быть сохранен отдельно), а затем в post используйте библиотеку для создания, например, файла MJPEG (AFAIK в настоящее время нет ни одного, который поддерживает аудио).

вы столкнетесь с несколькими проблемами с этим подходом, однако: потребуется много времени, чтобы использовать JavaScript для обработки всей этой информации-просто сохранение кадра как jpeg, преобразование его в blob и сохранить его в файловой системе или индексированной БД будет потреблять большую часть (или больше) бюджета времени у вас есть доступный для одиночной рамки.

вы не сможете синхронизировать видеокадры со звуком должным образом - вы можете сохранить отметку времени и использовать ее для "исправления" кадров, но ваш FPS, скорее всего, будет меняться, создавая отрывистое видео. И даже если вы получите синхронизацию в определенном порядке, вы, вероятно, столкнетесь с проблемами с задержкой, когда аудио и видео не совпадают, поскольку они изначально являются двумя отдельными потоками.

но видео очень редко выше 30 FPS (США) или 25 FPS (Европа) так что вам не понадобится полный 60 кадров в секунду скорость браузера мая обеспечить. Это дает вам немного лучший бюджет времени около 33 миллисекунд на кадр для системы US (NTSC) и немного больше, если вы находитесь в стране, использующей систему PAL. Нет ничего плохого в использовании еще более низкой частоты кадров, но в определенный момент (

есть, однако, много факторов, которые будут влиять на это, такие как процессор, дисковая система, размер рамки и так далее. JavaScript однопоточен, а canvas API синхронен, поэтому 12-ядерный процессор не поможет вам в этом отношении, а полезность веб-работников в настоящее время ограничена в значительной степени более длительными задачами. Если у вас есть много доступной памяти, вы можете кэшировать кадры в памяти, которая способна и выполнять всю обработку в post, которая снова займет некоторое время. Поток, записанный на 720p @ 30 FPS, будет потреблять минимум 105 Мб в секунду (это просто необработанные данные, не включая внутренняя обработка браузером буферов, которые могут удвоить или даже утроить это).

WebRTC

лучшим решением, вероятно, является использование WebRTC и подключение к серверу (внешнему или локальному) и обработка потока там. Этот поток будет содержать синхронизированные аудио и видео, и вы можете сохранить поток временно на диск без ограничений области хранения браузера в песочнице. Недостатком здесь будет (для внешних соединений) пропускная способность, поскольку это может уменьшить качество, а также возможности сервера.

Это открывает возможность использовать, например, узел.js, .Net или PHP для фактической обработки с использованием сторонних компонентов (или более низкоуровневый подход, такой как использование скомпилированного C/C++ и CGI/piping, если вы в этом).

вы можете проверить этот проект с открытым исходным кодом, который поддерживает перекодирование потоков WebRTC:
http://lynckia.com/licode/

проект Licode предоставляет клиент NodeJS API для WebRTC, чтобы вы могли использовать его на стороне сервера,посмотреть документы

и это в основном, как далеко вы можете пойти с текущим состоянием HTML5.

вспышка

тогда есть возможность установки Flash и использовать это-вы еще нужен сервер бортовое разрешение (Red5, Wowza или AMS).

Это, вероятно, даст вам менее болезненный опыт, но вам нужно установить Flash в браузере (очевидно) и во многих случаях существует более высокий коэффициент затрат из-за лицензий (см. Red5 для открытого исходного кода альтернатива).

Если вы готовы платить за коммерческие решения, есть такие решения, как это:
http://nimbb.com/


поток создается здесь.

function handleVideo(stream) {
 video.src = window.URL.createObjectURL(stream);
 document.getElementById("videoElement").pause();
}

ваши данные-это sream .. или окно.URL-АДРЕС.createObjectURL(поток).

но вы не можете просто написать поток или окно.URL-АДРЕС.createObjectURL (поток) для локального хранилища (2Мб.. для малого) или webkitRequestFileSystem (который позволяет вам ГБ) ... вам нужно прочитать данные из тега video и преобразовать их в canvas как один кадр, сохранив его в webkitfilesystem.

как файловая система изменилась в последнее время i googled для нового кода и нашел этот идеальный пример для вас. https://gist.github.com/piatra/2549734

в Примере он использует

setTimeout(function(){ draw(v, bc, w, h); }, 200);

который пишет кадр каждые 200 мс

Если вы хотите пользовательскую частоту кадров, просто измените 200 мс на 1000/25 ..(25кадров / с)

или используйте requestanimationframe, и вы должны получить около 60 кадров в секунду, если процессор ur поддерживает это .

теперь у вас нет реального потока в хорошем формате, таком как mp4 ... но много кадров, которые вы можете отобразить с помощью другой функции ... опять вам нужен очень быстрый процессор.

в этом примере аудио не работает.

для записи также аудио в WAV (вы не можете записывать mp3 или aac)... я нашел это.

http://typedarray.org/from-microphone-to-wav-with-getusermedia-and-web-audio/

Так что в конце вы могли бы это сделать... но это займет много места всего за несколько минут и требует очень быстрого процессора, чтобы все продумать.