如何使用webRTC和基于服务器的Peer连接记录网络摄像头和音频

Dav*_*tch 81 javascript c++ video-streaming audio-streaming webrtc

我想记录用户网络摄像头和音频,并将其保存到服务器上的文件中.然后,这些文件可以提供给其他用户.

我没有播放问题,但是我在录制内容方面遇到了问题.

我的理解是.record()还没有编写getUserMedia 函数 - 到目前为止只提出了一个提议.

我想使用PeerConnectionAPI在我的服务器上创建一个对等连接.我知道这有点hacky,但我认为应该可以在服务器上创建一个peer并记录client-peer发送的内容.

如果可以,我应该能够将此数据保存为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>
Run Code Online (Sandbox Code Playgroud)

igr*_*cia 44

你一定要看看Kurento.它提供了一个WebRTC服务器基础结构,允许您从WebRTC源记录等等.您还可以在此处找到您计划的应用程序的一些示例.向该演示添加录制功能非常容易,并将媒体文件存储在URI(本地磁盘或任何位置)中.

该项目根据LGPL Apache 2.0 获得许可


编辑1

从这篇文章开始,我们添加了一个新教程,展示了如何在几个场景中添加录制器

免责声明:我是开发Kurento团队的一员.

  • @Redtopia在最近的一些负载测试中,我们能够在i5/16GB RAM上获得150个one2one的webrtc连接.您可以预期这些数字将来会更好,但不要指望奇迹:SRTP有很多加密,而且要求很高.我们正在研究硬件加速加密/解密,数字会更高,虽然我不能保证在我们更彻底地测试它之前会有多好,但我们预计会有3倍的改进 (2认同)
  • @ user344146 那可能是我在回答。你介意分享那个帖子的链接吗?如果你得到了那个答案,那可能是因为你问了一些已经存在或在列表中的问题。看起来您正在尝试编译 SNAPSHOT 版本。这些工件不会在中央发布,因此您可以查看教程的版本或使用我们的内部开发存储库。这已经在列表中多次回答了,文档中有一个关于使用开发版本的条目......我们花时间写它,所以你花时间阅读它会很高兴。 (2认同)
  • 我只是用Kurento进行录音.我并不复杂,但需要一点时间来理解这个概念 - 因为一些文档真的很有意义 - 并且找到我可以发送给kurento的内容,或者事件的描述等等有时候真的很令人沮丧.但无论如何 - 像这样的开放项目真的是一项伟大的工作,值得使用.Kurento只在linux上工作(Windows版本不是官方版本,不支持完整功能). (2认同)
  • 不幸的是,正如我在回答中所说,在 Twilio 收购之后,Kurento 的发展严重放缓。我建议改用 Janus。 (2认同)

Dmi*_*try 15

请检查RecordRTC

RecordRTC在github上获得MIT许可.

  • @BrianDear有一个[RecordRTC-together](https://github.com/H0201030/record-rtc-together) (3认同)
  • 这真是太棒了 - 我的问题是:可以将视频和音频一起录制(直播视频而不是两个独立的视频吗?) (2认同)
  • 这种方法通过Chrome中的Whammy.js起作用。这是有问题的,因为根据Whammy提供的模拟,Chrome缺少MediaStreamRecorder,因此质量往往要低得多。本质上发生的是WhammyRecorder将视频标签指向MediaStream对象URL,然后以特定帧速率拍摄canvas元素的webp快照。然后,它使用Whammy将所有这些帧放到一个webm视频中。 (2认同)

mid*_*ido 9

我认为使用kurento或其他MCU仅用于录制视频会有点过分,特别是考虑到Chrome 自v25以来已经从v47和Firefox 获得了MediaRecorder API支持.所以在这个结点,你可能甚至不需要一个外部的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);
}
Run Code Online (Sandbox Code Playgroud)
      button {
        margin: 10px 5px;
      }
      li {
        margin: 10px;
      }
      body {
        width: 90%;
        max-width: 960px;
        margin: 0px auto;
      }
      #btns {
        display: none;
      }
      h1 {
        margin-bottom: 100px;
      }
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)


Kon*_*aju 7

是的,正如您所理解的,MediaStreamRecorder目前尚未实现.

MediaStreamRecorder是一个用于记录getUserMedia()流的WebRTC API.它允许Web应用程序从实时音频/视频会话创建文件.

或者你可能会喜欢这个http://ericbidelman.tumblr.com/post/31486670538/creating-webm-video-from-getusermedia但音频缺少部分.