Frage Wie man Webcam und Audio mit webRTC und einer serverbasierten Peer-Verbindung aufnimmt


Ich möchte die Webcam und Audio des Benutzers aufnehmen und in einer Datei auf dem Server speichern. Diese Dateien könnten dann anderen Benutzern zur Verfügung gestellt werden.

Ich habe keine Probleme mit der Wiedergabe, aber ich habe Probleme, den Inhalt aufzunehmen.

Mein Verständnis ist das getUserMedia .record() Funktion wurde noch nicht geschrieben - nur ein Vorschlag wurde bisher gemacht.

Ich möchte eine Peer-Verbindung auf meinem Server mit der PeerConnectionAPI erstellen. Ich verstehe, dass dies ein bisschen hacky ist, aber ich denke, es sollte möglich sein, einen Peer auf dem Server zu erstellen und aufzuzeichnen, was der Client-Peer sendet.

Wenn dies möglich ist, sollte ich dann in der Lage sein, diese Daten in FLV oder einem anderen Videoformat zu speichern.

Meine Vorliebe ist eigentlich, die webcam + audio client-Seite aufzunehmen, um dem Kunden zu erlauben, Videos neu aufzunehmen, wenn sie ihren ersten Versuch vor dem Hochladen nicht mögen. Dies würde auch Unterbrechungen in Netzwerkverbindungen ermöglichen. Ich habe Code gesehen, der es ermöglicht, einzelne "Bilder" von der Webcam aufzunehmen, indem man die Daten an die Leinwand sendet - das ist cool, aber ich brauche auch das Audio.

Hier ist der clientseitige Code, den ich bisher habe:

  <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>

75
2018-05-15 17:06


Ursprung


Antworten:


Sie sollten sich das unbedingt ansehen Kurento. Es bietet eine WebRTC-Server-Infrastruktur, mit der Sie von einem WebRTC-Feed aufnehmen können und vieles mehr. Sie können auch einige Beispiele für die Anwendung finden, die Sie planen Hier. Es ist sehr einfach, dieser Demo Aufzeichnungsmöglichkeiten hinzuzufügen und die Mediendatei in einem URI (lokale Festplatte oder wo auch immer) zu speichern.

Das Projekt ist lizenziert unter LGPL Apache 2.0


BEARBEITEN 1

Seit diesem Beitrag haben wir ein neues Tutorial hinzugefügt, das zeigt, wie Sie den Rekorder in einigen Szenarien hinzufügen können

Disclaimer: Ich bin Teil des Teams, das Kurento entwickelt.


42
2017-07-25 16:18



Bitte überprüfen Sie die AufnahmeRTC

RecordRTC ist MIT lizenziert auf Github.


14
2018-06-30 12:22



Ich glaube, dass die Verwendung von Kurento oder anderen MCUs nur für das Aufnehmen von Videos ein wenig Overkill wäre, vor allem wenn man bedenkt, dass es Chrome gibt Medienrekorder API-Unterstützung von v47 und Firefox seit v25. An dieser Kreuzung brauchen Sie vielleicht nicht einmal eine externe js-Bibliothek, um diese Aufgabe zu erledigen. Versuchen Sie diese Demo, die ich gemacht habe, um Video / Audio mit MediaRecorder aufzunehmen:

Demo - würde in Chrome und Firefox funktionieren (absichtlich weggelassen Blob auf Server-Code schieben)

Github-Codequelle

Wenn Firefox läuft, könntest du es hier selbst testen (Chrome benötigt 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>


8
2018-04-22 02:29



Ja, wie Sie verstanden haben, ist MediaStreamRecorder derzeit nicht implementiert.

MediaStreamRecorder ist eine WebRTC-API zum Aufzeichnen von getUserMedia () - Streams. Es ermöglicht Web-Apps, eine Datei aus einer Live-Audio- / Videositzung zu erstellen.

alternativ können Sie dies tun http://ericbidelman.tumblr.com/post/31486670538/creating-webm-video-from-getusermedia aber Audio fehlt Teil.


7
2018-05-21 11:20



Sie können verwenden RecordRTC zusammen, die auf RecordRTC basiert.

Es unterstützt die Aufzeichnung von Video und Audio in separaten Dateien. Sie werden Werkzeug wie benötigen ffmpeg um zwei Dateien zu einem Server zusammenzufügen.


4
2017-11-10 16:26



Webanrufserver 4 kann WebRTC-Audio und Video im WebM-Container aufzeichnen. Die Aufnahme erfolgt mit Vorbis-Codec für Audio und VP8-Codec für Video. Ursprüngliche WebRTC-Codecs sind Opus oder G.711 und VP8. So erfordert die serverseitige Aufzeichnung entweder Opus / G.711 zu Vorbis serverseitiges Transcodieren oder VP8-H.264-Transcodieren, wenn es notwendig ist, einen anderen Container, d. H. AVI, zu verwenden.


0
2017-09-10 20:14



Für die Aufzeichnung habe ich auch nicht genug Wissen darüber,

Aber ich fand das auf Git Hub-

<!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>

On Line Nummer 89 in meinem Fall Code OnrecordComplete tatsächlich einen Link der Recorder-Datei anhängen, wenn Sie auf den Link klicken wird es den Download starten, können Sie diesen Pfad auf Ihrem Server als Datei speichern.

Der Aufnahmecode sieht ungefähr so ​​aus

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);
            };

Das BlobUrl enthält den Pfad. Ich habe mein Problem damit gelöst, hoffe, dass jemand das nützlich findet


0
2018-04-24 05:11



Schau dir Janus an. Hier ist eine Aufnahme Demo:

https://janus.conf.meetecho.com/recordplaytest.html

Im Gegensatz zu Kurento, dessen Entwicklung sich nach der Übernahme von Twilio stark verlangsamt hat, wird Janus weiterhin aktiv entwickelt und unterstützt.


0
2018-01-03 10:36



Technisch können Sie FFMPEG im Backend verwenden, um Video und Audio zu mischen


-4
2017-11-11 16:45