{"id":103577,"date":"2025-03-28T20:26:43","date_gmt":"2025-03-28T15:56:43","guid":{"rendered":"https:\/\/nabfollower.com\/blog\/video-streaming-tutorial-javascript-webrtc-streaming-example-libreremoteplay-l90\/"},"modified":"2025-03-28T20:26:43","modified_gmt":"2025-03-28T15:56:43","slug":"video-streaming-tutorial-javascript-webrtc-streaming-example-libreremoteplay-l90","status":"publish","type":"post","link":"https:\/\/nabfollower.com\/blog\/video-streaming-tutorial-javascript-webrtc-streaming-example-libreremoteplay-l90\/","title":{"rendered":"\u0622\u0645\u0648\u0632\u0634 \u067e\u062e\u0634 \u0648\u06cc\u062f\u06cc\u0648. JavaScript Webrtc Streaming \u0645\u062b\u0627\u0644 \ud83c\udf10liberremoteplay"},"content":{"rendered":"<div data-article-id=\"2352077\" id=\"article-body\">\n<p>\u0633\u0644\u0627\u0645 \u060c \u062f\u0631 \u0627\u06cc\u0646 \u067e\u0633\u062a \u0641\u0642\u0637 \u0628\u0627 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 GetDisplayMedia () (\u0635\u0641\u062d\u0647)) \u0641\u0642\u0637 \u062a\u0646\u0638\u06cc\u0645 \u0633\u0627\u062f\u0647 Webrtc \u0631\u0627 \u067e\u0648\u0634\u0634 \u062e\u0648\u0627\u0647\u0645 \u062f\u0627\u062f \u0627\u0645\u0627 \u0628\u0631\u0627\u06cc GetUsermedia () (\u062f\u0648\u0631\u0628\u06cc\u0646 \u060c \u0645\u06cc\u06a9\u0631\u0648\u0641\u0648\u0646) \u0646\u06cc\u0632 \u0645\u0639\u062a\u0628\u0631 \u0627\u0633\u062a.<\/p>\n<p>\u0627\u0648\u0644 \u0627\u06af\u0631 \u062f\u0631 \u062a\u0648\u0636\u06cc\u062d\u0627\u062a\/\u0622\u0645\u0648\u0632\u0634 \u0647\u0627\u06cc WEBRTC \u0628\u06cc\u0634\u062a\u0631 \u0645\u0648\u0631\u062f \u062a\u0648\u062c\u0647 \u0642\u0631\u0627\u0631 \u06af\u0631\u0641\u062a\u0647 \u0627\u06cc\u062f \u060c \u0627\u06cc\u0646 \u0628\u062e\u0634\u06cc \u0627\u0632 \u0645\u0642\u0627\u0644\u0627\u062a \u0633\u0631\u06cc Webrtc \u0628\u0631\u0627\u06cc JavaScript \u0648 Golang \u0627\u0633\u062a (\u0627\u06cc\u0646 \u0634\u0627\u0645\u0644 \u062f\u0627\u0646\u0634 \u0639\u0645\u0648\u0645\u06cc \u062f\u0631 \u0645\u0648\u0631\u062f Webrtc) \u0627\u0633\u062a.<\/p>\n<p>\u062f\u0631 \u0648\u0647\u0644\u0647 \u062f\u0648\u0645 \u060c \u0627\u0635\u0648\u0644 \u0627\u0648\u0644\u06cc\u0647 \u0631\u0627 \u062f\u0631 \u0645\u0648\u0631\u062f Medialchannels \u060c \u0622\u0646\u0686\u0647 \u0622\u0646\u0647\u0627 \u0647\u0633\u062a\u0646\u062f \u0648 \u0646\u062d\u0648\u0647 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 \u0622\u0646\u0647\u0627 \u062f\u0631 WebApp \u0634\u0645\u0627 \u0631\u0627 \u0628\u0647 \u0634\u0645\u0627 \u0645\u0639\u0631\u0641\u06cc \u0645\u06cc \u06a9\u0646\u0645.<\/p>\n<p>\u062f\u0631 \u06cc\u06a9 PeerConnection \u0645\u06cc \u062a\u0648\u0627\u0646\u06cc\u0645 \u062f\u0648 \u0646\u0648\u0639 \u06a9\u0627\u0646\u0627\u0644 \u060c Datachannels (\u0628\u0631\u0627\u06cc \u0627\u0646\u062a\u0642\u0627\u0644 \u062f\u0627\u062f\u0647 \u0647\u0627\u06cc \u0647\u062f\u0641 \u06a9\u0644\u06cc \u0628\u06cc\u0646 \u0647\u0645\u0633\u0627\u0644\u0627\u0646) \u0648 MediaChannels (\u0628\u0631\u0627\u06cc \u062f\u0627\u062f\u0647 \u0647\u0627\u06cc \u0631\u0633\u0627\u0646\u0647 \u0627\u06cc \u0645\u0627\u0646\u0646\u062f \u0641\u06cc\u0644\u0645\/\u0635\u0648\u062a\u06cc) \u0627\u06cc\u062c\u0627\u062f \u06a9\u0646\u06cc\u0645. MediaChannels \u0642\u0628\u0644 \u0627\u0632 \u0645\u062d\u06a9\u0645 \u0627\u062a\u0635\u0627\u0644 \u0645\u0646\u0641\u06cc \u0645\u06cc \u0634\u0648\u0646\u062f \u0627\u0645\u0627 \u067e\u0627\u0631\u062a\u0648\u0631\u0647\u0627\u06cc \u0622\u0646 \u0645\u06cc \u062a\u0648\u0627\u0646\u0646\u062f \u0628\u0627 \u0632\u0645\u0627\u0646 \u0628\u0647 \u0635\u0648\u0631\u062a \u062e\u0648\u062f\u06a9\u0627\u0631 \u06cc\u0627 \u062f\u0633\u062a\u06cc \u062a\u063a\u06cc\u06cc\u0631 \u06a9\u0646\u0646\u062f.<\/p>\n<p>\u062c\u0631\u06cc\u0627\u0646 \u0628\u0627 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 MediaChannels \u0645\u0639\u0645\u0648\u0644\u0627\u064b \u0641\u0642\u0637 \u0627\u0632 \u062c\u0639\u0628\u0647 \u062e\u0627\u0631\u062c \u0645\u06cc \u0634\u0648\u062f \u0627\u0645\u0627 \u0627\u06af\u0631 WebApp \u0634\u0645\u0627 \u0628\u0647 \u0631\u0641\u062a\u0627\u0631 \u062e\u0627\u0635\u06cc \u0646\u06cc\u0627\u0632 \u062f\u0627\u0631\u062f \u06a9\u0647 \u0628\u0627 \u067e\u06cc\u0634 \u0641\u0631\u0636 \u0645\u062a\u0641\u0627\u0648\u062a \u0628\u0627\u0634\u062f \u0645\u06cc \u062a\u0648\u0627\u0646\u06cc\u062f \u0627\u0632 \u06a9\u062f\u06a9 \u0647\u0627\u06cc \u0648\u06cc\u062f\u0626\u0648\u06cc\u06cc\/\u0635\u0648\u062a\u06cc \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u062f.<\/p>\n<p>\u06a9\u062f\u06a9 \u0647\u0627\u06cc \u0632\u06cc\u0627\u062f\u06cc \u0628\u0631\u0627\u06cc \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0647\u0633\u062a\u0646\u062f \u0627\u0645\u0627 \u0628\u0627\u06cc\u062f \u0628\u062f\u0627\u0646\u06cc\u062f \u06a9\u0647 \u0647\u0645\u0647 \u06a9\u062f\u06a9 \u0647\u0627 \u0647\u0645\u06cc\u0634\u0647 \u067e\u0634\u062a\u06cc\u0628\u0627\u0646\u06cc \u0646\u0645\u06cc \u0634\u0648\u0646\u062f (\u0622\u0646\u0647\u0627 \u0628\u0647 \u0646\u0631\u0645 \u0627\u0641\u0632\u0627\u0631\/\u0633\u062e\u062a \u0627\u0641\u0632\u0627\u0631 \u06a9\u0627\u0631\u0628\u0631 \u0648\u0627\u0628\u0633\u062a\u0647 \u0647\u0633\u062a\u0646\u062f) \u0627\u0645\u0627 \u062c\u0627\u06cc \u0646\u06af\u0631\u0627\u0646\u06cc \u0646\u06cc\u0633\u062a \u0632\u06cc\u0631\u0627 \u0645\u0646\u0641\u06cc \u06a9\u062f\u06a9 \u062a\u0648\u0633\u0637 \u0645\u0631\u0648\u0631\u06af\u0631 \u0645\u0627\u0646\u0646\u062f Magic \u0627\u0646\u062c\u0627\u0645 \u0645\u06cc \u0634\u0648\u062f. \u062f\u0631 \u0627\u06cc\u0646\u062c\u0627 \u0644\u06cc\u0633\u062a\u06cc \u0627\u0632 \u06a9\u062f\u06a9 \u0647\u0627\u06cc \u0645\u0648\u062c\u0648\u062f \u0628\u0631\u0627\u06cc Webrtc \u0631\u0627 \u062f\u0631 \u0627\u062e\u062a\u06cc\u0627\u0631 \u062f\u0627\u0631\u06cc\u062f.<\/p>\n<p>\u0628\u0631\u0627\u06cc \u06a9\u0627\u0631 \u0628\u0627 \u06a9\u062f\u06a9 \u0647\u0627 \u060c \u0628\u0647 \u0645\u062c\u0645\u0648\u0639\u0647 \u0627\u06cc \u0627\u0632 \u06a9\u062f\u06a9 \u0647\u0627\u06cc \u062a\u0631\u062c\u06cc\u062d\u06cc \u06a9\u0647 \u062f\u0631 \u062a\u0631\u062c\u06cc\u062d \u062f\u0627\u062f\u0647 \u0645\u06cc \u0634\u0648\u0646\u062f \u060c \u0646\u06cc\u0627\u0632 \u062f\u0627\u0631\u06cc\u0645. \u0633\u0627\u0628\u0642: [The codec I want the most, &#8230;, Other codecs, &#8230;, Worst codec]\u0628\u0634\u0631 \u062a\u0646\u0638\u06cc\u0645\u0627\u062a Codecs \u0628\u0627\u06cc\u062f \u062a\u0648\u0633\u0637 \u0645\u0634\u062a\u0631\u06cc \u062a\u0646\u0638\u06cc\u0645 \u0634\u0648\u062f (\u0645\u0648\u0631\u062f\u06cc \u06a9\u0647 \u0645\u06cc \u062e\u0648\u0627\u0647\u062f \u0641\u06cc\u0644\u0645\/\u0635\u0648\u062a\u06cc \u0631\u0627 \u062f\u0631\u06cc\u0627\u0641\u062a \u06a9\u0646\u062f).<\/p>\n<p>\u0627\u06a9\u0646\u0648\u0646 \u06a9\u0647 \u0627\u06cc\u0646 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u06a9\u0644\u06cc \u06a9\u0648\u0686\u06a9 \u0631\u0627 \u062f\u0631 \u0645\u0648\u0631\u062f MediaChannels \u0622\u0645\u0648\u062e\u062a\u0647 \u0627\u06cc\u062f \u060c \u0646\u0645\u0648\u0646\u0647 \u0647\u0627\u06cc\u06cc \u0631\u0627 \u0645\u0634\u0627\u0647\u062f\u0647 \u062e\u0648\u0627\u0647\u06cc\u0645 \u06a9\u0631\u062f.<\/p>\n<p>\u2b50 \u0627\u06cc\u0646 \u0646\u0645\u0648\u0646\u0647 \u0647\u0627\u06cc \u0627\u0635\u0644\u0627\u062d \u0634\u062f\u0647 \u0648 \u0633\u0627\u062f\u0647 \u0627\u0632 &#8220;<strong>\u0644\u06cc\u0628\u0631\u0647 \u0628\u0627\u0632\u06cc<\/strong>&#8220;\u0645\u062d\u0635\u0648\u0644 \u0646\u0631\u0645 \u0627\u0641\u0632\u0627\u0631\u06cc \u0645\u0646 \u06a9\u0647 \u0633\u0639\u06cc \u0645\u06cc \u06a9\u0646\u062f \u06cc\u06a9 \u0628\u0627\u0634\u062f <strong>\u062c\u0627\u06cc\u06af\u0632\u06cc\u0646 \u0628\u0631\u0627\u06cc \u0628\u0627\u0632\u06cc \u0627\u0632 \u0631\u0627\u0647 \u062f\u0648\u0631 Steam<\/strong>\u0628\u0634\u0631 \u0627\u06af\u0631 \u0639\u0644\u0627\u0642\u0647 \u0645\u0646\u062f \u0628\u0647 \u06a9\u0633\u0628 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0628\u06cc\u0634\u062a\u0631 \u062f\u0631 \u0645\u0648\u0631\u062f \u0646\u062d\u0648\u0647 \u0639\u0645\u0644\u06a9\u0631\u062f \u0622\u0646 \u0647\u0633\u062a\u06cc\u062f \u060c \u0645\u0646 \u0627\u06cc\u0646 \u0633\u0631\u06cc \u0631\u0627 \u0627\u062f\u0627\u0645\u0647 \u062e\u0648\u0627\u0647\u0645 \u062f\u0627\u062f \u060c \u0627\u0645\u0627 \u0628\u0631\u0627\u06cc \u0644\u062d\u0638\u0647 \u0627\u06cc \u067e\u0627\u06cc\u06af\u0627\u0647 \u06a9\u062f \u0631\u0627 \u0628\u0631\u0627\u06cc \u0628\u0631\u0631\u0633\u06cc \u0622\u0646 \u062e\u0648\u0627\u0647\u06cc\u062f \u062f\u0627\u0634\u062a<\/p>\n<p><\/p>\n<p>\ud83d\udcd8 \u0645\u062b\u0627\u0644 \u06a9\u062f \u0628\u0631\u0627\u06cc \u0647\u0645\u062a\u0627 \u0645\u06cc\u0632\u0628\u0627\u0646 (\u06a9\u0647 \u0635\u0641\u062d\u0647 \u0646\u0645\u0627\u06cc\u0634 \u0631\u0627 \u0628\u0647 \u0627\u0634\u062a\u0631\u0627\u06a9 \u0645\u06cc \u06af\u0630\u0627\u0631\u062f)<\/p>\n<p>\u062f\u0631 \u0627\u06cc\u0646 \u0645\u062b\u0627\u0644 \u0633\u06cc\u06af\u0646\u0627\u0644\u06cc\u0633\u0645 \u0628\u0627 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 WebSocket \u0633\u0627\u062e\u062a\u0647 \u0634\u062f\u0647 \u0627\u0633\u062a \u060c \u0645\u0646 \u0622\u0646 \u0631\u0627 WS () \u0645\u06cc \u0646\u0627\u0645\u0645 ()<\/p>\n<p>\u0628\u0639\u062f \u0647\u0645\u0647 \u0645\u0646\u0637\u0642 \u0631\u0627 \u0628\u0631\u0627\u06cc \u0645\u06cc\u0632\u0628\u0627\u0646 JS \u062e\u0648\u062f \u062e\u0648\u0627\u0647\u06cc\u0645 \u0646\u0648\u0634\u062a<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code>\n<span class=\"c1\">\/\/ PeerConnection declaration (note that you will need to specify iceServers)<\/span>\n<span class=\"kd\">let<\/span> <span class=\"nx\">peerConnection<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">peerConnection<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">RTCPeerConnection<\/span><span class=\"p\">({<\/span><span class=\"nx\">iceServers<\/span><span class=\"p\">});;<\/span>\n\n<span class=\"c1\">\/\/ This function returns the media stream generated by getDisplayMedia or<\/span>\n<span class=\"c1\">\/\/ undefined if the user rejects to share screen.<\/span>\n<span class=\"c1\">\/\/ Video and Audio properties can be objects to specify some parameters<\/span>\n<span class=\"c1\">\/\/ like resolution, frame rate, ...<\/span>\n<span class=\"k\">async<\/span> <span class=\"kd\">function<\/span> <span class=\"nf\">getDisplayMediaStream<\/span><span class=\"p\">(<\/span><span class=\"nx\">resolution<\/span><span class=\"p\">,<\/span> <span class=\"nx\">idealFrameRate<\/span> <span class=\"nx\">maxFramerate<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">try<\/span> <span class=\"p\">{<\/span>\n        <span class=\"kd\">const<\/span> <span class=\"nx\">mediastream<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nb\">navigator<\/span><span class=\"p\">.<\/span><span class=\"nx\">mediaDevices<\/span><span class=\"p\">.<\/span><span class=\"nf\">getDisplayMedia<\/span><span class=\"p\">({<\/span>\n            <span class=\"na\">video<\/span><span class=\"p\">:<\/span> <span class=\"kc\">true<\/span><span class=\"p\">,<\/span>\n            <span class=\"na\">audio<\/span><span class=\"p\">:<\/span> <span class=\"kc\">true<\/span><span class=\"p\">,<\/span>\n        <span class=\"p\">});<\/span>\n\n        <span class=\"k\">return<\/span> <span class=\"nx\">mediastream<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span> <span class=\"k\">catch <\/span><span class=\"p\">(<\/span><span class=\"nx\">e<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span> <span class=\"kc\">undefined<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n\n<span class=\"nx\">peerConnection<\/span><span class=\"p\">.<\/span><span class=\"nx\">onicecandidate<\/span> <span class=\"o\">=<\/span> <span class=\"k\">async <\/span><span class=\"p\">(<\/span><span class=\"nx\">event<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">if <\/span><span class=\"p\">(<\/span><span class=\"nx\">event<\/span><span class=\"p\">.<\/span><span class=\"nx\">candidate<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n        <span class=\"kd\">const<\/span> <span class=\"nx\">data<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span>\n            <span class=\"na\">type<\/span><span class=\"p\">:<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">candidate<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span>\n            <span class=\"na\">candidate<\/span><span class=\"p\">:<\/span> <span class=\"nx\">event<\/span><span class=\"p\">.<\/span><span class=\"nx\">candidate<\/span><span class=\"p\">.<\/span><span class=\"nf\">toJSON<\/span><span class=\"p\">(),<\/span>\n            <span class=\"na\">role<\/span><span class=\"p\">:<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">host<\/span><span class=\"dl\">'<\/span>\n        <span class=\"p\">};<\/span>\n\n        <span class=\"k\">return<\/span> <span class=\"nf\">ws<\/span><span class=\"p\">().<\/span><span class=\"nf\">send<\/span><span class=\"p\">(<\/span><span class=\"nx\">JSON<\/span><span class=\"p\">.<\/span><span class=\"nf\">stringify<\/span><span class=\"p\">(<\/span><span class=\"nx\">data<\/span><span class=\"p\">));<\/span>\n\n    <span class=\"p\">}<\/span>\n\n    <span class=\"kd\">const<\/span> <span class=\"nx\">answer<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">peerConnection<\/span><span class=\"p\">?.<\/span><span class=\"nx\">localDescription<\/span><span class=\"p\">?.<\/span><span class=\"nf\">toJSON<\/span><span class=\"p\">();<\/span>\n    <span class=\"kd\">const<\/span> <span class=\"nx\">data<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span>\n        <span class=\"na\">type<\/span><span class=\"p\">:<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">answer<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span>\n        <span class=\"nx\">answer<\/span><span class=\"p\">,<\/span>\n        <span class=\"na\">role<\/span><span class=\"p\">:<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">host<\/span><span class=\"dl\">'<\/span>\n    <span class=\"p\">};<\/span>\n\n    <span class=\"k\">return<\/span> <span class=\"nf\">ws<\/span><span class=\"p\">().<\/span><span class=\"nf\">send<\/span><span class=\"p\">(<\/span><span class=\"nx\">JSON<\/span><span class=\"p\">.<\/span><span class=\"nf\">stringify<\/span><span class=\"p\">(<\/span><span class=\"nx\">data<\/span><span class=\"p\">));<\/span>\n\n<span class=\"p\">};<\/span>\n\n<span class=\"kd\">let<\/span> <span class=\"nx\">offerArrived<\/span> <span class=\"o\">=<\/span> <span class=\"kc\">false<\/span>\n\n<span class=\"k\">async<\/span> <span class=\"kd\">function<\/span> <span class=\"nf\">onSignalArrive<\/span><span class=\"p\">(<\/span><span class=\"nx\">data<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n\n    <span class=\"kd\">const<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">type<\/span><span class=\"p\">,<\/span> <span class=\"nx\">offer<\/span><span class=\"p\">,<\/span> <span class=\"nx\">candidate<\/span><span class=\"p\">,<\/span> <span class=\"nx\">role<\/span> <span class=\"p\">}<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">JSON<\/span><span class=\"p\">.<\/span><span class=\"nf\">parse<\/span><span class=\"p\">(<\/span><span class=\"nx\">data<\/span><span class=\"p\">);<\/span>\n\n    <span class=\"k\">if <\/span><span class=\"p\">(<\/span><span class=\"nx\">role<\/span> <span class=\"o\">!==<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">client<\/span><span class=\"dl\">'<\/span><span class=\"p\">)<\/span> <span class=\"k\">return<\/span><span class=\"p\">;<\/span>\n\n    <span class=\"k\">if <\/span><span class=\"p\">(<\/span><span class=\"nx\">type<\/span> <span class=\"o\">===<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">candidate<\/span><span class=\"dl\">\"<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n        <span class=\"k\">try<\/span> <span class=\"p\">{<\/span><span class=\"nx\">peerConnection<\/span><span class=\"p\">.<\/span><span class=\"nf\">addIceCandidate<\/span><span class=\"p\">(<\/span><span class=\"nx\">candidate<\/span><span class=\"p\">)}<\/span> <span class=\"k\">catch<\/span> <span class=\"p\">{<\/span><span class=\"cm\">\/** *\/<\/span><span class=\"p\">}<\/span>\n        <span class=\"k\">return<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"k\">if <\/span><span class=\"p\">(<\/span><span class=\"nx\">type<\/span> <span class=\"o\">!==<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">offer<\/span><span class=\"dl\">'<\/span><span class=\"p\">)<\/span> <span class=\"k\">return<\/span><span class=\"p\">;<\/span>\n    <span class=\"k\">if <\/span><span class=\"p\">(<\/span><span class=\"o\">!<\/span><span class=\"nx\">offer<\/span> <span class=\"o\">||<\/span> <span class=\"nx\">offerArrived<\/span><span class=\"p\">)<\/span> <span class=\"k\">return<\/span><span class=\"p\">;<\/span>\n\n    <span class=\"k\">try<\/span> <span class=\"p\">{<\/span>\n        <span class=\"k\">await<\/span> <span class=\"nx\">peerConnection<\/span><span class=\"p\">.<\/span><span class=\"nf\">setRemoteDescription<\/span><span class=\"p\">(<\/span><span class=\"nx\">offer<\/span><span class=\"p\">);<\/span>\n    <span class=\"p\">}<\/span> <span class=\"k\">catch <\/span><span class=\"p\">(<\/span><span class=\"nx\">e<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n        <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nf\">error<\/span><span class=\"p\">(<\/span><span class=\"nx\">e<\/span><span class=\"p\">)<\/span>\n        <span class=\"k\">return<\/span>\n    <span class=\"p\">}<\/span>\n    <span class=\"nx\">offerArrived<\/span> <span class=\"o\">=<\/span> <span class=\"kc\">true<\/span><span class=\"p\">;<\/span>\n\n    <span class=\"kd\">const<\/span> <span class=\"nx\">stream<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nf\">getDisplayMediaStream<\/span><span class=\"p\">(<\/span><span class=\"nx\">resolution<\/span><span class=\"p\">,<\/span> <span class=\"nx\">idealFrameRate<\/span><span class=\"p\">,<\/span> <span class=\"nx\">maxFramerate<\/span><span class=\"p\">);<\/span>\n\n    <span class=\"c1\">\/\/ Here I add MediaStream tracks to the WebRTC Peerconnection<\/span>\n    <span class=\"nx\">stream<\/span><span class=\"p\">?.<\/span><span class=\"nf\">getTracks<\/span><span class=\"p\">().<\/span><span class=\"nf\">forEach<\/span><span class=\"p\">((<\/span><span class=\"nx\">track<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n        <span class=\"k\">if <\/span><span class=\"p\">(<\/span><span class=\"o\">!<\/span><span class=\"nx\">stream<\/span><span class=\"p\">)<\/span> <span class=\"k\">return<\/span><span class=\"p\">;<\/span>\n        <span class=\"nx\">peerConnection<\/span><span class=\"p\">?.<\/span><span class=\"nf\">addTrack<\/span><span class=\"p\">(<\/span><span class=\"nx\">track<\/span><span class=\"p\">,<\/span> <span class=\"nx\">stream<\/span><span class=\"p\">);<\/span>\n    <span class=\"p\">});<\/span>\n\n    <span class=\"k\">try<\/span> <span class=\"p\">{<\/span>\n\n        <span class=\"k\">await<\/span> <span class=\"nx\">peerConnection<\/span><span class=\"p\">.<\/span><span class=\"nf\">setLocalDescription<\/span><span class=\"p\">(<\/span><span class=\"k\">await<\/span> <span class=\"nx\">peerConnection<\/span><span class=\"p\">.<\/span><span class=\"nf\">createAnswer<\/span><span class=\"p\">());<\/span>\n\n    <span class=\"p\">}<\/span> <span class=\"k\">catch <\/span><span class=\"p\">(<\/span><span class=\"nx\">e<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n        <span class=\"nx\">console<\/span><span class=\"p\">.<\/span><span class=\"nf\">error<\/span><span class=\"p\">(<\/span><span class=\"nx\">e<\/span><span class=\"p\">)<\/span>\n        <span class=\"k\">return<\/span>\n    <span class=\"p\">}<\/span>\n\n<span class=\"p\">}<\/span>\n\n\n<span class=\"kd\">const<\/span> <span class=\"nx\">cllbck<\/span> <span class=\"o\">=<\/span> <span class=\"p\">(<\/span><span class=\"nx\">ev<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span>  <span class=\"nf\">onSignalArrive<\/span><span class=\"p\">(<\/span><span class=\"nx\">ev<\/span><span class=\"p\">.<\/span><span class=\"nx\">data<\/span><span class=\"p\">)<\/span>\n<span class=\"nf\">ws<\/span><span class=\"p\">().<\/span><span class=\"nf\">addEventListener<\/span><span class=\"p\">(<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">message<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span> <span class=\"nx\">cllbck<\/span><span class=\"p\">)<\/span>\n<span class=\"nx\">unlistenerStreamingSignal<\/span> <span class=\"o\">=<\/span> <span class=\"p\">()<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"nf\">ws<\/span><span class=\"p\">().<\/span><span class=\"nf\">removeEventListener<\/span><span class=\"p\">(<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">message<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span> <span class=\"nx\">cllbck<\/span><span class=\"p\">)<\/span>\n<span class=\"k\">return<\/span>\n\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\">\n    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"><title>\u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0631\u0627 \u0648\u0627\u0631\u062f \u06a9\u0646\u06cc\u062f<\/title>\n    <path d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"\/>\n<\/svg><\/p>\n<p>    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"><title>\u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"\/>\n<\/svg><\/p>\n<\/div>\n<\/div>\n<\/div>\n<p>\ud83d\udcd8 \u0645\u062b\u0627\u0644 \u06a9\u062f \u0628\u0631\u0627\u06cc \u0645\u0634\u062a\u0631\u06cc \u0645\u0634\u062a\u0631\u06cc (\u06a9\u0647 \u062c\u0631\u06cc\u0627\u0646 \u0648\u06cc\u062f\u06cc\u0648\/\u0635\u0648\u062a\u06cc \u0631\u0627 \u062f\u0631\u06cc\u0627\u0641\u062a \u0645\u06cc \u06a9\u0646\u062f)<\/p>\n<p>\u062f\u0631 \u0627\u06cc\u0646 \u0645\u062b\u0627\u0644 \u0633\u06cc\u06af\u0646\u0627\u0644\u06cc\u0633\u0645 \u0628\u0627 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 WebSocket \u0633\u0627\u062e\u062a\u0647 \u0634\u062f\u0647 \u0627\u0633\u062a \u060c \u0645\u0646 \u0622\u0646 \u0631\u0627 WS () \u0645\u06cc \u0646\u0627\u0645\u0645 ()<\/p>\n<p>\u0627\u0639\u0644\u0627\u0645 \u0639\u0646\u0635\u0631 \u0648\u06cc\u062f\u06cc\u0648\u06cc\u06cc HTML<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight html\"><code><span class=\"nt\"><video> <span class=\"na\">id=<\/span><span class=\"s\">\"video-streaming\"<\/span><span class=\"nt\">&gt;<\/span><\/video><\/span>\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\">\n    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"><title>\u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0631\u0627 \u0648\u0627\u0631\u062f \u06a9\u0646\u06cc\u062f<\/title>\n    <path d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"\/>\n<\/svg><\/p>\n<p>    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"><title>\u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"\/>\n<\/svg><\/p>\n<\/div>\n<\/div>\n<\/div>\n<p>\u0627\u0639\u0644\u0627\u0645 \u06a9\u062f\u06a9 \u0647\u0627\u06cc \u062a\u0631\u062c\u06cc\u062d\u06cc \u0645\u0627<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"kd\">const<\/span> <span class=\"nx\">DEFAULT_PREFERED_CODECS<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">video\/VP9<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">video\/AV1<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">video\/H264<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">video\/VP8<\/span><span class=\"dl\">\"<\/span><span class=\"p\">]<\/span>\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\">\n    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"><title>\u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0631\u0627 \u0648\u0627\u0631\u062f \u06a9\u0646\u06cc\u062f<\/title>\n    <path d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"\/>\n<\/svg><\/p>\n<p>    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"><title>\u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"\/>\n<\/svg><\/p>\n<\/div>\n<\/div>\n<\/div>\n<p>\u062a\u0631\u062a\u06cc\u0628 \u0627\u0648\u0644\u0648\u06cc\u062a: &#8220;VP9&#8221; \u060c &#8220;AV1&#8221; \u060c &#8220;H264&#8221; \u0648 &#8220;VP8&#8221; \u0627\u0633\u062a<\/p>\n<p>\u0627\u0628\u062a\u062f\u0627 \u06cc\u06a9 \u062a\u0627\u0628\u0639 \u0631\u0627 \u0628\u0631\u0627\u06cc \u062f\u0631\u06cc\u0627\u0641\u062a \u06a9\u062f\u06a9 \u0647\u0627\u06cc \u0645\u0648\u0631\u062f \u0646\u0638\u0631 \u062e\u0648\u062f \u0628\u0647 \u062a\u0631\u062a\u06cc\u0628 \u0627\u0639\u0644\u0627\u0645 \u062e\u0648\u0627\u0647\u06cc\u0645 \u06a9\u0631\u062f<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code><span class=\"c1\">\/\/ This function is a little modification of one that you can find in MDN<\/span>\n<span class=\"c1\">\/\/ docs<\/span>\n<span class=\"k\">export<\/span> <span class=\"kd\">function<\/span> <span class=\"nf\">getSortedVideoCodecs<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\n\n    <span class=\"kd\">const<\/span> <span class=\"nx\">codecs<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">RTCRtpReceiver<\/span><span class=\"p\">.<\/span><span class=\"nf\">getCapabilities<\/span><span class=\"p\">(<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">video<\/span><span class=\"dl\">\"<\/span><span class=\"p\">)?.<\/span><span class=\"nx\">codecs<\/span><span class=\"p\">;<\/span>\n\n    <span class=\"k\">if <\/span><span class=\"p\">(<\/span><span class=\"o\">!<\/span><span class=\"nx\">codecs<\/span><span class=\"p\">)<\/span> <span class=\"k\">return<\/span> <span class=\"p\">[];<\/span>\n\n    <span class=\"k\">return<\/span> <span class=\"nx\">codecs<\/span><span class=\"p\">.<\/span><span class=\"nf\">sort<\/span><span class=\"p\">((<\/span><span class=\"nx\">a<\/span><span class=\"p\">,<\/span> <span class=\"nx\">b<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n      <span class=\"kd\">const<\/span> <span class=\"nx\">indexA<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">DEFAULT_PREFERED_CODECS<\/span><span class=\"p\">.<\/span><span class=\"nx\">value<\/span><span class=\"p\">.<\/span><span class=\"nf\">indexOf<\/span><span class=\"p\">(<\/span><span class=\"nx\">a<\/span><span class=\"p\">.<\/span><span class=\"nx\">mimeType<\/span><span class=\"p\">);<\/span>\n      <span class=\"kd\">const<\/span> <span class=\"nx\">indexB<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">DEFAULT_PREFERED_CODECS<\/span><span class=\"p\">.<\/span><span class=\"nx\">value<\/span><span class=\"p\">.<\/span><span class=\"nf\">indexOf<\/span><span class=\"p\">(<\/span><span class=\"nx\">b<\/span><span class=\"p\">.<\/span><span class=\"nx\">mimeType<\/span><span class=\"p\">);<\/span>\n      <span class=\"kd\">const<\/span> <span class=\"nx\">orderA<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">indexA<\/span> <span class=\"o\">&gt;=<\/span> <span class=\"mi\">0<\/span> <span class=\"p\">?<\/span> <span class=\"nx\">indexA<\/span> <span class=\"p\">:<\/span> <span class=\"nb\">Number<\/span><span class=\"p\">.<\/span><span class=\"nx\">MAX_VALUE<\/span><span class=\"p\">;<\/span>\n      <span class=\"kd\">const<\/span> <span class=\"nx\">orderB<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">indexB<\/span> <span class=\"o\">&gt;=<\/span> <span class=\"mi\">0<\/span> <span class=\"p\">?<\/span> <span class=\"nx\">indexB<\/span> <span class=\"p\">:<\/span> <span class=\"nb\">Number<\/span><span class=\"p\">.<\/span><span class=\"nx\">MAX_VALUE<\/span><span class=\"p\">;<\/span>\n      <span class=\"k\">return<\/span> <span class=\"nx\">orderA<\/span> <span class=\"o\">-<\/span> <span class=\"nx\">orderB<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">});<\/span>\n<span class=\"p\">}<\/span>\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\">\n    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"><title>\u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0631\u0627 \u0648\u0627\u0631\u062f \u06a9\u0646\u06cc\u062f<\/title>\n    <path d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"\/>\n<\/svg><\/p>\n<p>    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"><title>\u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"\/>\n<\/svg><\/p>\n<\/div>\n<\/div>\n<\/div>\n<p>\u0648 \u0627\u06a9\u0646\u0648\u0646 \u062a\u0645\u0627\u0645 \u0645\u0646\u0637\u0642 \u0645\u0634\u062a\u0631\u06cc JS<\/p>\n<div class=\"highlight js-code-highlight\">\n<pre class=\"highlight javascript\"><code>\n<span class=\"c1\">\/\/ PeerConnection declaration (note that you will need to specify iceServers)<\/span>\n<span class=\"kd\">let<\/span> <span class=\"nx\">peerConnection<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">peerConnection<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">RTCPeerConnection<\/span><span class=\"p\">({<\/span><span class=\"nx\">iceServers<\/span><span class=\"p\">});;<\/span>\n\n<span class=\"c1\">\/\/ Get the video element<\/span>\n<span class=\"kd\">const<\/span> <span class=\"nx\">videoElement<\/span> <span class=\"o\">=<\/span> <span class=\"nb\">document<\/span><span class=\"p\">.<\/span><span class=\"nf\">getElementById<\/span><span class=\"p\">(<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">video-streaming<\/span><span class=\"dl\">\"<\/span><span class=\"p\">);<\/span>\n\n<span class=\"c1\">\/\/ Add transceiver to receive video (if you don't want codec preferences<\/span>\n<span class=\"c1\">\/\/ is not needed to declare the transceiver)<\/span>\n<span class=\"kd\">const<\/span> <span class=\"nx\">transceiver<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">peerConnection<\/span><span class=\"p\">.<\/span><span class=\"nf\">addTransceiver<\/span><span class=\"p\">(<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">video<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span> <span class=\"p\">{<\/span> <span class=\"na\">direction<\/span><span class=\"p\">:<\/span> <span class=\"dl\">\"<\/span><span class=\"s2\">recvonly<\/span><span class=\"dl\">\"<\/span> <span class=\"p\">});<\/span>\n\n<span class=\"c1\">\/\/ Set the codec preferences to the transceiver (this is the prefered<\/span>\n<span class=\"c1\">\/\/ syntax, a lot of StackOverflow answers are not updated and say that <\/span>\n<span class=\"c1\">\/\/ you must modify the raw SDP messages. These days setCodecPreferences<\/span>\n<span class=\"c1\">\/\/ is supported in almost every modern browsers)<\/span>\n<span class=\"nx\">transceiver<\/span><span class=\"p\">.<\/span><span class=\"nf\">setCodecPreferences<\/span><span class=\"p\">(<\/span><span class=\"nf\">getSortedVideoCodecs<\/span><span class=\"p\">());<\/span>\n\n<span class=\"nx\">peerConnection<\/span><span class=\"p\">.<\/span><span class=\"nx\">onicecandidate<\/span> <span class=\"o\">=<\/span> <span class=\"p\">(<\/span><span class=\"nx\">e<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n    <span class=\"k\">if <\/span><span class=\"p\">(<\/span><span class=\"o\">!<\/span><span class=\"nx\">e<\/span><span class=\"p\">.<\/span><span class=\"nx\">candidate<\/span><span class=\"p\">)<\/span> <span class=\"k\">return<\/span><span class=\"p\">;<\/span>\n\n    <span class=\"kd\">const<\/span> <span class=\"nx\">data<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span>\n        <span class=\"na\">type<\/span><span class=\"p\">:<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">candidate<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span>\n        <span class=\"na\">candidate<\/span><span class=\"p\">:<\/span> <span class=\"nx\">e<\/span><span class=\"p\">.<\/span><span class=\"nx\">candidate<\/span><span class=\"p\">.<\/span><span class=\"nf\">toJSON<\/span><span class=\"p\">(),<\/span>\n        <span class=\"na\">role<\/span><span class=\"p\">:<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">client<\/span><span class=\"dl\">'<\/span>\n    <span class=\"p\">};<\/span>\n\n    <span class=\"nf\">ws<\/span><span class=\"p\">().<\/span><span class=\"nf\">send<\/span><span class=\"p\">(<\/span><span class=\"nx\">JSON<\/span><span class=\"p\">.<\/span><span class=\"nf\">stringify<\/span><span class=\"p\">(<\/span><span class=\"nx\">data<\/span><span class=\"p\">));<\/span>\n<span class=\"p\">};<\/span>\n\n<span class=\"nx\">peerConnection<\/span><span class=\"p\">.<\/span><span class=\"nx\">ontrack<\/span> <span class=\"o\">=<\/span> <span class=\"p\">(<\/span><span class=\"nx\">ev<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"p\">{<\/span>\n\n    <span class=\"k\">if <\/span><span class=\"p\">(<\/span><span class=\"nx\">ev<\/span><span class=\"p\">.<\/span><span class=\"nx\">streams<\/span> <span class=\"o\">&amp;&amp;<\/span> <span class=\"nx\">ev<\/span><span class=\"p\">.<\/span><span class=\"nx\">streams<\/span><span class=\"p\">[<\/span><span class=\"mi\">0<\/span><span class=\"p\">])<\/span> <span class=\"p\">{<\/span>\n        <span class=\"c1\">\/\/ Setting videoElement source and automatically play video<\/span>\n        <span class=\"nx\">videoElement<\/span><span class=\"p\">.<\/span><span class=\"nx\">srcObject<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">ev<\/span><span class=\"p\">.<\/span><span class=\"nx\">streams<\/span><span class=\"p\">[<\/span><span class=\"mi\">0<\/span><span class=\"p\">];<\/span>\n        <span class=\"nx\">videoElement<\/span><span class=\"p\">.<\/span><span class=\"nf\">play<\/span><span class=\"p\">();<\/span>\n    <span class=\"p\">}<\/span> <span class=\"k\">else<\/span> <span class=\"p\">{<\/span>\n        <span class=\"k\">if <\/span><span class=\"p\">(<\/span><span class=\"o\">!<\/span><span class=\"nx\">inboundStream<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n        <span class=\"c1\">\/\/ Setting videoElement source and automatically play video<\/span>\n            <span class=\"nx\">inboundStream<\/span> <span class=\"o\">=<\/span> <span class=\"k\">new<\/span> <span class=\"nc\">MediaStream<\/span><span class=\"p\">();<\/span>\n            <span class=\"nx\">videoElement<\/span><span class=\"p\">.<\/span><span class=\"nx\">srcObject<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">inboundStream<\/span><span class=\"p\">;<\/span>\n            <span class=\"nx\">videoElement<\/span><span class=\"p\">.<\/span><span class=\"nf\">play<\/span><span class=\"p\">();<\/span>\n        <span class=\"p\">}<\/span>\n        <span class=\"c1\">\/\/ Adding the track to the MediaStream<\/span>\n        <span class=\"nx\">inboundStream<\/span><span class=\"p\">.<\/span><span class=\"nf\">addTrack<\/span><span class=\"p\">(<\/span><span class=\"nx\">ev<\/span><span class=\"p\">.<\/span><span class=\"nx\">track<\/span><span class=\"p\">);<\/span>\n<span class=\"p\">};<\/span>\n\n<span class=\"c1\">\/\/ Create the offer indicating that we want to receive audio\/video<\/span>\n<span class=\"kd\">const<\/span> <span class=\"nx\">offer<\/span> <span class=\"o\">=<\/span> <span class=\"k\">await<\/span> <span class=\"nx\">peerConnection<\/span><span class=\"p\">.<\/span><span class=\"nf\">createOffer<\/span><span class=\"p\">({<\/span>\n    <span class=\"na\">offerToReceiveAudio<\/span><span class=\"p\">:<\/span> <span class=\"kc\">true<\/span><span class=\"p\">,<\/span>\n    <span class=\"na\">offerToReceiveVideo<\/span><span class=\"p\">:<\/span> <span class=\"kc\">true<\/span><span class=\"p\">,<\/span>\n    <span class=\"na\">iceRestart<\/span><span class=\"p\">:<\/span> <span class=\"kc\">true<\/span>\n<span class=\"p\">});<\/span>\n\n<span class=\"k\">await<\/span> <span class=\"nx\">peerConnection<\/span><span class=\"p\">.<\/span><span class=\"nf\">setLocalDescription<\/span><span class=\"p\">(<\/span><span class=\"nx\">offer<\/span><span class=\"p\">);<\/span>\n\n<span class=\"kd\">const<\/span> <span class=\"nx\">data<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span>\n    <span class=\"na\">type<\/span><span class=\"p\">:<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">offer<\/span><span class=\"dl\">'<\/span><span class=\"p\">,<\/span>\n    <span class=\"na\">offer<\/span><span class=\"p\">:<\/span> <span class=\"nx\">offer<\/span><span class=\"p\">,<\/span>\n    <span class=\"na\">role<\/span><span class=\"p\">:<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">client<\/span><span class=\"dl\">'<\/span>\n<span class=\"p\">};<\/span>\n\n<span class=\"nf\">ws<\/span><span class=\"p\">().<\/span><span class=\"nf\">send<\/span><span class=\"p\">(<\/span><span class=\"nx\">JSON<\/span><span class=\"p\">.<\/span><span class=\"nf\">stringify<\/span><span class=\"p\">(<\/span><span class=\"nx\">data<\/span><span class=\"p\">));<\/span>\n\n<span class=\"k\">async<\/span> <span class=\"kd\">function<\/span> <span class=\"nf\">onSignalArrive<\/span><span class=\"p\">(<\/span><span class=\"nx\">data<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n    <span class=\"kd\">const<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">type<\/span><span class=\"p\">,<\/span> <span class=\"nx\">answer<\/span><span class=\"p\">,<\/span> <span class=\"nx\">candidate<\/span><span class=\"p\">,<\/span> <span class=\"nx\">role<\/span> <span class=\"p\">}<\/span> <span class=\"o\">=<\/span> <span class=\"nx\">JSON<\/span><span class=\"p\">.<\/span><span class=\"nf\">parse<\/span><span class=\"p\">(<\/span><span class=\"nx\">data<\/span><span class=\"p\">);<\/span>\n\n    <span class=\"k\">if <\/span><span class=\"p\">(<\/span><span class=\"nx\">role<\/span> <span class=\"o\">!==<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">host<\/span><span class=\"dl\">'<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n        <span class=\"k\">return<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n\n    <span class=\"k\">switch <\/span><span class=\"p\">(<\/span><span class=\"nx\">type<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\n        <span class=\"k\">case<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">answer<\/span><span class=\"dl\">'<\/span><span class=\"p\">:<\/span>\n            <span class=\"k\">if <\/span><span class=\"p\">(<\/span><span class=\"o\">!<\/span><span class=\"nx\">answer<\/span><span class=\"p\">)<\/span> <span class=\"k\">return<\/span><span class=\"p\">;<\/span>\n            <span class=\"k\">await<\/span> <span class=\"nx\">peerConnection<\/span><span class=\"p\">.<\/span><span class=\"nf\">setRemoteDescription<\/span><span class=\"p\">(<\/span><span class=\"nx\">answer<\/span><span class=\"p\">);<\/span>\n            <span class=\"k\">break<\/span><span class=\"p\">;<\/span>\n        <span class=\"k\">case<\/span> <span class=\"dl\">'<\/span><span class=\"s1\">candidate<\/span><span class=\"dl\">'<\/span><span class=\"p\">:<\/span>\n            <span class=\"k\">try<\/span> <span class=\"p\">{<\/span><span class=\"k\">await<\/span> <span class=\"nx\">peerConnection<\/span><span class=\"p\">.<\/span><span class=\"nf\">addIceCandidate<\/span><span class=\"p\">(<\/span><span class=\"nx\">candidate<\/span><span class=\"p\">)}<\/span> <span class=\"k\">catch<\/span> <span class=\"p\">{<\/span><span class=\"cm\">\/** *\/<\/span><span class=\"p\">}<\/span>\n            <span class=\"k\">break<\/span><span class=\"p\">;<\/span>\n    <span class=\"p\">}<\/span>\n<span class=\"p\">}<\/span>\n\n<span class=\"kd\">const<\/span> <span class=\"nx\">cllbck<\/span> <span class=\"o\">=<\/span> <span class=\"p\">(<\/span><span class=\"nx\">ev<\/span><span class=\"p\">)<\/span> <span class=\"o\">=&gt;<\/span>  <span class=\"nf\">onSignalArrive<\/span><span class=\"p\">(<\/span><span class=\"nx\">ev<\/span><span class=\"p\">.<\/span><span class=\"nx\">data<\/span><span class=\"p\">);<\/span>\n<span class=\"nf\">ws<\/span><span class=\"p\">().<\/span><span class=\"nf\">addEventListener<\/span><span class=\"p\">(<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">message<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span> <span class=\"nx\">cllbck<\/span><span class=\"p\">);<\/span>\n<span class=\"nx\">unlistenerStreamingSignal<\/span> <span class=\"o\">=<\/span> <span class=\"p\">()<\/span> <span class=\"o\">=&gt;<\/span> <span class=\"nf\">ws<\/span><span class=\"p\">().<\/span><span class=\"nf\">removeEventListener<\/span><span class=\"p\">(<\/span><span class=\"dl\">\"<\/span><span class=\"s2\">message<\/span><span class=\"dl\">\"<\/span><span class=\"p\">,<\/span> <span class=\"nx\">cllbck<\/span><span class=\"p\">);<\/span>\n\n<\/code><\/pre>\n<div class=\"highlight__panel js-actions-panel\">\n<div class=\"highlight__panel-action js-fullscreen-code-action\">\n    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"><title>\u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u0631\u0627 \u0648\u0627\u0631\u062f \u06a9\u0646\u06cc\u062f<\/title>\n    <path d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"\/>\n<\/svg><\/p>\n<p>    <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"><title>\u0627\u0632 \u062d\u0627\u0644\u062a \u062a\u0645\u0627\u0645 \u0635\u0641\u062d\u0647 \u062e\u0627\u0631\u062c \u0634\u0648\u06cc\u062f<\/title>\n    <path d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"\/>\n<\/svg><\/p>\n<\/div>\n<\/div>\n<\/div>\n<p>\u0628\u0627 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 \u0627\u06cc\u0646 \u06a9\u062f \u0645\u06cc \u062a\u0648\u0627\u0646\u06cc\u062f \u0634\u0631\u0648\u0639 \u0628\u0647 \u0627\u062c\u0631\u0627\u06cc \u0631\u0627\u0647 \u062d\u0644 \u067e\u062e\u0634 \u0648\u06cc\u062f\u06cc\u0648\u06cc\u06cc \u062e\u0648\u062f \u06a9\u0646\u06cc\u062f \u060c \u0627\u0645\u06cc\u062f\u0648\u0627\u0631\u0645 \u06a9\u0647 \u0627\u06cc\u0646 \u0622\u0645\u0648\u0632\u0634 \u06a9\u0648\u0686\u06a9 \u0631\u0627 \u062f\u0648\u0633\u062a \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u06cc\u062f. \u2764<\/p>\n<p>\u0627\u06af\u0631 \u0645\u06cc \u062e\u0648\u0627\u0647\u06cc\u062f \u0622\u0645\u0648\u0632\u0634 \u0647\u0627\u06cc \u0628\u06cc\u0634\u062a\u0631 Webrtc \u062f\u0631 \u0646\u0638\u0631\u0627\u062a \u0628\u0647 \u0645\u0646 \u0628\u06af\u0648\u06cc\u06cc\u062f \u06a9\u0647 \u0622\u0646\u0647\u0627 \u0631\u0627 \u0645\u06cc \u062e\u0648\u0627\u0646\u0645.<\/p>\n<p>\u0645\u0646\u0627\u0628\u0639 \u0627\u0637\u0644\u0627\u0639\u0627\u062a\u06cc:<\/p>\n<\/p><\/div>\n","protected":false},"excerpt":{"rendered":"<p>\u0633\u0644\u0627\u0645 \u060c \u062f\u0631 \u0627\u06cc\u0646 \u067e\u0633\u062a \u0641\u0642\u0637 \u0628\u0627 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 GetDisplayMedia () (\u0635\u0641\u062d\u0647)) \u0641\u0642\u0637 \u062a\u0646\u0638\u06cc\u0645 \u0633\u0627\u062f\u0647 Webrtc \u0631\u0627 \u067e\u0648\u0634\u0634 \u062e\u0648\u0627\u0647\u0645 \u062f\u0627\u062f \u0627\u0645\u0627 \u0628\u0631\u0627\u06cc GetUsermedia () (\u062f\u0648\u0631\u0628\u06cc\u0646 \u060c \u0645\u06cc\u06a9\u0631\u0648\u0641\u0648\u0646) \u0646\u06cc\u0632 \u0645\u0639\u062a\u0628\u0631 \u0627\u0633\u062a. \u0627\u0648\u0644 \u0627\u06af\u0631 \u062f\u0631 \u062a\u0648\u0636\u06cc\u062d\u0627\u062a\/\u0622\u0645\u0648\u0632\u0634 \u0647\u0627\u06cc WEBRTC \u0628\u06cc\u0634\u062a\u0631 \u0645\u0648\u0631\u062f \u062a\u0648\u062c\u0647 \u0642\u0631\u0627\u0631 \u06af\u0631\u0641\u062a\u0647 \u0627\u06cc\u062f \u060c \u0627\u06cc\u0646 \u0628\u062e\u0634\u06cc \u0627\u0632 \u0645\u0642\u0627\u0644\u0627\u062a \u0633\u0631\u06cc Webrtc \u0628\u0631\u0627\u06cc JavaScript \u0648 Golang \u0627\u0633\u062a (\u0627\u06cc\u0646 &hellip;<\/p>\n","protected":false},"author":2,"featured_media":103578,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"fifu_image_url":"","fifu_image_alt":"","footnotes":""},"categories":[339],"tags":[],"class_list":["post-103577","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dev"],"_links":{"self":[{"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/posts\/103577","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/comments?post=103577"}],"version-history":[{"count":0,"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/posts\/103577\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/media\/103578"}],"wp:attachment":[{"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/media?parent=103577"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/categories?post=103577"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nabfollower.com\/blog\/wp-json\/wp\/v2\/tags?post=103577"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}