WebRTC ile gerçek zamanlı iletişim

1. Giriş

WebRTC; web uygulamalarında ve yerel uygulamalarda ses, video ve verilerin gerçek zamanlı iletişimini sağlayan açık kaynak bir projesidir.

WebRTC'de çeşitli JavaScript API'leri vardır. Demoları görmek için bağlantıları tıklayın.

WebRTC'yi nerede kullanabilirim?

Firefox, Opera ve masaüstü ile Android'deki Chrome'da. WebRTC, iOS ve Android'deki yerel uygulamalarda da kullanılabilir.

Sinyal nedir?

WebRTC, akış verilerini tarayıcılar arasında iletmek için RTCPeerConnection'ı kullanır, ancak aynı zamanda, iletişimi koordine etmek ve kontrol mesajlarını göndermek için bir mekanizmaya (sinyal gönderme olarak bilinir) ihtiyaç duyar. Sinyal yöntemleri ve protokolleri, WebRTC tarafından belirtilmez. Bu codelab'de mesajlaşma için Socket.IO'yu kullanacaksınız ancak pek çok alternatifi bulunmaktadır.

STUN ve TURN nedir?

WebRTC, eşler arası çalışmak üzere tasarlanmıştır. Böylece kullanıcılar mümkün olan en doğrudan rotadan bağlanabilir. Ancak WebRTC, gerçek dünyadaki ağ iletişimleriyle başa çıkacak şekilde tasarlanmıştır: İstemci uygulamalarının NAT ağ geçitlerini ve güvenlik duvarlarını çekip çekmesi gerekir. Doğrudan bağlantının başarısız olması durumunda ise eşler arası ağ iletişimi için yedeklere ihtiyaç vardır. Bu işlemin bir parçası olarak WebRTC API'leri, bilgisayarınızın IP adresini almak için STUN sunucularını ve eşler arası iletişimin başarısız olması durumunda geçiş sunucusu olarak çalışmak için TURN sunucularını kullanır. (Gerçek dünyada WebRTC daha ayrıntılı olarak açıklanmaktadır.)

WebRTC güvenli midir?

Şifreleme tüm WebRTC bileşenleri için zorunludur ve JavaScript API'leri yalnızca güvenli kaynaklardan (HTTPS veya localhost) kullanılabilir. Sinyal mekanizmaları WebRTC standartları tarafından tanımlanmamıştır, bu nedenle güvenli protokolleri kullandığınızdan emin olmak size bağlıdır.

2. Genel Bakış

Web kameranızla video almak ve anlık görüntüler almak için bir uygulama oluşturun ve bunları WebRTC aracılığıyla eşler arası paylaşın. Bu süreçte, temel WebRTC API'lerini kullanmayı ve Node.js kullanarak bir mesajlaşma sunucusu oluşturmayı öğreneceksiniz.

Neler öğreneceksiniz?

  • Web kameranızdan video alın
  • RTCPeerConnection ile video akışı
  • RTCDataChannel ile veri akışı
  • Mesaj alışverişi için sinyal hizmeti kurma
  • Eş bağlantısı ve sinyali birleştirme
  • Fotoğraf çekip veri kanalı üzerinden paylaşın

Gerekenler

  • Chrome 47 veya sonraki sürümler
  • Chrome için Web Sunucusu veya tercih ettiğiniz kendi web sunucunuzu kullanın.
  • Örnek kod
  • Metin düzenleyici
  • Temel HTML, CSS ve JavaScript bilgisi

3. Örnek kodu alın

Kodu indirme

Git hakkında bilginiz varsa klonlayarak bu codelab'in kodunu GitHub'dan indirebilirsiniz:

git clone https://github.com/googlecodelabs/webrtc-web

Alternatif olarak, kodun .zip dosyasını indirmek için aşağıdaki düğmeyi tıklayın:

İndirilen zip dosyasını açın. Bu işlem, ihtiyacınız olan tüm kaynakların yanı sıra bu codelab'in her adımı için bir klasör içeren bir proje klasörünün (udaptive-web-media) paketini açar.

Tüm kodlama işinizi work adlı dizinde yapacaksınız.

step-nn klasörleri, bu codelab'in her adımı için tamamlanmış bir sürüm içerir. Bu platformlar referans için vardır.

Web sunucusunu yükleme ve doğrulama

Kendi web sunucunuzu kullanabilirsiniz ancak bu codelab, Chrome Web Sunucusu ile uyumlu çalışacak şekilde tasarlanmıştır. Bu uygulama henüz yüklü değilse, Chrome Web Mağazası'ndan yükleyebilirsiniz.

6ddeb4aee53c0f0e.png

Chrome için Web Sunucusu uygulamasını yükledikten sonra, yer işaretleri çubuğunda, Yeni Sekme sayfasında veya Uygulama Başlatıcı'dan Chrome Uygulamaları kısayolunu tıklayın:

1d2b4aa977ab7e24.png

Web Server simgesini tıklayın:

27fce4494f641883.png

Ardından, yerel web sunucunuzu yapılandırmanıza olanak tanıyan şu iletişim kutusunu görürsünüz:

Screen Shot 2016-02-18 at 11.48.14:00.png

KLASÖR SEÇ düğmesini tıklayın ve az önce oluşturduğunuz klasörünü seçin. Bu, Web Sunucusu URL'leri bölümündeki Web Sunucusu iletişim kutusunda vurgulanan URL aracılığıyla Chrome'daki devam eden çalışmanızı görüntülemenizi sağlar.

Seçenekler altında, aşağıda gösterildiği gibi index.html'yi otomatik olarak göster seçeneğinin yanındaki kutuyu işaretleyin:

Screen Shot 2016-02-18 at 11.56.30 AM.png

Ardından, Web Sunucusu: BAŞLADI etiketli açma/kapatma düğmesini sola ve ardından tekrar sağa kaydırarak sunucuyu durdurun ve yeniden başlatın.

Screen Shot 2016-02-18 at 12.22.18 PM.png

Şimdi, vurgulanan Web Sunucusu URL'sini tıklayarak web tarayıcınızda iş sitenizi ziyaret edin. Aşağıdaki gibi, work/index.html'ye karşılık gelen bir sayfa göreceksiniz:

18a705cb6ccc5181.png

Bu uygulamanın henüz ilgi çekici bir şey yapmadığı bellidir. Şu ana kadar web sunucunuzun düzgün bir şekilde çalıştığından emin olmak için kullandığımız iskeletten sadece küçük bir tanesinden ibarettir. Sonraki adımlarda işlevsellik ve düzen özellikleri ekleyeceksiniz.

4. Web kameranızdan video akışı gerçekleştirebilirsiniz

Neler öğreneceksiniz?

Bu adımda şunları öğreneceksiniz:

  • Web kameranızdan video akışı alın.
  • Akış oynatma işlemini değiştirme.
  • Videoyu işlemek için CSS ve SVG kullanın.

Bu adımın tam sürümünü step-01 klasöründe bulabilirsiniz.

Bir çizgi HTML...

work dizininizdeki index.html'ye bir video öğesi ve bir script öğesi ekleyin:

<!DOCTYPE html>
<html>

<head>

  <title>Realtime communication with WebRTC</title>

  <link rel="stylesheet" href="css/main.css" />

</head>

<body>

  <h1>Realtime communication with WebRTC</h1>

  <video autoplay playsinline></video>

  <script src="js/main.js"></script>

</body>

</html>

...ve birkaç JavaScript

Aşağıdakileri js klasörünüzdeki main.js'ye ekleyin:

'use strict';

// On this codelab, you will be streaming only video (video: true).
const mediaStreamConstraints = {
  video: true,
};

// Video element where stream will be placed.
const localVideo = document.querySelector('video');

// Local stream that will be reproduced on the video.
let localStream;

// Handles success by adding the MediaStream to the video element.
function gotLocalMediaStream(mediaStream) {
  localStream = mediaStream;
  localVideo.srcObject = mediaStream;
}

// Handles error by logging a message to the console with the error message.
function handleLocalMediaStreamError(error) {
  console.log('navigator.getUserMedia error: ', error);
}

// Initializes media stream.
navigator.mediaDevices.getUserMedia(mediaStreamConstraints)
  .then(gotLocalMediaStream).catch(handleLocalMediaStreamError);

Deneyin

Tarayıcınızda index.html sayfasını açın. Şuna benzer bir şey görürsünüz (web kameranızdan web kamerasıyla alınabilir):

9297048e43ed0f3d.png

İşleyiş şekli

getUserMedia() çağrısının ardından tarayıcı, kullanıcıdan kamerasına erişim izni ister (mevcut kaynak için ilk kez kamera erişimi istendiyse). Başarılı olursa srcObject özelliği aracılığıyla bir medya öğesi tarafından kullanılabilecek bir MediaStream döndürülür:

navigator.mediaDevices.getUserMedia(mediaStreamConstraints)
  .then(gotLocalMediaStream).catch(handleLocalMediaStreamError);


}
function gotLocalMediaStream(mediaStream) {
  localVideo.srcObject = mediaStream;
}

constraints bağımsız değişkeni, almak istediğiniz medyayı belirtmenize olanak tanır. Bu örnekte, ses varsayılan olarak devre dışı bırakıldığından yalnızca video özelliği:

const mediaStreamConstraints = {
  video: true,
};

Video çözünürlüğü gibi ek koşullar için kısıtlamalar kullanabilirsiniz:

const hdConstraints = {
  video: {
    width: {
      min: 1280
    },
    height: {
      min: 720
    }
  }
}

MediaTrackConstraints spesifikasyonu, tüm olası kısıtlama türlerini listeler, ancak tüm seçenekler tüm tarayıcılar tarafından desteklenmez. İstenen çözünürlük şu anda seçili olan kamera tarafından desteklenmiyorsa getUserMedia(), OverconstrainedError ile reddedilir ve kullanıcıdan kamerasına erişim izni vermesi istenmez.

getUserMedia() başarılı olursa web kamerasından video akışı, video öğesinin kaynağı olarak ayarlanır:

function gotLocalMediaStream(mediaStream) {
  localVideo.srcObject = mediaStream;
}

Bonus puanlar

  • getUserMedia() hizmetine iletilen localStream nesnesi genel kapsamda olduğundan, tarayıcı konsolundan denetleyebilirsiniz: Konsolu açın, stream yazın ve Return tuşuna basın. (Konsolu Chrome'da görüntülemek için Ctrl-Üst Karakter-J'ye veya Mac kullanıyorsanız Command-Option-J tuşlarına basın.)
  • localStream.getVideoTracks() sonucu ne döndürür?
  • localStream.getVideoTracks()[0].stop() numaralı telefonu aramayı deneyin.
  • Kısıtlamalar nesnesine bakın: Bunu {audio: true, video: true} olarak değiştirdiğinizde ne olur?
  • Video öğesinin boyutu nedir? Görüntü boyutu yerine JavaScript'ten videonun doğal boyutunu nasıl alabilirsiniz? Kontrol etmek için Chrome Geliştirici Araçları'nı kullanın.
  • Video öğesine CSS filtreleri eklemeyi deneyin. Örneğin:
video {
  filter: blur(4px) invert(1) opacity(0.5);
}
  • SVG filtreleri eklemeyi deneyin. Örneğin:
video {
   filter: hue-rotate(180deg) saturate(200%);
 }

Öğrendikleriniz

Bu adımda şunları öğreneceksiniz:

  • Web kameranızdan video alın.
  • Medya kısıtlamaları ayarlayın.
  • Video öğesiyle ilgili sorunları çözmek.

Bu adımın tam sürümünü step-01 klasöründe bulabilirsiniz.

İpuçları

  • video öğesindeki autoplay özelliğini unutmayın. Bu olmadan yalnızca tek bir kare görürsünüz.
  • getUserMedia() kısıtlaması için çok daha fazla seçenek vardır. webrtc.github.io/samples/src/content/peerconnection/constraints adresindeki demoya göz atın. Göreceğiniz gibi bu sitede çok sayıda ilginç WebRTC örneği var.

En iyi uygulama

  • Video öğenizin kapsayıcısından taşmadığından emin olun. Video için tercih edilen boyutu ve maksimum boyutu belirlemek amacıyla width ve max-width özelliklerini ekledik. Tarayıcı, yüksekliği otomatik olarak hesaplar:
video {
  max-width: 100%;
  width: 320px;
}

Sıradaki

Videonuz var, ama nasıl canlı oynatacaksınız? Cevabı sonraki adımda öğreneceksiniz.

5. RTCPeerConnection ile video akışı

Neler öğreneceksiniz?

Bu adımda şunları öğreneceksiniz:

  • WebRTC dolgusu olan adapter.js ile tarayıcı farklılıklarını soyutlayın.
  • Video akışı gerçekleştirmek için RTCPeerConnection API'yi kullanın.
  • Medya yakalama ve akışı kontrol edin.

Bu adımın tam bir versiyonu step-2 klasöründedir.

RTCPeerConnection nedir?

RTCPeerConnection, video ve ses yayını yapmak ve veri alışverişi yapmak için WebRTC çağrıları yapmaya yönelik bir API'dir.

Bu örnek, aynı sayfadaki iki RTCPeerConnection nesnesi (eşler olarak bilinir) arasında bir bağlantı oluşturur.

Pek pratik değil, ancak RTCPeerConnection'ın işleyiş şeklini anlamak için iyi bir yöntemdir.

Video öğeleri ekleme ve kontrol düğmeleri

index.html dosyasında, tek video öğesini iki video öğesi ve üç düğmeyle değiştirin:

<video id="localVideo" autoplay playsinline></video>
<video id="remoteVideo" autoplay playsinline></video>


<div>
  <button id="startButton">Start</button>
  <button id="callButton">Call</button>
  <button id="hangupButton">Hang Up</button>
</div>

Video öğelerinden biri getUserMedia() kaynağından gelen akışı gösterirken diğeri de RTCPeerConnection üzerinden yayınlanan aynı videoyu gösterir. (Gerçek hayattaki bir uygulamada, bir video öğesi yerel akışı ve diğeri uzak akışı gösterir.)

adaptör.js dolgusunu ekleyin

adapter.js'nin geçerli sürümüne ait, main.js bağlantısının üstüne bir bağlantı ekleyin:

<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>

Index.html artık şu şekilde görünmelidir:

<!DOCTYPE html>
<html>

<head>
  <title>Realtime communication with WebRTC</title>
  <link rel="stylesheet" href="css/main.css" />
</head>

<body>
  <h1>Realtime communication with WebRTC</h1>

  <video id="localVideo" autoplay playsinline></video>
  <video id="remoteVideo" autoplay playsinline></video>

  <div>
    <button id="startButton">Start</button>
    <button id="callButton">Call</button>
    <button id="hangupButton">Hang Up</button>
  </div>

  <script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
  <script src="js/main.js"></script>
</body>
</html>

RTCPeerConnection kodunu yükleme

main.js dosyasını, step-02 klasöründeki sürümle değiştirin.

Telefon et

index.html dosyasını açın, web kameranızdan video almak için Başlat düğmesini ve eş bağlantısını kurmak için Ara'yı tıklayın. Her iki video öğesinde de (web kameranızdan) aynı videoyu görmeniz gerekir. WebRTC günlük kaydını görmek için tarayıcı konsolunu görüntüleyin.

İşleyiş şekli

Bu adımın etkisi

WebRTC, eşler olarak da bilinen WebRTC istemcileri arasında video akışı bağlantısı kurmak için RTCPeerConnection API'yi kullanır.

Bu örnekte, iki RTCPeerConnection nesnesi aynı sayfadadır: pc1 ve pc2. Pek pratik değildir ama API'lerin nasıl çalıştığını göstermek için iyi bir yöntemdir.

WebRTC eşleri arasında görüşme ayarlamak üç görev içerir:

  • Aramanın her sonu için bir RTCPeerConnection oluşturun ve her sonda getUserMedia() kaynağından yerel akışı ekleyin.
  • Ağ bilgilerini alın ve paylaşın: Potansiyel bağlantı uç noktaları ICE adayları olarak bilinir.
  • Yerel ve uzak açıklamaları alın ve paylaşın: yerel medya ile ilgili meta veriler SDP biçiminde.

Aylin ve Bora'nın görüntülü sohbet ayarlamak için RTCPeerConnection'ı kullanmak istediğini varsayalım.

İlk olarak Aylin ve Bora, ağ bilgilerini birbiriyle paylaşıyor. "Adaylar bulunuyor" ifadesi ICE çerçevesini kullanarak ağ arayüzlerini ve bağlantı noktalarını bulma sürecini ifade eder.

  1. Alice, bir onicecandidate (addEventListener('icecandidate')) işleyiciyle RTCPeerConnection nesnesi oluşturur. Bu, main.js'de bulunan aşağıdaki koda karşılık gelir:
let localPeerConnection;
localPeerConnection = new RTCPeerConnection(servers);
localPeerConnection.addEventListener('icecandidate', handleConnection);
localPeerConnection.addEventListener(
    'iceconnectionstatechange', handleConnectionChange);
  1. Aylin, getUserMedia() adlı kümeyi çağırır ve bu akışa iletilen akışı ekler:
navigator.mediaDevices.getUserMedia(mediaStreamConstraints).
  then(gotLocalMediaStream).
  catch(handleLocalMediaStreamError);
function gotLocalMediaStream(mediaStream) {
  localVideo.srcObject = mediaStream;
  localStream = mediaStream;
  trace('Received local stream.');
  callButton.disabled = false;  // Enable call button.
}
localPeerConnection.addStream(localStream);
trace('Added local stream to localPeerConnection.');
  1. 1. adımdaki onicecandidate işleyicisi, ağ adayları kullanılabilir hale geldiğinde çağrılır.
  2. Aylin, serileştirilmiş aday verilerini Bulut'a gönderir. Gerçek bir uygulamada bu işlem (sinyal olarak bilinir) bir mesajlaşma hizmeti aracılığıyla gerçekleştirilir. Bunu nasıl yapacağınızı sonraki bir adımda öğreneceksiniz. Elbette bu adımda iki RTCPeerConnection nesnesi aynı sayfadadır ve harici mesajlaşmaya gerek kalmadan doğrudan iletişim kurabilir.
  3. Bora, Aylin'den bir aday mesajı aldığında, adayı uzaktaki benzer açıklamasına eklemek için addIceCandidate() adlı kişiyi arar:
function handleConnection(event) {
  const peerConnection = event.target;
  const iceCandidate = event.candidate;

  if (iceCandidate) {
    const newIceCandidate = new RTCIceCandidate(iceCandidate);
    const otherPeer = getOtherPeer(peerConnection);

    otherPeer.addIceCandidate(newIceCandidate)
      .then(() => {
        handleConnectionSuccess(peerConnection);
      }).catch((error) => {
        handleConnectionFailure(peerConnection, error);
      });

    trace(`${getPeerName(peerConnection)} ICE candidate:\n` +
          `${event.candidate.candidate}.`);
  }
}

WebRTC eşlerinin çözünürlük ve codec özellikleri gibi yerel ve uzaktan ses ve video medya bilgilerini bulması ve bunları paylaşması da gerekir. Medya yapılandırma bilgilerini gönderip almak için sinyal, SDP olarak bilinen Oturum Açıklaması Protokolü biçimini kullanarak offer ve yanıt olarak bilinen meta veri blob'ları değiştirilerek gerçekleşir:

  1. Aylin, RTCPeerConnection createOffer() yöntemini çalıştırır. Döndürülen söz, RTCSessionDescription: Ayşe'nin yerel oturum açıklaması sağlar:
trace('localPeerConnection createOffer start.');
localPeerConnection.createOffer(offerOptions)
  .then(createdOffer).catch(setSessionDescriptionError);
  1. İşlem başarılı olursa Aylin yerel açıklamayı setLocalDescription() ile belirler ve bu oturum açıklamasını, sinyal kanalı üzerinden Barış'a gönderir.
  2. Bora, Ayşe'nin ona gönderdiği açıklamayı setRemoteDescription() kullanarak uzak açıklama olarak ayarlar.
  3. Bora, RTCPeerConnection createAnswer() yöntemini çalıştırır ve Ayşe'den aldığı uzak açıklamayı bu yönteme iletir. Böylece, Alice'inkiyle uyumlu bir yerel oturum oluşturulabilir. createAnswer(), bir RTCSessionDescription: Bora tarafından yerel açıklama olarak ayarlanır ve Aylin'e gönderilir.
  4. Alice, Bulut'un oturum açıklamasını aldığında, bunu setRemoteDescription() ile uzak açıklama olarak ayarlar.
// Logs offer creation and sets peer connection session descriptions.
function createdOffer(description) {
  trace(`Offer from localPeerConnection:\n${description.sdp}`);

  trace('localPeerConnection setLocalDescription start.');
  localPeerConnection.setLocalDescription(description)
    .then(() => {
      setLocalDescriptionSuccess(localPeerConnection);
    }).catch(setSessionDescriptionError);

  trace('remotePeerConnection setRemoteDescription start.');
  remotePeerConnection.setRemoteDescription(description)
    .then(() => {
      setRemoteDescriptionSuccess(remotePeerConnection);
    }).catch(setSessionDescriptionError);

  trace('remotePeerConnection createAnswer start.');
  remotePeerConnection.createAnswer()
    .then(createdAnswer)
    .catch(setSessionDescriptionError);
}

// Logs answer to offer creation and sets peer connection session descriptions.
function createdAnswer(description) {
  trace(`Answer from remotePeerConnection:\n${description.sdp}.`);

  trace('remotePeerConnection setLocalDescription start.');
  remotePeerConnection.setLocalDescription(description)
    .then(() => {
      setLocalDescriptionSuccess(remotePeerConnection);
    }).catch(setSessionDescriptionError);

  trace('localPeerConnection setRemoteDescription start.');
  localPeerConnection.setRemoteDescription(description)
    .then(() => {
      setRemoteDescriptionSuccess(localPeerConnection);
    }).catch(setSessionDescriptionError);
}
  1. Ping!

Bonus puanlar

  1. chrome://webrtc-internals sayfasına göz atın. Bu, WebRTC istatistiklerini ve hata ayıklama verilerini sağlar. (Chrome URL'lerinin tam listesini chrome://about adresinde bulabilirsiniz.)
  2. Sayfanın stilini CSS ile değiştirin:
  • Videoları yan yana yerleştirmek.
  • Düğmeleri aynı genişlikte ve daha büyük metin kullanarak yapmak.
  • Sayfa düzeninin mobil cihazlarda çalıştığından emin olun.
  1. Chrome Geliştirici Araçları konsolunda localStream, localPeerConnection ve remotePeerConnection sayfalarına bakın.
  2. Konsolda localPeerConnectionpc1.localDescription öğesine bakın. SDP biçimi nasıl görünür?

Öğrendikleriniz

Bu adımda şunları öğreneceksiniz:

  • WebRTC dolgusu olan adapter.js ile tarayıcı farklılıklarını soyutlayın.
  • Video akışı gerçekleştirmek için RTCPeerConnection API'yi kullanın.
  • Medya yakalama ve akışı kontrol edin.
  • WebRTC çağrısı yapabilmek için medya ve ağ bilgilerini benzerler arasında paylaşın.

Bu adımın tam bir versiyonu step-2 klasöründedir.

İpuçları

  • Bu adımda öğrenecek çok şey var. RTCPeerConnection'ı daha ayrıntılı açıklayan diğer kaynakları bulmak için webrtc.org adresine göz atın. Bu sayfada, WebRTC kullanmak istiyor ancak API'leri düzenlemek istemiyorsanız JavaScript çerçeveleriyle ilgili öneriler bulabilirsiniz.
  • adapter.js GitHub deposunda adapt.js dolgusu hakkında daha fazla bilgi edinin.
  • Dünyanın en iyi görüntülü sohbet uygulamasının nasıl olduğunu öğrenmek ister misiniz? WebRTC projesinin WebRTC çağrıları için standart uygulaması olan AppRTC'ye göz atın: uygulama, kod. Arama kurulum süresi 500 ms'den az.

En iyi uygulama

  • Kodunuzu geleceğe hazırlamak için yeni Promise tabanlı API'leri kullanın ve adapter.js kullanarak bunları desteklemeyen tarayıcılarla uyumluluğu sağlayın.

Sıradaki

Bu adımda, benzerler arasında video akışı gerçekleştirmek için WebRTC'nin nasıl kullanılacağı gösterilmektedir. Ancak bu codelab'de veriler de ele alınmaktadır.

Sonraki adımda RTCDataChannel'ı kullanarak rastgele veri akışını nasıl yapacağınızı öğrenin.

6. Veri alışverişi için RTCDataChannel kullanma

Neler öğreneceksiniz?

  • WebRTC uç noktaları (eşler) arasında veri alışverişi yapma.

Bu adımın tam sürümünü step-03 klasöründe bulabilirsiniz.

HTML'nizi güncelleyin

Bu adımda, aynı sayfadaki iki textarea öğesi arasında metin göndermek için WebRTC veri kanallarını kullanırsınız. Bu pek kullanışlı değil, ancak WebRTC'nin video akışının yanı sıra veri paylaşmak için nasıl kullanılabileceğini gösterir.

Video ve düğme öğelerini index.html'den kaldırın ve bunları aşağıdaki HTML ile değiştirin:

<textarea id="dataChannelSend" disabled
    placeholder="Press Start, enter some text, then press Send."></textarea>
<textarea id="dataChannelReceive" disabled></textarea>

<div id="buttons">
  <button id="startButton">Start</button>
  <button id="sendButton">Send</button>
  <button id="closeButton">Stop</button>
</div>

Bir metin alanı metin girmek için, diğeri ise metni benzerler arasında akış olarak gösterir.

index.html artık şu şekilde görünmelidir:

<!DOCTYPE html>
<html>

<head>

  <title>Realtime communication with WebRTC</title>

  <link rel="stylesheet" href="css/main.css" />

</head>

<body>

  <h1>Realtime communication with WebRTC</h1>

  <textarea id="dataChannelSend" disabled
    placeholder="Press Start, enter some text, then press Send."></textarea>
  <textarea id="dataChannelReceive" disabled></textarea>

  <div id="buttons">
    <button id="startButton">Start</button>
    <button id="sendButton">Send</button>
    <button id="closeButton">Stop</button>
  </div>

  <script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
  <script src="js/main.js"></script>

</body>

</html>

JavaScript'inizi güncelleyin

main.js'yi step-03/js/main.js'nin içeriğiyle değiştirin.

Eşler arasında veri akışını deneyin: index.html dosyasını açın, eş bağlantısını kurmak için Başlat'a basın, soldaki textarea bölümüne metin girin ve metni WebRTC veri kanallarını kullanarak aktarmak için Gönder'i tıklayın.

İşleyiş şekli

Bu kod, kısa mesaj alışverişini etkinleştirmek için RTCPeerConnection ve RTCDataChannel'ı kullanır.

Bu adımdaki kodun büyük kısmı RTCPeerConnection örneğindekiyle aynıdır.

Yeni kodun büyük kısmı sendData() ve createConnection() işlevlerinde mevcut:

function createConnection() {
  dataChannelSend.placeholder = '';
  var servers = null;
  pcConstraint = null;
  dataConstraint = null;
  trace('Using SCTP based data channels');
  // For SCTP, reliable and ordered delivery is true by default.
  // Add localConnection to global scope to make it visible
  // from the browser console.
  window.localConnection = localConnection =
      new RTCPeerConnection(servers, pcConstraint);
  trace('Created local peer connection object localConnection');

  sendChannel = localConnection.createDataChannel('sendDataChannel',
      dataConstraint);
  trace('Created send data channel');

  localConnection.onicecandidate = iceCallback1;
  sendChannel.onopen = onSendChannelStateChange;
  sendChannel.onclose = onSendChannelStateChange;

  // Add remoteConnection to global scope to make it visible
  // from the browser console.
  window.remoteConnection = remoteConnection =
      new RTCPeerConnection(servers, pcConstraint);
  trace('Created remote peer connection object remoteConnection');

  remoteConnection.onicecandidate = iceCallback2;
  remoteConnection.ondatachannel = receiveChannelCallback;

  localConnection.createOffer().then(
    gotDescription1,
    onCreateSessionDescriptionError
  );
  startButton.disabled = true;
  closeButton.disabled = false;
}

function sendData() {
  var data = dataChannelSend.value;
  sendChannel.send(data);
  trace('Sent Data: ' + data);
}

RTCDataChannel'ın söz dizimi, send() yöntemi ve message etkinliği ile kasıtlı olarak WebSocket'e benzer.

dataConstraint kullanımına dikkat edin. Veri kanalları, farklı türde veri paylaşımına olanak tanıyacak şekilde yapılandırılabilir (ör. performanstan ziyade güvenilir yayına öncelik verme). Seçenekler hakkında daha fazla bilgiyi Mozilla Geliştirici Ağı'nda bulabilirsiniz.

Bonus puanlar

  1. SCTP ile WebRTC veri kanalları tarafından kullanılan protokol, güvenilir ve sıralı veri teslimi varsayılan olarak etkindir. RTCDataChannel'ın güvenilir veri yayını sağlaması gerektiğinde ne zaman gerekir ve bazı verileri kaybetmek anlamına gelse bile performans ne zaman daha önemli olabilir?
  2. Sayfa düzenini iyileştirmek için CSS kullanın ve "dataChannelReceive" öğesine bir yer tutucu özellik ekleyin metin alanı.
  3. Sayfayı bir mobil cihazda test edin.

Öğrendikleriniz

Bu adımda şunları öğreneceksiniz:

  • İki WebRTC eşi arasında bağlantı kurar.
  • Eşler arasında metin verileri değişimi.

Bu adımın tam sürümünü step-03 klasöründe bulabilirsiniz.

Daha fazla bilgi

Sıradaki

Aynı sayfada eşler arasında veri alışverişi yapmayı öğrendiniz. Peki bunu farklı makineler arasında nasıl yapacağınızı öğrendiniz. Öncelikle, meta veri mesajları gönderip almak için bir sinyal kanalı oluşturmanız gerekir. Sonraki adımda bunu nasıl yapacağınızı öğrenin.

7. Mesaj alışverişi için sinyal hizmeti kurma

Neler öğreneceksiniz?

Bu adımda şunları öğreneceksiniz:

  • package.json dosyasında belirtildiği gibi proje bağımlılıklarını yüklemek için npm kullanın
  • Bir Node.js sunucusu çalıştırın ve statik dosyaları sunmak için Node-static kullanın.
  • Socket.IO'yu kullanarak Node.js'de bir mesajlaşma hizmeti oluşturun.
  • Bunu kullanarak "odalar" oluşturun bir araya geliyor.

Bu adımın tam sürümünü step-04 klasöründe bulabilirsiniz.

Kavramlar

WebRTC çağrısı oluşturmak ve sürdürmek için WebRTC istemcilerinin (eşler) meta veri alışverişi yapması gerekir:

  • Aday (ağ) bilgileri.
  • Çözünürlük ve codec'ler gibi medya hakkında bilgiler sağlayan mesajları sunma ve yanıtlama.

Başka bir deyişle, ses, video veya verilerin eşler arası akışı gerçekleşmesi için önce meta veri alışverişinin yapılması gerekir. Bu sürece sinyal adı verilir.

Önceki adımlarda, gönderen ve alıcı RTCPeerConnection nesneleri aynı sayfadadır. Dolayısıyla "sinyal" meta verileri nesneler arasında iletmektir.

Gerçek dünyadaki bir uygulamada, gönderen ve alıcı RTCPeerConnections farklı cihazlardaki web sayfalarında çalışır ve meta verileri iletebilecekleri bir yönteme ihtiyacınız vardır.

Bunun için WebRTC istemcileri (eşler) arasında mesaj iletebilen bir sunucu olan sinyal sunucusu kullanırsınız. Asıl mesajlar düz metindir, yani dizeleştirilmiş JavaScript nesneleridir.

Ön koşul: Node.js'yi yükleyin

Bu codelab'in sonraki adımlarını (step-04 ile step-06 arasındaki klasörler) çalıştırmak için Node.js kullanarak localhost'ta bir sunucu çalıştırmanız gerekir.

Node.js'yi bu bağlantıdan veya tercih ettiğiniz paket yöneticisi üzerinden indirip yükleyebilirsiniz.

Yüklendikten sonra, sonraki adımlarda (npm install çalıştırma) gereken bağımlılıkları içe aktarabilir ve codelab'i yürütmek için küçük bir yerel ana makine sunucusu çalıştırabilirsiniz (node index.js çalıştıran). Bu komutlar daha sonra gerektiğinde gösterilecektir.

Uygulama hakkında

WebRTC, istemci taraflı bir JavaScript API'si kullanır ancak gerçek hayatta kullanım için hem sinyal (mesajlaşma) sunucusu hem de STUN ve TURN sunucuları gerekir. Buradan daha fazla bilgi edinebilirsiniz.

Bu adımda, mesajlaşma için Socket.IO Node.js modülünü ve JavaScript kitaplığını kullanarak basit bir Node.js sinyal sunucusu oluşturacaksınız. Node.js ve Socket.IO deneyimi faydalı olsa da kritik öneme sahip değildir; mesaj bileşenleri çok basit.

Bu örnekte, sunucu (Node.js uygulaması) index.js'de ve üzerinde çalışan istemci (web uygulaması) index.html'de uygulanmıştır.

Bu adımdaki Node.js uygulamasının iki görevi vardır.

İlk olarak bir mesaj aktarma işlevi görür:

socket.on('message', function (message) {
  log('Got message: ', message);
  socket.broadcast.emit('message', message);
});

İkinci olarak, WebRTC görüntülü sohbet "odalarını" yönetir:

if (numClients === 0) {
  socket.join(room);
  socket.emit('created', room, socket.id);
} else if (numClients === 1) {
  socket.join(room);
  socket.emit('joined', room, socket.id);
  io.sockets.in(room).emit('ready');
} else { // max two clients
  socket.emit('full', room);
}

Basit WebRTC uygulamamız, en fazla iki arkadaşınızın odayı paylaşmasına izin verir.

HTML ve JavaScript

index.html dosyasını aşağıdaki gibi güncelleyin:

<!DOCTYPE html>
<html>

<head>

  <title>Realtime communication with WebRTC</title>

  <link rel="stylesheet" href="css/main.css" />

</head>

<body>

  <h1>Realtime communication with WebRTC</h1>

  <script src="/socket.io/socket.io.js"></script>
  <script src="js/main.js"></script>
  
</body>

</html>

Bu adımda sayfada hiçbir şey görmezsiniz: Tüm günlük kaydı tarayıcı konsoluna yapılır. (Konsolu Chrome'da görüntülemek için Ctrl-Üst Karakter-J'ye veya Mac kullanıyorsanız Command-Option-J tuşlarına basın.)

js/main.js dosyasını şununla değiştirin:

'use strict';

var isInitiator;

window.room = prompt("Enter room name:");

var socket = io.connect();

if (room !== "") {
  console.log('Message from client: Asking to join room ' + room);
  socket.emit('create or join', room);
}

socket.on('created', function(room, clientId) {
  isInitiator = true;
});

socket.on('full', function(room) {
  console.log('Message from client: Room ' + room + ' is full :^(');
});

socket.on('ipaddr', function(ipaddr) {
  console.log('Message from client: Server IP address is ' + ipaddr);
});

socket.on('joined', function(room, clientId) {
  isInitiator = false;
});

socket.on('log', function(array) {
  console.log.apply(console, array);
});

Socket.IO'yu Node.js'de çalışacak şekilde ayarlama

HTML dosyasında bir Socket.IO dosyası kullandığınızı fark etmiş olabilirsiniz:

<script src="/socket.io/socket.io.js"></script>

work dizininizin en üst düzeyinde, aşağıdaki içeriklere sahip package.json adlı bir dosya oluşturun:

{
  "name": "webrtc-codelab",
  "version": "0.0.1",
  "description": "WebRTC codelab",
  "dependencies": {
    "node-static": "^0.7.10",
    "socket.io": "^1.2.0"
  }
}

Bu, Düğüm Paketi Yöneticisi'ne (npm) hangi proje bağımlılıklarının yükleneceğini bildiren bir uygulama manifestidir.

Bağımlılıkları (/socket.io/socket.io.js gibi) yüklemek için dizininizdeki komut satırı terminalinden aşağıdaki komutu çalıştırın:

npm install

Şuna benzer bir şekilde biten bir yükleme günlüğü görürsünüz:

3ab06b7bcc7664b9.png

Gördüğünüz üzere npm, package.json dosyasında tanımlanan bağımlılıkları yükledi.

work dizininizin en üst düzeyinde (js dizininde değil) yeni bir index.js dosyası oluşturun ve aşağıdaki kodu ekleyin:

'use strict';

var os = require('os');
var nodeStatic = require('node-static');
var http = require('http');
var socketIO = require('socket.io');

var fileServer = new(nodeStatic.Server)();
var app = http.createServer(function(req, res) {
  fileServer.serve(req, res);
}).listen(8080);

var io = socketIO.listen(app);
io.sockets.on('connection', function(socket) {

  // convenience function to log server messages on the client
  function log() {
    var array = ['Message from server:'];
    array.push.apply(array, arguments);
    socket.emit('log', array);
  }

  socket.on('message', function(message) {
    log('Client said: ', message);
    // for a real app, would be room-only (not broadcast)
    socket.broadcast.emit('message', message);
  });

  socket.on('create or join', function(room) {
    log('Received request to create or join room ' + room);

    var clientsInRoom = io.sockets.adapter.rooms[room];
    var numClients = clientsInRoom ? Object.keys(clientsInRoom.sockets).length : 0;

    log('Room ' + room + ' now has ' + numClients + ' client(s)');

    if (numClients === 0) {
      socket.join(room);
      log('Client ID ' + socket.id + ' created room ' + room);
      socket.emit('created', room, socket.id);

    } else if (numClients === 1) {
      log('Client ID ' + socket.id + ' joined room ' + room);
      io.sockets.in(room).emit('join', room);
      socket.join(room);
      socket.emit('joined', room, socket.id);
      io.sockets.in(room).emit('ready');
    } else { // max two clients
      socket.emit('full', room);
    }
  });

  socket.on('ipaddr', function() {
    var ifaces = os.networkInterfaces();
    for (var dev in ifaces) {
      ifaces[dev].forEach(function(details) {
        if (details.family === 'IPv4' && details.address !== '127.0.0.1') {
          socket.emit('ipaddr', details.address);
        }
      });
    }
  });

});

Komut satırı terminalinden work dizininde aşağıdaki komutu çalıştırın:

node index.js

Tarayıcınızdan localhost:8080 uygulamasını açın.

Bu URL'yi her açtığınızda bir oda adı girmeniz istenir. Aynı odaya katılmak için her seferinde aynı oda adını seçin (ör. "foo").

Yeni bir sekme sayfası açın ve localhost:8080 adresini tekrar açın. Aynı oda adını seçin.

Üçüncü bir sekmede veya pencerede localhost:8080 adresini açın. Aynı oda adını tekrar seçin.

Her bir sekmede konsolu kontrol edin: Yukarıdaki JavaScript'ten günlük kaydını görmeniz gerekir.

Bonus puanlar

  1. Hangi alternatif mesajlaşma mekanizmaları mümkün olabilir? "Net" verilerini kullanarak hangi sorunlarla WebSocket?
  2. Bu uygulamanın ölçeklendirilmesiyle ilgili ne gibi sorunlar yaşanabilir? Binlerce veya milyonlarca aynı anda oda isteğini test etmek için bir yöntem geliştirebilir misiniz?
  3. Bu uygulama, oda adı almak için bir JavaScript istemi kullanıyor. Oda adını URL'den almanın bir yolunu bulun. Örneğin, localhost:8080/foo, oda adını foo verir.

Öğrendikleriniz

Bu adımda şunları öğreneceksiniz:

  • Bundle.json dosyasında belirtilen proje bağımlılıklarını yüklemek için npm kullanın
  • Statik dosyaları depolamak için Node.js sunucusu çalıştırın.
  • socket.io kullanarak Node.js'de bir mesajlaşma hizmeti oluşturun.
  • Bunu kullanarak "odalar" oluşturun bir araya geliyor.

Bu adımın tam sürümünü step-04 klasöründe bulabilirsiniz.

Daha fazla bilgi

Sıradaki

İki kullanıcının benzer bağlantı kurmasını sağlamak için sinyalin nasıl kullanılacağını öğrenin.

8. Eş bağlantısı ve sinyali birleştirme

Neler öğreneceksiniz?

Bu adımda şunları öğreneceksiniz:

  • Node.js'de çalışan Socket.IO'yu kullanarak bir WebRTC sinyal hizmeti çalıştırın
  • Eşler arasında WebRTC meta verilerini değiş tokuş etmek için bu hizmeti kullanın.

Bu adımın tam bir versiyonu step-05 klasöründedir.

HTML ve JavaScript'i değiştirme

index.html içeriğinin içeriğini şununla değiştirin:

<!DOCTYPE html>
<html>

<head>

  <title>Realtime communication with WebRTC</title>

  <link rel="stylesheet" href="/css/main.css" />

</head>

<body>

  <h1>Realtime communication with WebRTC</h1>

  <div id="videos">
    <video id="localVideo" autoplay muted></video>
    <video id="remoteVideo" autoplay></video>
  </div>

  <script src="/socket.io/socket.io.js"></script>
  <script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
  <script src="js/main.js"></script>
  
</body>

</html>

js/main.js'yi, step-05/js/main.js'nin içeriğiyle değiştirin.

Node.js sunucusunu çalıştırma

Bu codelab'i work dizininizden uygulamıyorsanız step-05 klasörü veya mevcut çalışma klasörünüz için bağımlılıkları yüklemeniz gerekebilir. Çalışma dizininizden aşağıdaki komutu çalıştırın:

npm install

Yüklendikten sonra Node.js sunucunuz çalışmıyorsa work dizininde aşağıdaki komutu çağırarak başlatın:

node index.js

Socket.IO'yu uygulayan önceki adımda index.js sürümünü kullandığınızdan emin olun. Düğüm ve Yuva KS'si hakkında daha fazla bilgi edinmek için "Mesaj alışverişi için sinyal hizmeti kurma" bölümüne bakın.

Tarayıcınızdan localhost:8080 uygulamasını açın.

localhost:8080 adresini yeni bir sekmede veya pencerede tekrar açın. Video öğelerinden biri getUserMedia() yerel akışı, diğeri ise "uzaktan" akışını gösterir. RTCPeerlinked üzerinden video akışı gerçekleştirildi.

Tarayıcı konsolunda günlük kaydını görüntüleyin.

Bonus puanlar

  1. Bu uygulama yalnızca bire bir görüntülü sohbeti destekler. Aynı görüntülü sohbet odasını birden fazla kişinin paylaşabilmesi için tasarımı nasıl değiştirebilirsiniz?
  2. Örnekte foo oda adı sabit kodlu olarak kullanılmıştır. Diğer oda adlarını etkinleştirmek için en iyi yöntem nedir?
  3. Kullanıcılar oda adını nasıl paylaşır? Oda adlarını paylaşmaya alternatif bir yöntem oluşturmayı deneyin.
  4. Uygulamayı nasıl değiştirebilirsiniz?

Öğrendikleriniz

Bu adımda şunları öğreneceksiniz:

  • Node.js'de çalışan Socket.IO'yu kullanarak bir WebRTC sinyal hizmeti çalıştırın.
  • Eşler arasında WebRTC meta verilerini değiş tokuş etmek için bu hizmeti kullanın.

Bu adımın tam bir versiyonu step-05 klasöründedir.

İpuçları

  • WebRTC istatistikleri ve hata ayıklama verilerine chrome://webrtc-internals adresinden ulaşabilirsiniz.
  • Yerel ortamınızı kontrol edip kameranızı ve mikrofonunuzu test etmek için test.webrtc.org kullanılabilir.
  • Önbelleğe almayla ilgili tuhaf sorunlar yaşıyorsanız aşağıdakileri deneyin:
  • Ctrl tuşunu basılı tutup Yeniden Yükle düğmesini tıklayarak yenileme yapın.
  • Tarayıcıyı yeniden başlatma
  • Komut satırından npm cache clean komutunu çalıştırın.

Sıradaki

Fotoğraf çekmeyi, görüntü verilerini almayı ve bunları uzaktaki arkadaşlarınızla paylaşmayı öğrenin.

9. Fotoğraf çekip veri kanalı üzerinden paylaşın

Neler öğreneceksiniz?

Bu adımda şunları öğreneceksiniz:

  • Fotoğraf çekin ve tuval öğesini kullanarak fotoğraftaki verileri alın.
  • Uzak kullanıcıyla görüntü verilerini paylaşın.

Bu adımın tam sürümünü step-06 klasöründe bulabilirsiniz.

İşleyiş şekli

Daha önce RTCDataChannel'ı kullanarak kısa mesaj gönderip almayı öğrendiniz.

Bu adım, dosyaların tamamını paylaşmayı mümkün kılar: Bu örnekte, getUserMedia() ile çekilen fotoğraflar.

Bu adımın temel bölümleri şunlardır:

  1. Bir veri kanalı oluşturmak. Bu adımda eş bağlantısına medya akışı eklemeyeceğinizi unutmayın.
  2. Kullanıcının web kamerası video akışını getUserMedia() ile yakalayın:
var video = document.getElementById('video');

function grabWebCamVideo() {
  console.log('Getting user media (video) ...');
  navigator.mediaDevices.getUserMedia({
    video: true
  })
  .then(gotStream)
  .catch(function(e) {
    alert('getUserMedia() error: ' + e.name);
  });
}
  1. Kullanıcı Tuttur düğmesini tıkladığında, video akışından bir anlık görüntü (video karesi) alın ve bunu bir canvas öğesinde görüntüleyin:
var photo = document.getElementById('photo');
var photoContext = photo.getContext('2d');

function snapPhoto() {
  photoContext.drawImage(video, 0, 0, photo.width, photo.height);
  show(photo, sendBtn);
}
  1. Kullanıcı Gönder düğmesini tıkladığında resmi bayta dönüştürün ve bir veri kanalı üzerinden gönderin:
function sendPhoto() {
  // Split data channel message in chunks of this byte length.
  var CHUNK_LEN = 64000;
  var img = photoContext.getImageData(0, 0, photoContextW, photoContextH),
    len = img.data.byteLength,
    n = len / CHUNK_LEN | 0;

  console.log('Sending a total of ' + len + ' byte(s)');
  dataChannel.send(len);

  // split the photo and send in chunks of about 64KB
  for (var i = 0; i < n; i++) {
    var start = i * CHUNK_LEN,
      end = (i + 1) * CHUNK_LEN;
    console.log(start + ' - ' + (end - 1));
    dataChannel.send(img.data.subarray(start, end));
  }

  // send the reminder, if any
  if (len % CHUNK_LEN) {
    console.log('last ' + len % CHUNK_LEN + ' byte(s)');
    dataChannel.send(img.data.subarray(n * CHUNK_LEN));
  }
}
  1. Alıcı taraf, veri kanalı mesaj baytlarını tekrar bir resme dönüştürür ve resmi kullanıcıya gösterir:
function receiveDataChromeFactory() {
  var buf, count;

  return function onmessage(event) {
    if (typeof event.data === 'string') {
      buf = window.buf = new Uint8ClampedArray(parseInt(event.data));
      count = 0;
      console.log('Expecting a total of ' + buf.byteLength + ' bytes');
      return;
    }

    var data = new Uint8ClampedArray(event.data);
    buf.set(data, count);

    count += data.byteLength;
    console.log('count: ' + count);

    if (count === buf.byteLength) {
      // we're done: all data chunks have been received
      console.log('Done. Rendering photo.');
      renderPhoto(buf);
    }
  };
}

function renderPhoto(data) {
  var canvas = document.createElement('canvas');
  canvas.width = photoContextW;
  canvas.height = photoContextH;
  canvas.classList.add('incomingPhoto');
  // trail is the element holding the incoming images
  trail.insertBefore(canvas, trail.firstChild);

  var context = canvas.getContext('2d');
  var img = context.createImageData(photoContextW, photoContextH);
  img.data.set(data);
  context.putImageData(img, 0, 0);
}

Kodu alın

work klasörünüzün içeriğini step-06'nın içeriğiyle değiştirin. work dosyasındaki index.html dosyanız artık şu şekilde görünmelidir**:**

<!DOCTYPE html>
<html>

<head>

  <title>Realtime communication with WebRTC</title>

  <link rel="stylesheet" href="/css/main.css" />

</head>

<body>

  <h1>Realtime communication with WebRTC</h1>

  <h2>
    <span>Room URL: </span><span id="url">...</span>
  </h2>

  <div id="videoCanvas">
    <video id="camera" autoplay></video>
    <canvas id="photo"></canvas>
  </div>

  <div id="buttons">
    <button id="snap">Snap</button><span> then </span><button id="send">Send</button>
    <span> or </span>
    <button id="snapAndSend">Snap &amp; Send</button>
  </div>

  <div id="incoming">
    <h2>Incoming photos</h2>
    <div id="trail"></div>
  </div>

  <script src="/socket.io/socket.io.js"></script>
  <script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
  <script src="js/main.js"></script>

</body>

</html>

Bu codelab'i work dizininizden uygulamıyorsanız step-06 klasörü veya mevcut çalışma klasörünüz için bağımlılıkları yüklemeniz gerekebilir. Çalışma dizininizde şu komutu çalıştırmanız yeterlidir:

npm install

Yüklendikten sonra Node.js sunucunuz çalışmıyorsa work dizininizden aşağıdaki komutu çağırarak başlatın:

node index.js

Socket.IO'yu uygulayan index.js sürümünü kullandığınızdan emin olun ve değişiklik yaparsanız Node.js sunucunuzu yeniden başlatmayı unutmayın. Düğüm ve Yuva KS'si hakkında daha fazla bilgi edinmek için "Mesaj alışverişi için sinyal hizmeti kurma" bölümüne bakın.

Gerekirse uygulamanın web kameranızı kullanmasına izin vermek için İzin ver düğmesini tıklayın.

Uygulama, rastgele bir oda kimliği oluşturur ve bu kimliği URL'ye ekler. Adres çubuğundaki URL'yi yeni bir tarayıcı sekmesinde veya penceresinde açın.

Snap ve Gönder düğmesini tıklayın ve sayfanın en altında bulunan diğer sekmede bulunan Gelen alanına bakın. Uygulama, sekmeleri sekmeler arasında aktarır.

Aşağıdakine benzer bir tablo görürsünüz:

911b40f36ba6ba8.png

Bonus puanlar

  1. Kodu, her dosya türünün paylaşılmasını sağlayacak şekilde nasıl değiştirebilirsiniz?

Daha fazla bilgi

  • MediaStream Image Capture API: Fotoğraf çekmek ve kameraları kontrol etmek için kullanılan bir API; yakında yakınınızdaki bir tarayıcıda kullanıma sunulacak!
  • Ses ve video kaydı için MediaRecorder API: demo, belgeler.

Öğrendikleriniz

  • Tuval öğesini kullanarak fotoğraf çekme ve fotoğraftaki verileri alma.
  • Bu verilerin uzak bir kullanıcıyla nasıl paylaşılacağı.

Bu adımın tam sürümünü step-06 klasöründe bulabilirsiniz.

10. Tebrikler

Gerçek zamanlı video akışı ve veri alışverişi yapmak için bir uygulama geliştirdiniz.

Öğrendikleriniz

Bu codelab'de şunları öğrendiniz:

  • Web kameranızdan video alın.
  • RTCPeerConnection ile video izleyin.
  • RTCDataChannel ile veri akışı gerçekleştirebilirsiniz.
  • Mesaj alışverişi için sinyal hizmeti kurun.
  • Eş bağlantısı ve sinyali birleştirin.
  • Fotoğraf çekip veri kanalı üzerinden paylaşın.

Sonraki adımlar

Daha fazla bilgi

  • webrtc.org adresinde WebRTC'yi kullanmaya başlamak için çeşitli kaynaklar mevcuttur.