如何使用的WebRTC和基于服务器等连接以录制视频和音频(How to record webcam

2019-09-03 10:22发布

我想记录用户的摄像头和音频,并将其保存到服务器上的文件。 然后,这些文件将能够担任了给其他用户。

我有没有播放问题,但是我在获取内容记录的问题。

我的理解是,getUserMedia .record()函数还没有被写入-只是一个提议已经为它作了至今。

我想创建一个使用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>

Answer 1:

你一定要看看Kurento 。 它提供了一个服务器的WebRTC架构,可以让你从一个的WebRTC饲料和更多的记录。 您还可以找到您所规划的应用一些例子在这里 。 这是很容易录制功能添加到演示,并存储在一个URI的媒体文件(本地磁盘或其他地方)。

该项目按LGPL Apache 2.0的许可


编辑1

由于这个职位,我们增加了一个新的教程,显示如何添加记录在几个场景

  • kurento问候世界记录 :简单的录音教程,表示记录端点的不同的能力。
  • kurento-one2one录音 :如何录制媒体服务器一个一对一的沟通。
  • kurento问候世界-仓库 :使用外部存储库记录文件。

免责声明:我认为发展Kurento团队的一部分。



Answer 2:

请检查RecordRTC

RecordRTC是MIT许可在github上 。



Answer 3:

我相信使用kurento或其它MCU只为录制视频将是矫枉过正位,特别是考虑到Chrome的事实MediaRecorder从自V25 V47和Firefox API支持。 因此,在这个路口,你甚至不需要一个外部JS库来完成这项工作,试试这个演示中,我提出用MediaRecorder录制视频/音频:

演示 -将在Chrome和Firefox浏览器(故意冷落推BLOB到服务器代码)

Github的代码源

如果运行Firefox,你可以在这里本身(铬需要测试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> 



Answer 4:

是的,正如你明白,MediaStreamRecorder目前还没有实现。

MediaStreamRecorder是用于记录一个getUserMedia API的WebRTC()流。 它让网络应用从现场音频/视频会话创建一个文件。

或者你可以做这样的http://ericbidelman.tumblr.com/post/31486670538/creating-webm-video-from-getusermedia但听不到声音的一部分。



Answer 5:

您可以使用RecordRTC在一起 ,这是基于RecordRTC。

它支持在不同的文件中记录的视频和音频在一起。 您将需要一个像工具ffmpeg两个文件合并到一个服务器上。



Answer 6:

网络呼叫服务器4可记录的WebRTC音频和视频的WebM容器。 记录使用Vorbis格式编解码器的视频和音频编解码器VP8完成。 Iniitial的WebRTC编解码器作品或G.711和VP8。 所以,服务器端的记录要求要么OPUS / G.711到Vorbis格式的服务器端转码或VP8-H.264转码,如果有必要使用其他容器,如AVI。



Answer 7:

退房剑锋。 这里是一个记录演示:

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

不像Kurento,其发展的Twilio收购后严重放缓,剑锋继续积极开发和支持。



Answer 8:

为了记录我也没有对此足够的知识,

但是我发现这对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>

在我的情况下,代码OnrecordComplete实际上追加记录文件的链接,如果你是点击链接就会开始下载行号89,您可以在路径保存到服务器的文件。

记录码看起来是这样的

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保存路径。 我解决我的这个问题,希望有人会发现这很有用



Answer 9:

从技术上讲,你可以使用FFMPEG在后台混合的视频和音频



文章来源: How to record webcam and audio using webRTC and a server-based Peer connection