वेबआरटीसी और सर्वर-आधारित पीयर कनेक्शन का उपयोग करके वेबकैम और ऑडियो कैसे रिकॉर्ड करें


90

मैं उपयोगकर्ताओं को वेबकैम और ऑडियो रिकॉर्ड करना और सर्वर पर एक फ़ाइल में सहेजना चाहूंगा। इन फ़ाइलों को तब अन्य उपयोगकर्ताओं के लिए परोसा जा सकेगा।

मुझे प्लेबैक की कोई समस्या नहीं है, हालाँकि मुझे सामग्री को रिकॉर्ड करने में समस्या हो रही है।

मेरी समझ यह है कि getUserMedia .record()फ़ंक्शन अभी तक नहीं लिखा गया है - केवल इसके लिए अब तक एक प्रस्ताव बनाया गया है।

मैं PeerConnectionAPI का उपयोग करके अपने सर्वर पर सहकर्मी कनेक्शन बनाना चाहूंगा। मैं समझता हूं कि यह थोड़ा हैकी है, लेकिन मैं सोच रहा हूं कि सर्वर पर सहकर्मी बनाना और क्लाइंट-पेयर द्वारा भेजे गए रिकॉर्ड को रिकॉर्ड करना संभव होना चाहिए।

यदि यह संभव है, तो मुझे इस डेटा को फ़्लव या किसी अन्य वीडियो प्रारूप में सहेजने में सक्षम होना चाहिए।

मेरी प्राथमिकता वास्तव में वेब कैमरा + ऑडियो क्लाइंट-साइड रिकॉर्ड करना है, क्लाइंट को वीडियो को फिर से रिकॉर्ड करने की अनुमति देने के लिए अगर वे अपलोड करने के अपने पहले प्रयास को पसंद नहीं करते थे। यह नेटवर्क कनेक्शन में रुकावट के लिए भी अनुमति देगा। मैंने कुछ कोड देखे हैं जो डेटा को कैनवास पर भेजकर वेबकैम से अलग-अलग 'छवियों' को रिकॉर्ड करने की अनुमति देता है - यह अच्छा है, लेकिन मुझे ऑडियो भी चाहिए।

यहाँ अब तक मेरे पास क्लाइंट साइड कोड है:

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

मेरे साथ भी वही दिक्कत है। क्या विधि getRecordedData () आपके लिए काम कर रही है? यह मेरे ताज़ा-अपडेटेड-ब्राउज़र पर नहीं है।
फिरास

नहीं - मैंने 'Google कैनरी' भी आजमाई।
डेव हिल्डिच

हाँ, मैं इस पर कड़ी नज़र रख रहा हूँ - जब उचित समाधान होगा तो मैं इस धागे को अपडेट करूँगा।
डेव हिल्डिच

2
यदि आपको उपरोक्त प्रश्न का समाधान मिला है तो कृपया मेरे साथ साझा करें, धन्यवाद
मुहम्मद

2
क्या किसी ने मीडियास्ट्रीम बाइट्स को कुछ सर्वर-साइड RTC मैजिक के माध्यम से प्राप्त किया है?
विनय

जवाबों:


44

आप निश्चित रूप से Kurento पर एक नज़र होना चाहिए । यह एक WebRTC सर्वर अवसंरचना प्रदान करता है जो आपको WebRTC फ़ीड और बहुत कुछ रिकॉर्ड करने की अनुमति देता है। आप यहां जिस एप्लिकेशन की योजना बना रहे हैं उसके लिए कुछ उदाहरण भी पा सकते हैं । उस डेमो में रिकॉर्डिंग क्षमताओं को जोड़ना वास्तव में आसान है, और मीडिया फ़ाइल को एक यूआरआई (स्थानीय डिस्क या जहां भी) में संग्रहीत करना है।

परियोजना LGPL अपाचे 2.0 के तहत लाइसेंस प्राप्त है


EDIT 1

इस पोस्ट के बाद से, हमने एक नया ट्यूटोरियल जोड़ा है जो बताता है कि रिकॉर्डर को एक-दो परिदृश्यों में कैसे जोड़ा जाए

डिस्क्लेमर: मैं उस टीम का हिस्सा हूं जो कुरेंटो को विकसित करता है।


2
@Redtopia कुछ हालिया लोड परीक्षणों में हम I5 / I10 RAM पर webrtc के 150 वन 2 कनेक्शन प्राप्त करने में सक्षम थे। आप उम्मीद कर सकते हैं कि ये संख्या भविष्य में बेहतर होगी, लेकिन चमत्कार की उम्मीद न करें: SRTP के लिए बहुत सी एन्क्रिप्शन चल रही है, और यह मांग कर रही है। हम हार्डवेयर-त्वरित एन्क्रिप्शन / डिक्रिप्शन में देख रहे हैं, और संख्या अधिक हो जाएगी, और हालांकि मैं आपको आश्वासन नहीं दे सकता कि जब तक हम इसे और अधिक अच्छी तरह से परीक्षण नहीं करेंगे, हम एक 3x सुधार की उम्मीद करते हैं
igracia

2
@ user344146 वह शायद मुझे जवाब दे रहा था। क्या आप उस पोस्ट का लिंक साझा करना चाहेंगे? यदि आपको वह उत्तर मिला है, तो शायद इसलिए कि आपने कुछ पूछा है जो पहले से था या सूची में था। ऐसा लगता है कि आप एक स्नैपशॉट संस्करण संकलित करने की कोशिश कर रहे थे। उन कलाकृतियों को केंद्रीय में प्रकाशित नहीं किया जाता है, इसलिए या तो आप ट्यूटोरियल की एक रिलीज़ की जाँच करें या हमारे आंतरिक देव रेपो का उपयोग करें। इस सूची में कई बार जवाब दिया गया है, विकास संस्करणों के साथ काम करने के बारे में प्रलेखन में एक प्रविष्टि है ... हमने इसे लिखने के लिए समय लिया है, इसलिए इसे पढ़ने के लिए समय निकालना आपके लिए अच्छा होगा।
.ग्रेसिया

2
मैं सिर्फ ऐसी रिकॉर्डिंग बनाने के लिए कुर्तेो का उपयोग कर रहा हूं। अवधारणा को समझने के लिए जटिल नहीं है, लेकिन थोड़ा समय की आवश्यकता है, क्योंकि कुछ डॉक्स वास्तव में मतलबी हैं- और यह पता लगाना कि मैं कुर्तेो को क्या भेज सकता हूं, या घटनाओं का विवरण और कभी-कभी वास्तव में निराशा हो सकती है। लेकिन वैसे भी- इस तरह की एक खुली परियोजना वास्तव में एक महान काम और उपयोग करने के लायक है। Kurento केवल linux में काम कर रही है (विंडोज़ संस्करण आधिकारिक नहीं है और पूरी कार्यक्षमता के साथ काम नहीं करता है)।
क्रिस्चियन

1
उपरोक्त प्रश्नों के उत्तर (दूसरों के लिए यहां पोस्ट करना) के लिए मिला, कुर्तो वर्तमान में जेडीके 7.0 का समर्थन करता है, ऐसा नहीं है कि इसे उबंटू 14.04 पर निर्भर रहना पड़ता है, इसे बाद के संस्करणों का भी समर्थन करना चाहिए, लेकिन कुरंतो को उबंटू के अन्य संस्करणों पर आधिकारिक रूप से परीक्षण नहीं किया गया है / अन्य लिनक्स संस्करण। इसके अलावा कुरेंटो 64 बिट संस्करण को आइसेंटलेशन के लिए आसानी से उपलब्ध है, हालाँकि आप 32 बिट वर्जन के सर्वर को इंस्टॉल कर सकते हैं, लेकिन आपको इसे पहले बनाना होगा।
बिल्बो बैगिन्स

1
दुर्भाग्य से, जैसा कि मेरे उत्तर में कहा गया है, टरिलियो अधिग्रहण के बाद कुर्तेो का विकास गंभीर रूप से धीमा हो गया है। मैं इसके बजाय Janus का उपयोग करने की सलाह देता हूं।
जैमिक्स

17

कृपया, RecordRTC की जाँच करें

RecordRTC एमआईटी पर लाइसेंस प्राप्त है GitHub


2
यह बहुत बढ़िया है - मेरा प्रश्न: क्या वीडियो और ऑडियो एक साथ रिकॉर्ड कर सकते हैं (दो अलग-अलग चीजों के बजाय एक वास्तविक वीडियो लाइव?)
ब्रायन प्रिय

सहमत - भयानक, लेकिन ऐसा लगता है कि यह केवल डेटा को अलग से रिकॉर्ड करता है।
डेव हिल्डिच


2
यह दृष्टिकोण क्रोम में Whammy.js के माध्यम से काम करता है। यह समस्याग्रस्त है क्योंकि गुणवत्ता के अनुकरण से बहुत कम हो जाता है Whammy Chrome की MediaStreamRadorder की कमी के लिए प्रदान करता है। अनिवार्य रूप से क्या होता है WhammyRecorder मीडियास्ट्रीम ऑब्जेक्ट URL पर एक वीडियो टैग इंगित करता है और फिर एक निश्चित फ्रेम दर पर एक कैनवास तत्व के वेब स्नैपशॉट लेता है। इसके बाद वह उन सभी फ़्रेमों को एक वेबम वीडियो में डालने के लिए Whammy का उपयोग करता है।
विनय

15

मैं सिर्फ वीडियो रिकॉर्डिंग overkill की बिट होगा kurento या अन्य MCUs उपयोग, विशेष रूप से तथ्य यह है क्रोम है कि विचार का मानना है MediaRecorder v47 और Firefox V25 के बाद से एपीआई समर्थन करते हैं। तो इस जंक्शन पर, आपको नौकरी करने के लिए किसी बाहरी js लाइब्रेरी की आवश्यकता भी नहीं हो सकती है, इस डेमो को मैं कोशिश करता हूं जिसे मैंने MediaRecorder का उपयोग करके वीडियो / ऑडियो रिकॉर्ड करने के लिए किया है:

डेमो - क्रोम और फ़ायरफ़ॉक्स में काम करेगा (जानबूझकर सर्वर कोड के लिए ब्लॉब को छोड़कर)

जीथब कोड स्रोत

अगर फ़ायरफ़ॉक्स चल रहा है, तो आप इसे स्वयं यहां जांच सकते हैं (क्रोम की आवश्यकता 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>


Chrome 49 फ्लैग के बिना MediaRecorder API को सपोर्ट करने वाला 1 है।
ऑक्टेवियन नाइकू

7

हाँ, जैसा कि आप समझते हैं, MediaStreamRecorder वर्तमान में कार्यान्वित नहीं किया गया है।

MediaStreamRecorder, GetUserMedia () स्ट्रीम को रिकॉर्ड करने के लिए एक WebRTC API है। यह वेब ऐप्स को लाइव ऑडियो / वीडियो सत्र से एक फ़ाइल बनाने की अनुमति देता है।

वैकल्पिक रूप से आप इस तरह से कर सकते हैं http://ericbidelman.tumblr.com/post/31486670538/creating-webm-video-from-getusermedia लेकिन ऑडियो हिस्सा गायब है।


1
हां, और आप ऑडियो फ़ाइल पर कब्जा कर सकते हैं, इसे सर्वर पर भेज सकते हैं, और सर्वर साइड पर एक वास्तविक वीडियो फ़ाइल बनाने के लिए उन्हें वहां जोड़ सकते हैं। लेकिन यह समाधान अपने कंप्यूटर कॉन्फ़िगरेशन के आधार पर क्लाइंट की तरफ बहुत धीमा हो सकता है, क्योंकि इसमें एक कैनवास का उपयोग करके छवि फ़ाइलों को बनाना है और ऑडियो को कैप्चर करना है, और रैम में यह सब ... Btw, फ़ायरफ़ॉक्स टीम इस पर काम कर रही है , इसलिए उम्मीद है कि वे इसे जल्द ही जारी करेंगे।
फिरास

4

आप RecordRTC- एक साथ उपयोग कर सकते हैं , जो RecordRTC पर आधारित है।

यह अलग-अलग फाइलों में एक साथ वीडियो और ऑडियो रिकॉर्ड करने का समर्थन करता है। आपको ffmpegसर्वर पर दो फ़ाइलों को एक में मर्ज करने जैसे टूल की आवश्यकता होगी ।


2
यह एक ब्राउज़र समाधान है, न कि सर्वर-साइड।
ब्रैड

2

वेब कॉल सर्वर 4 वेबएमटीसी ऑडियो और वीडियो को वेबएम कंटेनर में रिकॉर्ड कर सकता है। रिकॉर्डिंग ऑडियो के लिए Vorbis कोडेक और वीडियो के लिए VP8 कोडेक का उपयोग करके किया जाता है। Iniitial WebRTC कोडक Opus या G.711 और VP8 हैं। तो, सर्वर-साइड रिकॉर्डिंग के लिए या तो ओपस / G.711 से वोरबिस सर्वर-साइड ट्रांसकोडिंग या VP8-H.264 ट्रांसकोडिंग की आवश्यकता होती है, यदि किसी अन्य कंटेनर, यानी AVI का उपयोग करना आवश्यक हो।


क्या यह वाणिज्यिक सामान है?
Stepan Yakovenko

0

रिकॉर्ड के लिए मुझे भी इस बारे में पर्याप्त ज्ञान नहीं है,

लेकिन मैंने इसे 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>

मेरे केस कोड में लाइन नंबर 89 पर OnrecordComplete वास्तव में रिकॉर्डर फ़ाइल का एक लिंक संलग्न करता है, यदि आप उस लिंक पर क्लिक करेंगे तो यह डाउनलोड शुरू हो जाएगा, आप उस पथ को फ़ाइल के रूप में अपने सर्वर पर सहेज सकते हैं।

रिकॉर्डिंग कोड कुछ इस तरह दिखता है

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 पथ रखता है। मैंने इसके साथ अपनी समस्या को हल किया, आशा है कि किसी को यह उपयोगी लगेगा


-4

तकनीकी रूप से आप वीडियो और ऑडियो को मिलाने के लिए बैकएंड पर FFMPEG का उपयोग कर सकते हैं


7
हाँ, लेकिन आप उन्हें कैसे प्राप्त करते हैं?
एडी मेन्ज जूनियर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.