در این مقاله بصورت گام به گام نحوه انتشار ویدیوی زنده با WebRTC و راه اندازی یک سیستم انتشار تصویر یک به چند (یک طرفه) آموزش داده و ضمن استفاده از فریم ورک های رایگان و متن باز، از سرور آماده ای که توسط سایت www.pubnub.com ارایه شده نیز کمک گرفته شده.

پس از اتمام این مقاله قادر خواهید بود که یک کلاس مجازی صوتی تصویری آنلاین راه اندازی کنید. پیش نیاز این آموزش تسلط بر مفاهیم frontend مانند html5,css,javascript.jqueryy میباشد. همچنین پیش از مطالعه این مطلب نیاز است که مطلب “آشنایی با WebRTC” را در همین وبسایت مطالعه فرمایید.

در این آموزش ما میخواهیم یه نرم افزار انتشار زنده ی یک به چند را با WebRTC بسازیم. به عبارت دیگر یک ارتباط یک طرفه از یک منتشر کننده به چند نمایش دهنده  همه در مرورگر رخ میدهد.

بررسی خواهیم کرد که چگونه با PubNub WebRTC SDK یک ارتباط زنده را به آسانی پیاده سازی کنیم، و از   PubNub Presence برای گرفتن تعداد نمایش دهنده ها کمک بگیریم.

در نشانی زیر میتوانید اتمام شده این پروژه را مشاهده نموده و با باز کردن چند پنجره آن را تست کنید:

http://kevingleason.me/SimpleRTC/stream.html

و برای دیدن کد پروژه به آدرس زیر بروید:

https://github.com/pubnub/SimpleRTC

در مثال های قبلی نیز نمونه های تماس تصویری با عنوان های دیگر اموزش داده شد:

 

عیب یابی و تست

اگر بخواهیم برنامه را در مرورگر بطور محلی، یعنی با آدرس file://<your-webrtc-project> اجرا کنیم ، مرور گر با اعلام خطای Cross-Origin Resource Sharing) CORS) دسترسی به وبکم و میکروفون را برایمان مسدود میکند. بنابراین یا باید از هاست واقعی و یا وب سرور محلی برنامه را تست کنیم.

 

گام نخست: ساختار فایل HTML5 ما

فایلی با نام stream.html را میسازیم و درون آن کد زیر را مینویسیم:

<div id=”vid-box”><!– Stream goes here –></div>

<form name=”streamForm” id=”stream” action=”#” onsubmit=”return stream(this);”>

    <input type=”text” name=”streamname” id=”streamname” placeholder=”Pick a stream name!” />

    <input type=”submit” name=”stream_submit” value=”Stream”>

    <div id=”stream-info”>Watching: <span id=”here-now”>0</span></div>

</form>

<form name=”watchForm” id=”watch” action=”#” onsubmit=”return watch(this);”>

<input type=”text” name=”number” placeholder=”Enter stream to join!” /><input type=”submit” value=”Watch”/>

</form>

<div id=”inStream”>

                <button id=”end” onclick=”end()”>Done</button> <br>

                Generate Embed: <button onclick=”genEmbed(400,600)”>Tall</button><button onclick=”genEmbed(600,400)”>Wide</button><button onclick=”genEmbed(500,500)”>Square</button><br>

                <div id=”embed-code”></div>

</div>

در این صفحه تعدادی ورودی و گزینه وجود دارد که به شما این امکان را میدهد که جریان(stream) محلی خود و جریان دریافتی را مشاهده نمایید. و همچنین تعداد افراد گروه انتشار را میبینیم.

– stream(form): Begin streaming video on channel in form.

– watch(form): Join the steam channel provided by the form.

– end(): Stop streaming.

– genEmbed(width,height): Generate an embeddable code for the stream.

 

گام دوم: افزودن کتابخانه های تسهیل کننده

سه کتابخانه زیر را به برنامه اضافه کنید:

  • ابتدا jQuery
  • کتابخانه PubNub JavaScript SDK برای راحت کردن فریند سیگنالینگ
  • کتابخانه PubNub WebRTC SDK و کتابخانه های SDK Wrapper که فرایند تماس را تسهیل میکنند.

<script src=”https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js”></script>

<script src=”https://cdn.pubnub.com/pubnub-3.7.14.min.js”></script>

<script src=”https://cdn.pubnub.com/webrtc/webrtc.js”></script>

<script src=”https://cdn.pubnub.com/webrtc/rtc-controller.js”></script>

 

گام سوم: انتشار جریان شما

برای آغاز انتشار جریان نخست شما باید نسبت به publish و subscribe key اقدام کنید. برای اینکار باید در سایت https://admin.pubnub.com عضو شوید و در داشبرد توسعه دهندگان نسبت به دریافت این کلید ها اقدام کنید.

گام سوم – ۱ : آماده شدن برای پخش

نخست اجازه دهید تا دارنده تصویر محلی مان را به یک جریان وصل کنید ، دارنده کد را تعبیه کنیم ، و برای بروز رسانی آماده شویم. همچنین اجازه دهید یک متغیر عمومی برای نگهداری نام جریان جاری بسازیم.

گام سوم – ۲ : انتشار و پیکربندی

حالا برای راه اندازی ارتباط انتشاری باید تابع stream را پیاده سازی کنیم. اکنون شما جریان خود را در کانال streamName قرار داده اید. اگر شما در مثال های پیش متغیر phone را به یاد داشته باشید. متوجه خواهید شد که دو متغییر oneway  و  broadcast به آن اضافه شده است. متغیر oneway به راحتی WebRTC SDK را بروی انتشار یکطرفه تنظیم میکند.

متغیر broadcast را که برابر true قرار دهیم به این معنی است که سیستم جاری انتشار دهنده است و نیاز نیست که جریان را دریافت کند. مقدار oneway هم باعث میشود که دریافت کننده گان فقط دریافت کننده باشند بنابراین نیاز به مجور دسترسی به دوربین و میکروفون ندارند.

تابع ctrl.ready دارنده یک کالبک میشود که زمانی که آماده ارسال جریان شدیم ، اجرا میشود. ابتدا دکمه و کادرمتن را تغییر رنگ ظاهری میدهیم سپس با استفاده از ctrl.addLocalStream(video_out) جریان را در تگ div با شناسه video_out قرار میدهیم. درنهایت با فراخوانی ctrl.stream اقدام به انتشار برای مشترکین میکنیم.

آخرین کاری که ما در تابع stream انجام میدهیم این است که یک اداره کننده بصورت ctrl.streamPresence(function(m){…}) بسازیم. با این کار مشترکین قادر خواهند بود که جریان منتشر شده را دریافت کنند. جریان دریافتی به راحتی در تگ div به نام here_now قرار میگیرد. برای درک کامل میتوانید به ادرس زیر مراجعه نمایید:

https://www.pubnub.com/docs/web-javascript/presence

 

گام چهارم: اتصال به جریان (Join)

اکنون ما یک کاربر فرستنده جریان (منتشر کننده) داریم ف و باید این امکان را فراهم کنیم تا سایر کاربران به این جریان وصل شوند. تابع watch یک مقدار را از ورودی html میگیرد و به آن وصل میشود.

function watch(form){

                var num = form.number.value;  // Stream to join

                var phone = window.phone = PHONE({

                    number        : “Viewer” + Math.floor(Math.random()*100), // Random name

                    publish_key   : ‘your_pub_key’, // Your Pub Key

                    subscribe_key : ‘your_sub_key’, // Your Sub Key

                    oneway        : true              // One way streaming enabled

                });

                var ctrl = window.ctrl = CONTROLLER(phone, true);

                ctrl.ready(function(){

                                ctrl.isStreaming(num, function(isOn){

                                                if (isOn) ctrl.joinStream(num);

                                                else alert(“User is not streaming!”);

                                });

                });

                ctrl.receive(function(session){

                    session.connected(function(session){ video_out.appendChild(session.video); });

                });

                ctrl.streamPresence(function(m){ here_now.innerHTML=m.occupancy; });

                return false;  // Prevent form from submitting

}

راه اندازی ابتدایی  بسیار شبیه به قبلی است اما توجه کنید که فقط از oneway استفاده کردیم که فقط دریافت کننده باشیم نه منتشر کننده.

زمانی که کنترل کننده آماده اتصال هست از ctrl.isStreaming(number, function(isStrm){}) استفاده میکند که میتوان بررسی کرد که کاربر در حال استفاده از جریان جاری هست یا خیر ، این تابع یک شماره و یک کالبک را دریافت میکند. اگر شماره در حال استفاده از جریان بود متغیر isStrm به کالبک پاس داده میشود. اگر کاربر درحال جریان است با استفاده از ctrl.joinStream به جریان وصل میشویم. نیازی به دسترسی به دوربین و میکروفون هم نیست چون ما تنها در حال دریافت جریان هستیم.

سپس با ما استفاده از  ctrl.streamPresence نسبت به بروزرسانی تعداد کاربرانی که در حال استفاده از جریان هستند، اقدام میکنیم.

گام پنجم: تعبیه پخش زنده

درنهایت ما میخواهیم برای همه مرورگر ها ، تعبیه کننده پخش زنده بسازیم. این کار به همین سادگی هست که ما یک iframe بسازیم تا محتواها خودکار به جریان زنده متصل شوند.

گام پنجم – ۱ : تولید کد تعبیه کننده

قبل از اینگه کد html اش را بنویسیم اجازه دهید که یک تابع بنویسیم که کد تعبیه را تولید کند:

function genEmbed(w,h){

                if (!streamName) return;  // If global var not set, not streaming

                var url = “http://<your-webstie>/embed.html?stream=” + streamName;

                var embed    = document.createElement(‘iframe’);

                embed.src    = url;

                embed.width  = w;

                embed.height = h;

                embed.setAttribute(“frameborder”, 0);

                embed_code.innerHTML = ‘Embed Code: ‘;

                embed_code.appendChild(document.createTextNode(embed.outerHTML));

}

گام پنجم – ۲ : نوشتن کد HTML & CSS برای تعبیه کننده

درپوشه ای که فایل stream.html قرار دارد ، فایلی به نام embed.html بسازید و کد زیر را درونش کپی کنید:

<div id=”vid-box”></div>

<div id=”stream-info”><span id=”here-now”>0</span></div>

و همچنین:

#vid-box{width: 100%;height: 100%;text-align: center;}

#vid-box video{width: 100%;height: 100%;}

#stream-info{position: absolute; bottom: 3vh; right: 5vw;}

گام پنجم – ۳ : جاوااسکریپت های محتوای قابل تعبیه

<script src=”https://cdn.pubnub.com/pubnub.min.js”></script>

<script src=”http://kevingleason.me/SimpleRTC/js/webrtc.js”></script>

<script src=”http://kevingleason.me/SimpleRTC/js/rtc-controller.js”></script>

در نهایت یک تگ اسکریپت مینویسیم که نام جریان را از پرامتر های آدرس دریافت کند و در سه بخش از تابع watch کارهای نوشته شده را انجام دهد:

ابتدا متغیر های عمومی را تعریف و سپس مطمین میشویم که کارامتر های مورد نظر در آدرس وجود دارند یا خیر:

(function(){

var urlargs     = urlparams();

var video_out   = document.getElementById(“vid-box”);

var stream_info = document.getElementById(“stream-info”);

var here_now    = document.getElementById(“here-now”);

// Handle error if stream is not in urlargs.

if (!(‘stream’ in urlargs)) {handleNoStream();return;}

// Get URL params

function urlparams() {

    var params = {};

    if (location.href.indexOf(‘?’) < 0) return params;

    PUBNUB.each(

        location.href.split(‘?’)[1].split(‘&’),

        function(data) { var d = data.split(‘=’); params[d[0]] = d[1]; }

    );

    return params;

}

function handleNoStream(){

                video_out.innerHTML=”<h2>That stream no longer exists!</h2>”;

                stream_info.hidden=true;

}

}())

توجه کنید که این کدها در یک تابع بدون نام نوشته و اجرا شده تا متغیر هافقط در حوزه خود معنی داشته باشند و در جاهای دیگر بی معنی باشند.

تابع urlparams بعد از ؟ در نوار آدرس را دریافت میکند و بصورت یک نقشه(map) ، رشته به رشته   در میاورد. سپس بررسی میکنیم که اگر کلید stream نبود تابع handleNoStream اجرا گردد.

همچنین این تابع در زمان هایی که یک کاربر دسترسی اش قطع ، یا جوین و یا انتشار پایان می یابد نیز فراخوانی میشود. به نوعی هدایت دستی خطاست که میتواند تعداد انلاین ها را بروز کند و یا پیام خطایی را نمایش دهد.در آن تابع بی نام و در زیر handleNoStream کد زیر را قرار میدهیم:

var phone = window.phone = PHONE({

    number        : “EmbedViewer” + Math.floor(Math.random()*100), // random viewer name

    publish_key   : ‘your_pub_key’, // Your Pub Key

    subscribe_key : ‘your_sub_key’, // Your Sub Key

    oneway        : true,

});

var ctrl = window.ctrl = CONTROLLER(phone);

ctrl.ready(function(){

                ctrl.isStreaming(stream, function(isOn){

                                if (isOn) ctrl.joinStream(stream);

                                else handleNoStream();

                });

});

ctrl.receive(function(session){

    session.connected(function(session){ stream_info.hidden=false; video_out.appendChild(session.video); });

    session.ended(function(session){ handleNoStream(); });

});

ctrl.streamPresence(function(m){

                here_now.innerHTML = m.occupancy;

});

ctrl.unable(function(){ handleNoStream(); });

تنها تفاوت این بلاک کد با تابع watch در گام سوم این است که ما ctrl.unable را کش کرده ایم و فراخوانی شده اگر مرورگر دارای WebRTC نبوده باشد. و session.ended فراخوانی میشود اگر انتساردهنده کار را متوقف کند. در هر صورت handleNoStream اجرا شده و پیام no stream خواهد داد.

 

منبع؛ این مقاله ترجمه و برداشت از مطالب صفحه اینترنتی زیر میباشد:

https://www.pubnub.com/blog/2015-08-27-webrtc-live-video-stream-broadcasting-from-one-to-many/

ارسال دیدگاه

نشانی ایمیل شما منتشر نخواهد شد.