Я хочу записать пользовательскую веб-камеру и аудио и сохранить их в файл на сервере. Затем эти файлы можно будет передать другим пользователям.
У меня нет проблем с воспроизведением, но у меня проблемы с записью контента.
Насколько я понимаю, .record()
функция getUserMedia еще не написана - пока для нее сделано только предложение.
Я хочу создать одноранговое соединение на моем сервере с помощью PeerConnectionAPI. Я понимаю, что это немного взломано, но я думаю, что должно быть возможно создать одноранговый узел на сервере и записывать, что отправляет одноранговый клиент.
Если это возможно, я смогу сохранить эти данные в flv или любом другом видеоформате.
Я предпочитаю записывать веб-камеру + аудио на стороне клиента, чтобы позволить клиенту перезаписывать видео, если ему не понравилась первая попытка перед загрузкой. Это также позволило бы прерывать сетевые соединения. Я видел код, который позволяет записывать отдельные «изображения» с веб-камеры, отправляя данные на холст - это круто, но мне тоже нужен звук.
Вот код на стороне клиента, который у меня есть:
<video autoplay></video>
<script language="javascript" type="text/javascript">
function onVideoFail(e) {
console.log('webcam fail!', e);
};
function hasGetUserMedia() {
// Note: Opera is unprefixed.
return !!(navigator.getUserMedia || navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia || navigator.msGetUserMedia);
}
if (hasGetUserMedia()) {
// Good to go!
} else {
alert('getUserMedia() is not supported in your browser');
}
window.URL = window.URL || window.webkitURL;
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia || navigator.msGetUserMedia;
var video = document.querySelector('video');
var streamRecorder;
var webcamstream;
if (navigator.getUserMedia) {
navigator.getUserMedia({audio: true, video: true}, function(stream) {
video.src = window.URL.createObjectURL(stream);
webcamstream = stream;
// streamrecorder = webcamstream.record();
}, onVideoFail);
} else {
alert ('failed');
}
function startRecording() {
streamRecorder = webcamstream.record();
setTimeout(stopRecording, 10000);
}
function stopRecording() {
streamRecorder.getRecordedData(postVideoToServer);
}
function postVideoToServer(videoblob) {
/* var x = new XMLHttpRequest();
x.open('POST', 'uploadMessage');
x.send(videoblob);
*/
var data = {};
data.video = videoblob;
data.metadata = 'test metadata';
data.action = "upload_video";
jQuery.post("http://www.foundthru.co.uk/uploadvideo.php", data, onUploadSuccess);
}
function onUploadSuccess() {
alert ('video uploaded');
}
</script>
<div id="webcamcontrols">
<a class="recordbutton" href="javascript:startRecording();">RECORD</a>
</div>
источник
Ответы:
Вам обязательно стоит взглянуть на Куренто . Он предоставляет инфраструктуру сервера WebRTC, которая позволяет записывать из веб-канала WebRTC и многое другое. Вы также можете найти некоторые примеры для приложения , которое вы планируете здесь . В эту демонстрацию действительно легко добавить возможности записи и сохранить медиафайл в URI (на локальном диске или где-то еще).
Проект под лицензией
LGPLApache 2.0.ИЗМЕНИТЬ 1
После этого поста мы добавили новый учебник, в котором показано, как добавить регистратор в нескольких сценариях.
Отказ от ответственности: я часть команды, которая разрабатывает Kurento.
источник
Пожалуйста, проверьте RecordRTC
RecordRTC имеет лицензию MIT на github .
источник
Я считаю, что использование kurento или других микроконтроллеров только для записи видео было бы излишним, особенно учитывая тот факт, что Chrome поддерживает MediaRecorder API от v47 и Firefox начиная с v25. Итак, на этом стыке вам может даже не понадобиться внешняя библиотека js для выполнения этой работы, попробуйте эту демонстрацию, которую я сделал для записи видео / аудио с помощью MediaRecorder:
Демо - будет работать в chrome и firefox (намеренно пропущено нажатие blob на серверный код)
Исходный код Github
Если вы используете firefox, вы можете протестировать его здесь (требуется Chrome
https
):'use strict' let log = console.log.bind(console), id = val => document.getElementById(val), ul = id('ul'), gUMbtn = id('gUMbtn'), start = id('start'), stop = id('stop'), stream, recorder, counter = 1, chunks, media; gUMbtn.onclick = e => { let mv = id('mediaVideo'), mediaOptions = { video: { tag: 'video', type: 'video/webm', ext: '.mp4', gUM: { video: true, audio: true } }, audio: { tag: 'audio', type: 'audio/ogg', ext: '.ogg', gUM: { audio: true } } }; media = mv.checked ? mediaOptions.video : mediaOptions.audio; navigator.mediaDevices.getUserMedia(media.gUM).then(_stream => { stream = _stream; id('gUMArea').style.display = 'none'; id('btns').style.display = 'inherit'; start.removeAttribute('disabled'); recorder = new MediaRecorder(stream); recorder.ondataavailable = e => { chunks.push(e.data); if (recorder.state == 'inactive') makeLink(); }; log('got media successfully'); }).catch(log); } start.onclick = e => { start.disabled = true; stop.removeAttribute('disabled'); chunks = []; recorder.start(); } stop.onclick = e => { stop.disabled = true; recorder.stop(); start.removeAttribute('disabled'); } function makeLink() { let blob = new Blob(chunks, { type: media.type }), url = URL.createObjectURL(blob), li = document.createElement('li'), mt = document.createElement(media.tag), hf = document.createElement('a'); mt.controls = true; mt.src = url; hf.href = url; hf.download = `${counter++}${media.ext}`; hf.innerHTML = `donwload ${hf.download}`; li.appendChild(mt); li.appendChild(hf); ul.appendChild(li); }
button { margin: 10px 5px; } li { margin: 10px; } body { width: 90%; max-width: 960px; margin: 0px auto; } #btns { display: none; } h1 { margin-bottom: 100px; }
<link type="text/css" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"> <h1> MediaRecorder API example</h1> <p>For now it is supported only in Firefox(v25+) and Chrome(v47+)</p> <div id='gUMArea'> <div> Record: <input type="radio" name="media" value="video" checked id='mediaVideo'>Video <input type="radio" name="media" value="audio">audio </div> <button class="btn btn-default" id='gUMbtn'>Request Stream</button> </div> <div id='btns'> <button class="btn btn-default" id='start'>Start</button> <button class="btn btn-default" id='stop'>Stop</button> </div> <div> <ul class="list-unstyled" id='ul'></ul> </div> <script src="https://code.jquery.com/jquery-2.2.0.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
источник
да, как вы поняли, MediaStreamRecorder на данный момент не реализован.
MediaStreamRecorder - это API WebRTC для записи потоков getUserMedia (). Он позволяет веб-приложениям создавать файл из живого аудио / видео сеанса.
в качестве альтернативы вы можете сделать это http://ericbidelman.tumblr.com/post/31486670538/creating-webm-video-from-getusermedia, но часть звука отсутствует.
источник
Вы можете использовать RecordRTC вместе , который основан на RecordRTC.
Он поддерживает запись видео и звука вместе в отдельные файлы. Вам понадобится такой инструмент, как
ffmpeg
объединение двух файлов в один на сервере.источник
Web Call Server 4 может записывать аудио и видео WebRTC в контейнер WebM. Запись осуществляется с использованием кодека Vorbis для аудио и кодека VP8 для видео. Исходные кодеки WebRTC - это Opus или G.711 и VP8. Таким образом, для записи на стороне сервера требуется либо транскодирование Opus / G.711 в Vorbis на стороне сервера, либо транскодирование VP8-H.264, если необходимо использовать другой контейнер, например AVI.
источник
Для справки, у меня тоже недостаточно знаний об этом,
Но я нашел это в хабе Git-
<!DOCTYPE html> <html> <head> <title>XSockets.WebRTC Client example</title> <meta charset="utf-8" /> <style> body { } .localvideo { position: absolute; right: 10px; top: 10px; } .localvideo video { max-width: 240px; width:100%; margin-right:auto; margin-left:auto; border: 2px solid #333; } .remotevideos { height:120px; background:#dadada; padding:10px; } .remotevideos video{ max-height:120px; float:left; } </style> </head> <body> <h1>XSockets.WebRTC Client example </h1> <div class="localvideo"> <video autoplay></video> </div> <h2>Remote videos</h2> <div class="remotevideos"> </div> <h2>Recordings ( Click on your camera stream to start record)</h2> <ul></ul> <h2>Trace</h2> <div id="immediate"></div> <script src="XSockets.latest.js"></script> <script src="adapter.js"></script> <script src="bobBinder.js"></script> <script src="xsocketWebRTC.js"></script> <script> var $ = function (selector, el) { if (!el) el = document; return el.querySelector(selector); } var trace = function (what, obj) { var pre = document.createElement("pre"); pre.textContent = JSON.stringify(what) + " - " + JSON.stringify(obj || ""); $("#immediate").appendChild(pre); }; var main = (function () { var broker; var rtc; trace("Ready"); trace("Try connect the connectionBroker"); var ws = new XSockets.WebSocket("wss://rtcplaygrouund.azurewebsites.net:443", ["connectionbroker"], { ctx: '23fbc61c-541a-4c0d-b46e-1a1f6473720a' }); var onError = function (err) { trace("error", arguments); }; var recordMediaStream = function (stream) { if ("MediaRecorder" in window === false) { trace("Recorder not started MediaRecorder not available in this browser. "); return; } var recorder = new XSockets.MediaRecorder(stream); recorder.start(); trace("Recorder started.. "); recorder.oncompleted = function (blob, blobUrl) { trace("Recorder completed.. "); var li = document.createElement("li"); var download = document.createElement("a"); download.textContent = new Date(); download.setAttribute("download", XSockets.Utils.randomString(8) + ".webm"); download.setAttribute("href", blobUrl); li.appendChild(download); $("ul").appendChild(li); }; }; var addRemoteVideo = function (peerId, mediaStream) { var remoteVideo = document.createElement("video"); remoteVideo.setAttribute("autoplay", "autoplay"); remoteVideo.setAttribute("rel", peerId); attachMediaStream(remoteVideo, mediaStream); $(".remotevideos").appendChild(remoteVideo); }; var onConnectionLost = function (remotePeer) { trace("onconnectionlost", arguments); var peerId = remotePeer.PeerId; var videoToRemove = $("video[rel='" + peerId + "']"); $(".remotevideos").removeChild(videoToRemove); }; var oncConnectionCreated = function () { console.log(arguments, rtc); trace("oncconnectioncreated", arguments); }; var onGetUerMedia = function (stream) { trace("Successfully got some userMedia , hopefully a goat will appear.."); rtc.connectToContext(); // connect to the current context? }; var onRemoteStream = function (remotePeer) { addRemoteVideo(remotePeer.PeerId, remotePeer.stream); trace("Opps, we got a remote stream. lets see if its a goat.."); }; var onLocalStream = function (mediaStream) { trace("Got a localStream", mediaStream.id); attachMediaStream($(".localvideo video "), mediaStream); // if user click, video , call the recorder $(".localvideo video ").addEventListener("click", function () { recordMediaStream(rtc.getLocalStreams()[0]); }); }; var onContextCreated = function (ctx) { trace("RTC object created, and a context is created - ", ctx); rtc.getUserMedia(rtc.userMediaConstraints.hd(false), onGetUerMedia, onError); }; var onOpen = function () { trace("Connected to the brokerController - 'connectionBroker'"); rtc = new XSockets.WebRTC(this); rtc.onlocalstream = onLocalStream; rtc.oncontextcreated = onContextCreated; rtc.onconnectioncreated = oncConnectionCreated; rtc.onconnectionlost = onConnectionLost; rtc.onremotestream = onRemoteStream; rtc.onanswer = function (event) { }; rtc.onoffer = function (event) { }; }; var onConnected = function () { trace("connection to the 'broker' server is established"); trace("Try get the broker controller form server.."); broker = ws.controller("connectionbroker"); broker.onopen = onOpen; }; ws.onconnected = onConnected; }); document.addEventListener("DOMContentLoaded", main); </script>
В строке номер 89 в моем случае код OnrecordComplete фактически добавляет ссылку на файл рекордера, если вы нажмете на эту ссылку, начнется загрузка, вы можете сохранить этот путь на свой сервер в виде файла.
Код записи выглядит примерно так
recorder.oncompleted = function (blob, blobUrl) { trace("Recorder completed.. "); var li = document.createElement("li"); var download = document.createElement("a"); download.textContent = new Date(); download.setAttribute("download", XSockets.Utils.randomString(8) + ".webm"); download.setAttribute("href", blobUrl); li.appendChild(download); $("ul").appendChild(li); };
BlobUrl содержит путь. Я решил с этим свою проблему, надеюсь, кому-то это пригодится
источник
Технически вы можете использовать FFMPEG на бэкэнде для микширования видео и аудио.
источник