PageSourceSearch

https://deepstreamio.github.io/assets/js/9348334c.3feb161b.js

js deepstreamio.github.io collected 2026-10-03 08:58:59 UTC 6,268 bytes, 1 lines download raw bytes

1"use strict";(globalThis.webpackChunkdeepstreamio_github_io||=[]).push([[3874],{8387(e,t,i){i.r(t),i.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>h,frontMatter:()=>a,metadata:()=>r,toc:()=>d});const r=JSON.parse('{"id":"guides/webrtc/webrtc-audio-video","title":"WebRTC 03:Audio & Video","description":"Learn how to establish audio and video streams using deepstream","source":"@site/docs/20-guides/webrtc/30-webrtc-audio-video.md","sourceDirName":"20-guides/webrtc","slug":"/guides/webrtc/webrtc-audio-video","permalink":"/docs/guides/webrtc/webrtc-audio-video","draft":false,"unlisted":false,"editUrl":"https://github.com/deepstreamIO/deepstreamIO.github.io/docs/20-guides/webrtc/30-webrtc-audio-video.md","tags":[{"inline":true,"label":"WebRTC","permalink":"/docs/tags/web-rtc"},{"inline":true,"label":"Video","permalink":"/docs/tags/video"},{"inline":true,"label":"Audio","permalink":"/docs/tags/audio"}],"version":"current","sidebarPosition":30,"frontMatter":{"title":"WebRTC 03:Audio & Video","description":"Learn how to establish audio and video streams using deepstream","tags":["WebRTC","Video","Audio"]},"sidebar":"tutorialSidebar","previous":{"title":"WebRTC 02: Many-To-Many connectivity","permalink":"/docs/guides/webrtc/webrtc-full-mesh"},"next":{"title":"WebRTC 04: Video Editing / Canvas Streams","permalink":"/docs/guides/webrtc/webrtc-video-manipulation"}}');var o=i(4848),n=i(8453);const a={title:"WebRTC 03:Audio & Video",description:"Learn how to establish audio and video streams using deepstream",tags:["WebRTC","Video","Audio"]},s=void 0,l={},d=[{value:"Is that really all there is to it?",id:"is-that-really-all-there-is-to-it",level:3},{value:"Manipulating video",id:"manipulating-video",level:2}];function c(e){const t={a:"a",code:"code",h2:"h2",h3:"h3",p:"p",pre:"pre",...(0,n.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsxs)(t.p,{children:["Once you know how to ",(0,o.jsx)(t.a,{href:"webrtc-datachannels",children:"establish a WebRTC connection between two peers"}),", adding audio and video streams to this connection is surprisingly easy."]}),"\n",(0,o.jsxs)(t.p,{children:["First of all we request access to the user's microphone and camera using the browser's ",(0,o.jsx)(t.code,{children:"navigator.getUserMedia"})," method. Once we have access to a stream we store a reference to it, render it on a video element using ",(0,o.jsx)(t.code,{children:"URL.createObjectURL( stream )"})," and establish our P2PConnection."]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-javascript",children:"navigator.getUserMedia(\n    { video: true, audio: true },\n    stream => {\n        localStream = stream;\n        $( '.local video' ).attr( 'src', URL.createObjectURL( stream ) );\n        init();\n    },\n    error => {\n        alert( 'error while accessing usermedia ' + error.toString() );\n    }\n);\n"})}),"\n",(0,o.jsx)(t.p,{children:"When establishing the connection we'll add the stream as a parameter:"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-javascript",children:"const p2pConnection = new SimplePeer({\n    initiator: document.location.hash === '#initiator',\n    stream: localStream\n});\n"})}),"\n",(0,o.jsxs)(t.p,{children:["On the other client this will trigger a ",(0,o.jsx)(t.code,{children:"'stream'"})," event as soon as the stream becomes available. Upon receiving it we'll again render it to an HTML5 video tag."]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-javascript",children:"p2pConnection.on( 'stream', remoteStream => {\n    $( '.remote video' ).attr( 'src', URL.createObjectURL( remoteStream ) );\n});\n"})}),"\n",(0,o.jsxs)(t.p,{children:["And that's already all it takes to establish a simple audio & video chat between to peers Please find the ",(0,o.jsx)(t.a,{href:"https://github.com/deepstreamIO/dsh-demo-webrtc-examples/blob/master/02-full-mesh/full-mesh.js",children:"full code here"}),"."]}),"\n",(0,o.jsx)(t.h3,{id:"is-that-really-all-there-is-to-it",children:"Is that really all there is to it?"}),"\n",(0,o.jsx)(t.p,{children:"If you are a regular user of video conferencing software you know one thing only too well: It doesn't work properly. Reliable video-chat is still an extremely hard problem to solve and even giants like Google or Skype struggle to provide reliable and high-quality streams between users."}),"\n",(0,o.jsx)(t.p,{children:"WebRTC is no difference. If you've tried the example above it probably worked well - but only because there's a limited number of users chatting on a local network. For larger usecases you'll most likely want to avoud peer-to-peer connectivity and instead relay your video-stream to a server."}),"\n",(0,o.jsxs)(t.p,{children:["This server can be a so called Selective Forwarding Unit (SFU), e.g. ",(0,o.jsx)(t.a,{href:"https://jitsi.org/Projects/JitsiVideobridge",children:"Jitsi's Video Bridge"})," or a general purpose WebRTC Gateway such as ",(0,o.jsx)(t.a,{href:"https://janus.conf.meetecho.com/",children:"Janus"}),"."]}),"\n",(0,o.jsxs)(t.p,{children:["Alternatively you can also use one of the many cloud service providers in this space, e.g. ",(0,o.jsx)(t.a,{href:"https://tokbox.com/",children:"TokBox"})," or ",(0,o.jsx)(t.a,{href:"https://skylink.io/",children:"Skylink"}),"."]}),"\n",(0,o.jsx)(t.h2,{id:"manipulating-video",children:"Manipulating video"}),"\n",(0,o.jsxs)(t.p,{children:["So far we've only worked with the raw video stream from our webcam. But in times of Snapchat dog-nose overlays and Instagram retro-filters this might not be enough. Move on to the ",(0,o.jsx)(t.a,{href:"webrtc-video-manipulation",children:"next tutorial"})," to learn how to edit the stream before sending it to a peer."]})]})}function h(e={}){const{wrapper:t}={...(0,n.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(c,{...e})}):c(e)}},8453(e,t,i){i.d(t,{R:()=>a,x:()=>s});var r=i(6540);const o={},n=r.createContext(o);function a(e){const t=r.useContext(n);return r.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function s(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),r.createElement(n.Provider,{value:t},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.