Gostaria de gravar a webcam e o áudio dos usuários e salvá-los em um arquivo no servidor. Esses arquivos podem ser disponibilizados a outros usuários.
Não tenho problemas com a reprodução, mas estou tendo problemas para gravar o conteúdo.
Meu entendimento é que a .record()
função getUserMedia ainda não foi escrita - apenas uma proposta foi feita para ela até agora.
Eu gostaria de criar uma conexão de mesmo nível no meu servidor usando o PeerConnectionAPI. Eu entendo que isso é um pouco hacky, mas estou pensando que deveria ser possível criar um par no servidor e registrar o que o cliente-par envia.
Se isso for possível, devo ser capaz de salvar esses dados em flv ou qualquer outro formato de vídeo.
Minha preferência é, na verdade, gravar a webcam + áudio do lado do cliente, para permitir que o cliente regravar os vídeos se não gostou da primeira tentativa antes de enviar. Isso também permitiria interrupções nas conexões de rede. Eu vi um código que permite a gravação de 'imagens' individuais da webcam enviando os dados para a tela - isso é legal, mas eu preciso do áudio também.
Aqui está o código do lado do cliente que tenho até agora:
<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>
fonte
Respostas:
Você definitivamente deveria dar uma olhada no Kurento . Ele fornece uma infraestrutura de servidor WebRTC que permite gravar a partir de um feed WebRTC e muito mais. Você também pode encontrar alguns exemplos para o aplicativo que está planejando aqui . É realmente fácil adicionar recursos de gravação a essa demonstração e armazenar o arquivo de mídia em um URI (disco local ou qualquer outro lugar).
O projeto está licenciado sob
LGPLApache 2.0EDITAR 1
Desde esta postagem, adicionamos um novo tutorial que mostra como adicionar o gravador em alguns cenários
Disclaimer: Faço parte da equipe que desenvolve o Kurento.
fonte
Por favor, verifique o RecordRTC
RecordRTC é licenciado pelo MIT no github .
fonte
Eu acredito usando kurento ou outro MCUs apenas para a gravação de vídeos seria pouco de exagero, especialmente considerando o fato de que o Chrome tem MediaRecorder suporte API de V47 e Firefox desde v25. Então, nesta junção, você pode nem precisar de uma biblioteca js externa para fazer o trabalho, tente esta demonstração que fiz para gravar vídeo / áudio usando MediaRecorder:
Demo - funcionaria no Chrome e Firefox (intencionalmente deixado de fora empurrando blob para o código do servidor)
Fonte do código Github
Se estiver executando o Firefox, você pode testá-lo aqui (necessidades do 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>
fonte
sim, como você entendeu, MediaStreamRecorder não está implementado no momento.
MediaStreamRecorder é uma API WebRTC para gravar streams getUserMedia (). Ele permite que os aplicativos da web criem um arquivo a partir de uma sessão de áudio / vídeo ao vivo.
como alternativa, você pode fazer isso http://ericbidelman.tumblr.com/post/31486670538/creating-webm-video-from-getusermedia, mas falta parte do áudio.
fonte
Você pode usar RecordRTC junto , que é baseado em RecordRTC.
Ele suporta a gravação de vídeo e áudio juntos em arquivos separados. Você precisará de uma ferramenta como
ffmpeg
mesclar dois arquivos em um no servidor.fonte
O Web Call Server 4 pode gravar áudio e vídeo WebRTC no contêiner WebM. A gravação é feita usando o codec Vorbis para áudio e o codec VP8 para vídeo. Os codecs WebRTC iniciais são Opus ou G.711 e VP8. Portanto, a gravação do lado do servidor requer transcodificação Opus / G.711 para Vorbis do lado do servidor ou transcodificação VP8-H.264 se for necessário usar outro contêiner, ou seja, AVI.
fonte
Só para constar, também não tenho conhecimento suficiente sobre isso,
Mas eu encontrei isso no hub 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>
Na linha número 89 no meu código de caso OnrecordComplete, na verdade, anexar um link do arquivo do gravador, se você clicar nesse link, ele iniciará o download, você pode salvar esse caminho para o seu servidor como um arquivo.
O código de gravação se parece com isto
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); };
O blobUrl contém o caminho. Resolvi meu problema com isso, espero que alguém ache isso útil
fonte
Tecnicamente, você pode usar FFMPEG no back-end para misturar vídeo e áudio
fonte