para - javascript camera
Cómo grabar cámara web y audio usando webRTC y una conexión de Peer basada en servidor (9)
Me gustaría grabar la cámara web y el audio de los usuarios y guardarlo en un archivo en el servidor. Estos archivos podrían luego ser servidos a otros usuarios.
No tengo problemas con la reproducción, sin embargo, tengo problemas para grabar el contenido.
Tengo entendido que la función getUserMedia .record()
aún no se ha escrito, solo se ha hecho una propuesta hasta el momento.
Me gustaría crear una conexión de igual en mi servidor utilizando la PeerConnectionAPI. Entiendo que esto es un poco raro, pero creo que debería ser posible crear un par en el servidor y registrar lo que envía el cliente-par.
Si esto es posible, debería poder guardar esta información en flv o en cualquier otro formato de video.
Mi preferencia es grabar la cámara + audio del lado del cliente, para permitir que el cliente vuelva a grabar videos si no le gustó su primer intento antes de subirlo. Esto también permitiría interrupciones en las conexiones de red. He visto un código que permite grabar "imágenes" individuales desde la cámara web al enviar los datos al lienzo, eso es genial, pero también necesito el audio.
Aquí está el código del lado del cliente que tengo hasta ahora:
<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>
Creo que usar kurento u otras MCU solo para grabar videos sería un poco exagerado, especialmente teniendo en cuenta el hecho de que Chrome tiene MediaRecorder con MediaRecorder API desde v47 y Firefox desde v25. Entonces, en este cruce, puede que ni siquiera necesite una biblioteca js externa para hacer el trabajo, pruebe esta demostración que hice para grabar video / audio usando MediaRecorder:
Demo : funcionaría en Chrome y Firefox (se omitió intencionalmente al presionar blob al código del servidor)
Si ejecuta Firefox, puede probarlo aquí mismo (Chrome necesita 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>
Definitivamente deberías echarle un vistazo a Kurento . Proporciona una infraestructura de servidor WebRTC que le permite grabar desde un alimentador WebRTC y mucho más. También puede encontrar algunos ejemplos para la aplicación que está planeando here . Es realmente fácil agregar capacidades de grabación a esa demostración, y almacenar el archivo multimedia en un URI (disco local o donde sea).
El proyecto está licenciado bajo LGPL Apache 2.0
EDIT 1
Desde esta publicación, hemos agregado un nuevo tutorial que muestra cómo agregar la grabadora en un par de escenarios
- kurento-hello-world-recording : tutorial simple de grabación, que muestra las diferentes capacidades del punto final de grabación.
- kurento-one2one-recording : Cómo grabar una comunicación uno a uno en el servidor de medios.
- kurento-hello-world-repository : use un repositorio externo para registrar el archivo.
Descargo de responsabilidad: soy parte del equipo que desarrolla Kurento.
Echa un vistazo a Janus. Aquí hay una demostración de grabación:
https://janus.conf.meetecho.com/recordplaytest.html
A diferencia de Kurento, cuyo desarrollo se ha ralentizado severamente después de la adquisición de Twilio, Janus continúa siendo activamente desarrollado y respaldado.
Para el registro, tampoco tengo suficiente conocimiento sobre esto,
Pero encontré esto en el centro de 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>
En la línea número 89, en mi caso, el código OnrecordComplete anexa un enlace del archivo de la grabadora. Si hace clic en ese enlace, comenzará la descarga, puede guardar esa ruta en su servidor como un archivo.
El código de grabación se ve algo como esto
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);
};
El blobUrl contiene el camino. Resolví mi problema con esto, espero que alguien lo encuentre útil
Puede usar RecordRTC-together , que se basa en RecordRTC.
Es compatible con la grabación de video y audio juntos en archivos separados. Necesitará una herramienta como ffmpeg
para fusionar dos archivos en uno en el servidor.
Técnicamente puedes usar FFMPEG en back-end para mezclar video y audio
sí, como usted entendió, MediaStreamRecorder no está implementado actualmente.
MediaStreamRecorder es una API de WebRTC para grabar streams de getUserMedia (). Permite a las aplicaciones web crear un archivo a partir de una sesión de audio / video en vivo.
alternativamente, puede hacer esto http://ericbidelman.tumblr.com/post/31486670538/creating-webm-video-from-getusermedia pero falta el audio.
Web Call Server 4 puede grabar audio y video de WebRTC en el contenedor de WebM. La grabación se realiza utilizando el códec Vorbis para audio y el códec VP8 para video. Los codecs WebRTC iniciales son Opus o G.711 y VP8. Entonces, la grabación en el lado del servidor requiere una transcodificación Opus / G.711 a Vorbis del lado del servidor o una transcodificación VP8-H.264 si es necesario utilizar otro contenedor, es decir, AVI.