ASP.NET MVC 4 ile OpenTok API Version 2.0 Kullanımı

Uzun bir süredir, live video streaming (canlı video yayını)’i bir ücretsiz bir media server üzerinde nasıl kullanabileceğimi araştırıyordum ve OpenTok API ile tanıştım. Amacım OpenTok API’yi kullanarak şu an çalıştığım bir ASP.NET MVC 4 projesinde live video streaming gerçekleştirebilmekti. Uzun arayışlarım sonucunda ne yazıkki hiçbir tutorial’a rastlayamadım ve en sonunda kendim bir tane yazmak istedim. Bu yazımda ASP.NET MVC 4, JavaScript ve OpenTok API kullanarak nasıl bir live video streaming web sayfası geliştirmeyi anlatıcam.

Bu yazıda ilerlemeden önce lütfen aşağıdaki gereksinimleri sağladığınızdan emin olunuz.

Visual Studio 2012 veya Visual Studio 2010 bu linki takip ediniz.

OpenTok .NET API

Ben yazımda Visual Studio 2012 kullanıcam.

1. Yeni Proje Başalatınız

Adsız

2. Açılan pencereden ASP.NET MVC4 Web Application’ı seçerek, projenize dilediğiniz adı verebilirsiniz.

3. Ok dedikten sonra karşınıza Project Template penceresi açılacaktır.

Adsız2

4. Bu pencereden Internet Application’ı ve View Engine olarakta Razor’ı seçerek Ok’e basın.

5. Projemizi oluşturduktan sora sıra geldi Web.Config dosyasında yapıcağımız ayarlara, öncelikle kullanacağımız database için connection string’imizi ayarlayarak başlayalım.

<add name="SessionsEntities" connectionString="Data Source=|Data Directory|Session.sdf" providerName="System.Data.SqlServerCe.4.0" />

6. Şimdi yapmamız gereken ise OpenTok API için gerekli olan ayarlamaları yapmaya. Öncelikle bunu yapmak için OpenTok web sayfasına giderek kayıt olmanız gerekmektedir. Sayfaya kayıt olduktan sonra TokBox size bir Api Key ve Secret verecektir.
7. Sırada web.config dosyamızda OpenTok API’yi ayarlamaya geldi

  <appSettings>
    <add key="opentok_key" value="***API Key***" />
    <add key="opentok_secret" value="***API Secret***" />
    <add key="opentok_server" value="https://api.opentok.com" />
    <add key="opentok_token_sentinel" value="T1==" />
    <add key="opentok_sdk_version" value="tbdotnet" />
  </appSettings>

8. Gerekli ayarlamalarımızıda yaptıktan sonra artık geliştirmeye başlayabiliriz.
9. Projenize sağ tıklayıp Add->Existing Item’ı seçiniz.
10. Daha önceden bu adresten indirmiş olduğunuz .NET API’yi seçerek projenize ekleyeniz.
11. API’yi projeye ekledikten sonra artık Model’imizi oluşturabiliriz.
12. Yine Models klasörüne sağ tıklayarak Add->Class’ı seçerek iki yeni class oluşturunuz, ve ilkini Sessions olarak diğerinide SessionsEntities olarak adlandırınız.
13. Şimdi Sessions classına girerek aşağıdaki modeli oluşturunuz.

public class Sessions
 {
 [Key]
 public int SessionId { get; set; }
 public string SessionName { get; set; }
 public string SessionToken { get; set; }
 }

Bu modelimizde SessionId veritabanımız için gerekli olan primary key iken, SessionName ve SessionToken ise OpenTok APIile oluşturacağınız sessionları ve tokenları tutacak olan alandır.

14. SessionEntities Class’ına girerek oluşturduğunuz tablonun DbContext’ini aşağıdaki gibi yaratın.


public class SessionEntities:DbContext
 {
 public DbSet<Sessions> SessionList { get; set; }
 }

15. Sıra geldi Controllerımızı oluşturmaya, Controllers klasörüne sağ tıklayıp Add->Controller’ı seçin ve aşağıdaki resimde görüldüğü gibi gerekli ayarlamaları gerçekleştirin.

Adsız3

16. Bu aşamada Create(Sessions sessions) POST methodunda bir değişiklik yapmaya gerek olmaktadır. Bunun yerine Create GET methodu üzerinde aşağıdaki değişikliği gerçekleştiriniz.


public ActionResult Create()
{
Sessions sessions = new Sessions();
OpenTokSDK opentok = new OpenTokSDK();
string sessionId = opentok.CreateSession(Request.ServerVariables["REMOTE_ADDR");
string token = opentok.GenerateToken(sessionId);

sessions.SessionName = sessionId;
sessions.SessionToken = token;

db.SessionList.Add(sessions);
db.SaveChanges();

return View(sessions);
}

17. Controllerımızı’da ayarladıktan sonra, Şimdi View’larımız üzerindeki değişikliklerimizide yaparak projemizi bitirelim.

Bu aşamada Views->Sessions->Create.cshtml view’ını açalım.
Kod aşağıdaki gibidir.

@model OpenTokTest.Models.Sessions

@{
    ViewBag.Title = "Create";
}
<script src="http://static.opentok.com/v1.1/js/TB.min.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" charset="utf-8">
 var apiKey = "23153492"; // Replace with your API key. See https://dashboard.tokbox.com/projects
 var sessionId = '@Ajax.JavaScriptStringEncode(Model.SessionName)'; // Replace with your own session ID. See https://dashboard.tokbox.com/projects
 var token = "@Ajax.JavaScriptStringEncode(Model.SessionToken)"; // Replace with a generated token. See https://dashboard.tokbox.com/projects

var session;
 var publisher;
 var subscribers = {};
 var VIDEO_WIDTH = 320;
 var VIDEO_HEIGHT = 240;

TB.addEventListener("exception", exceptionHandler);

// Un-comment the following to set automatic logging:
 // TB.setLogLevel(TB.DEBUG);

if (TB.checkSystemRequirements() != TB.HAS_REQUIREMENTS) {
 alert("You don't have the minimum requirements to run this application."
 + "Please upgrade to the latest version of Flash.");
 } else {
 session = TB.initSession(sessionId); // Initialize session

// Add event listeners to the session
 session.addEventListener('sessionConnected', sessionConnectedHandler);
 session.addEventListener('sessionDisconnected', sessionDisconnectedHandler);
 session.addEventListener('connectionCreated', connectionCreatedHandler);
 session.addEventListener('connectionDestroyed', connectionDestroyedHandler);
 session.addEventListener('streamCreated', streamCreatedHandler);
 session.addEventListener('streamDestroyed', streamDestroyedHandler);
 }
 function connect() {
 session.connect(apiKey, token);
 }

function disconnect() {
 session.disconnect();
 hide('disconnectLink');

 }
 function startPublishing() {
 if (!publisher) {
 var parentDiv = document.getElementById("myCamera");
 var publisherDiv = document.createElement('div'); // Create a div for the publisher to replace
 publisherDiv.setAttribute('id', 'opentok_publisher');
 parentDiv.appendChild(publisherDiv);
 var publisherProps = { width: VIDEO_WIDTH, height: VIDEO_HEIGHT };
 publisher = TB.initPublisher(apiKey, publisherDiv.id, publisherProps); // Pass the replacement div id and properties
 session.publish(publisher);
 show('unpublishLink');
 hide('publishLink');
 }
 }

function stopPublishing() {
 if (publisher) {
 session.unpublish(publisher);
 }
 publisher = null;

show('publishLink');
 hide('unpublishLink');
 }

function sessionConnectedHandler(event) {
 // Subscribe to all streams currently in the Session
 for (var i = 0; i < event.streams.length; i++) {
 addStream(event.streams[i]);
 }
 show('disconnectLink');
 startPublishing();
 hide('connectLink');
 }

function streamCreatedHandler(event) {
 // Subscribe to the newly created streams
 for (var i = 0; i < event.streams.length; i++) {
 addStream(event.streams[i]);
 }
 }

function streamDestroyedHandler(event) {
 // This signals that a stream was destroyed. Any Subscribers will automatically be removed.
 // This default behaviour can be prevented using event.preventDefault()
 }

function sessionDisconnectedHandler(event) {
 // This signals that the user was disconnected from the Session. Any subscribers and publishers
 // will automatically be removed. This default behaviour can be prevented using event.preventDefault()
 publisher = null;

show('connectLink');
 stopPublishing();
 }

function connectionDestroyedHandler(event) {
 // This signals that connections were destroyed
 }

function connectionCreatedHandler(event) {
 // This signals new connections have been created.
 }

/*
 If you un-comment the call to TB.setLogLevel(), above, OpenTok automatically displays exception event messages.
 */
 function exceptionHandler(event) {
 alert("Exception: " + event.code + "::" + event.message);
 }
 function addStream(stream) {
 // Check if this is the stream that I am publishing, and if so do not publish.
 if (stream.connection.connectionId == session.connection.connectionId) {
 return;
 }
 var subscriberDiv = document.createElement('div'); // Create a div for the subscriber to replace
 subscriberDiv.setAttribute('id', stream.streamId); // Give the replacement div the id of the stream as its id.
 document.getElementById("subscribers").appendChild(subscriberDiv);
 var subscriberProps = { width: VIDEO_WIDTH, height: VIDEO_HEIGHT };
 subscribers[stream.streamId] = session.subscribe(stream, subscriberDiv.id, subscriberProps);
 }

function show(id) {
 document.getElementById(id).style.display = 'block';
 }

function hide(id) {
 document.getElementById(id).style.display = 'none';
 }
</script>
<h2>Create</h2>

<div>
    <input type="button" value="Connect" id="connectLink" onclick="javascript: connect()" />
    <input type="button" value="Leave" id="disconnectLink" onclick="javascript: disconnect()" />
</div>
<div id="myCamera" class="publisherContainer"></div>
<div id="subscribers"></div>
<script type="text/javascript" charset="utf-8">
    show('connectLink');
</script>
<div>
    @Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

Kodda kullanılan JavaScript OpenTok API Basic Tutorial’dan alınmıştır.
18. Şu ana kadar yeni bir stream yayına başlamayı gerçekleştirdik. Sıra geldi yayında olan bir stream’e katılmaya.
Views->Sessions->Details.cshtml view’ını açarak aşağıdaki düzenlemeyi yapınız. Burdaki JavaScript Koduda yine OpenTok API Basic Tutorial’dan alınmıştır.

@model OpenTokTest.Models.Sessions

@{
    ViewBag.Title = "Details";
}
<script src="http://static.opentok.com/v1.1/js/TB.min.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" charset="utf-8">
 var apiKey = "apiKey";
 var sessionId = '@Ajax.JavaScriptStringEncode(Model.SessionName)';
 var token = '@Ajax.JavaScriptStringEncode(Model.SessionToken)';

var session;
 var publisher;
 var subscriber = {};
 var VIDEO_WIDTH = 320;
 var VIDEO_HEIGHT = 240;

TB.addEventListener("exception", exceptionHandler);

if (TB.checkSystemRequirements() != TB.HAS_REQUIREMENTS) {
 alert("You don't have the minimum requirements to run this application."
 + "Please upgrade to the latest version of Flash.");
 }
 else {
 session = TB.initSession(sessionId);
 session.addEventListener("sessionConnected", sessionConnectedHandler);
 session.addEventListener("sessionDisconnected", sessionDisconnectedHandler);
 session.addEventListener("connectionCreated", connectionCreatedHandler);
 session.addEventListener("connectionDestroyed", connectionDestroyedHandler);
 session.addEventListener('streamCreated', streamCreatedHandler);
 session.addEventListener('streamDestroyed', streamDestroyedHandler);
 }
 function connect() {
 session.connect(apiKey, token);
 }
 function disconnect() {
 session.disconnect();
 hide("disconnectLink");
 }

function sessionConnectedHandler(event) {
 for (var i = 0; i < event.streams.length; i++) {
 addStream(event.streams[i]);
 }
 show("disconnectLink");
 hide("connectLink");
 }
 function streamCreatedHandler(event) {
 // Subscribe to the newly created streams
 for (var i = 0; i < event.streams.length; i++) {
 addStream(event.streams[i]);
 }
 }
 function streamDestroyedHandler(event) {
 // This signals that a stream was destroyed. Any Subscribers will automatically be removed.
 // This default behaviour can be prevented using event.preventDefault()
 }
 function sessionDisconnectedHandler(event) {
 // This signals that the user was disconnected from the Session. Any subscribers and publishers
 // will automatically be removed. This default behaviour can be prevented using event.preventDefault()
 publisher = null;

show('connectLink');
 hide('disconnectLink');
 hide('publishLink');
 hide('unpublishLink');
 }
 function connectionDestroyedHandler(event) {
 // This signals that connections were destroyed
 }

function connectionCreatedHandler(event) {
 // This signals new connections have been created.
 }

/*
 If you un-comment the call to TB.setLogLevel(), above, OpenTok automatically displays exception event messages.
 */
 function exceptionHandler(event) {
 alert("Exception: " + event.code + "::" + event.message);
 }
 function addStream(stream) {
 // Check if this is the stream that I am publishing, and if so do not publish.
 if (stream.connection.connectionId == session.connection.connectionId) {
 return;
 }
 var subscriberDiv = document.createElement('div'); // Create a div for the subscriber to replace
 subscriberDiv.setAttribute('id', stream.streamId); // Give the replacement div the id of the stream as its id.
 document.getElementById("subscribers").appendChild(subscriberDiv);
 var subscriberProps = { width: VIDEO_WIDTH, height: VIDEO_HEIGHT };
 subscribers[stream.streamId] = session.subscribe(stream, subscriberDiv.id, subscriberProps);
 }

function show(id) {
 document.getElementById(id).style.display = 'block';
 }

function hide(id) {
 document.getElementById(id).style.display = 'none';
 }
</script>
<h2>Details</h2>

<fieldset>
    <legend>Sessions</legend>

    <div class="display-label">
        @Html.DisplayNameFor(model => model.SessionName)
    </div>
    <div class="display-field">
        @Html.DisplayFor(model => model.SessionName)
    </div>
</fieldset>
<p>
    <input type="button" value="Connect" id="connectLink" onclick="javascript:connect()" />
    <input type="button" value="Leave" id="disconnectLink" onclick="javascript: disconnect()" />
</p>
<div id="myCamera" class="publisherContainer"></div>
<div id="subscribers"></div>
<script type="text/javascript" charset="utf-8">
    show('connectLink');
</script>

19. Projemizi şu an tamamlamış bulunmaktayız. Test etmek için F5’e basarak tarayıcınızda projeyi çalıştırınız ve adres satırında http://localhost:port_No/OpenTokAPITest/Sessions gerekli düzenlemeyi yaparak test işlemini gerçekleştiriniz.

Bu projeyi hazırlarken herhangi bir kodlama tekniği kullanmadım. Gereksiz kod olabilir, isteyenler bunu dahada geliştirip kullanabilirler.

Teşekkürler,

Yukarıdaki kodun bitmiş halini burdan indirebilirsiniz.

logo_sky

 

Reklamlar