sgcWebRTC: Delphi ve C++ Builder için Yerel bir WebRTC Medya Motoru

· Bileşenler
sgcWebRTC, Delphi ve C++ Builder için yerel bir WebRTC medya motoru

sgcWebRTC, uygulamanıza eksiksiz bir WebRTC motoru ekleyen, Delphi ve C++ Builder için yeni bir pakettir: gerçek SDP teklif/yanıt sinyalleşmesi, STUN ve TURN ile ICE bağlanabilirliği, DTLS-SRTP ile şifrelenmiş taşıma, SCTP veri kanalları ve Opus, G.711, VP8 ve H.264 ile ses ve video izleri.

Saf Object Pascal olarak çalışır. Süreç içinde gömülü bir Chromium, TWebBrowser veya TEdgeBrowser denetimi ya da JavaScript köprüsü yoktur. Delphi üzerinden WebRTC kullanmanın diğer çoğu yolundan farkı budur, çünkü onlar bir tarayıcı motorunu barındırıp JavaScript yığınını Pascal tarafından sürerek çalışır. Burada eşler arası bağlantı, doğrudan işletim sistemini çağıran derlenmiş koddur, bu yüzden Android ve iOS üzerinde de, başsız bir Windows hizmetinin içinde ya da hiç tarayıcı kurulu olmayan bir kiosk cihazında da çalışır.

sgcWebRTC, sgcWebSockets Enterprise için bir eklentidir ve All-Access paketine dahildir.

Tek Bileşen, Eşler Arası Bağlantının Tamamı

sgcWebRTC palete yeni bileşenler eklemez. sgcWebSockets Enterprise ile zaten gelen aynı TsgcRTCPeerConnection sınıfı üzerindeki W3C biçimli yüzeyin geri kalanının kilidini açar. Enterprise size bu bileşeni ICE ve TURN bağlanabilirliği için ve bir WebSocket aktarıcısı üzerinden sinyalleşme için verir. sgcWebRTC bunun üzerine SDP durum makinesini, SCTP birlikteliğini, RTP oturumlarını ve SRTP şifrelemesini ekler, böylece tek bir nesne sinyalleşmenin, bağlanabilirliğin, şifrelemenin, veri kanallarının ve medyanın sahibi olur.

Eşler arası bir bağlantı dört adımda kurulur. Önce sinyalleşme, burada iki eş, halihazırda sahip olduğunuz bir kanal üzerinden oturum tanımlarını değiş tokuş eder. Sonra bağlanma, burada ICE hangi adres ve bağlantı noktasının karşı tarafa gerçekten ulaşabildiğini belirler. Sonra güvenceye alma, burada seçilen aday çifti üzerinde yapılan bir DTLS el sıkışması SRTP anahtarlarını türetir. Ve son olarak iletişim, burada veri ve medya, arada hiçbir sunucu olmadan doğrudan eşler arasında akar.

Sinyalleşme: Gerçek SDP, Böylece Karşı Eş Bir Tarayıcı Olabilir

CreateOffer, CreateAnswer, SetLocalDescription, SetRemoteDescription ve AddIceCandidate, RFC 8829 belgesindeki JSEP durum makinesini izleyerek standart SDP üretir ve tüketir. Karşı uçtaki eş başka bir Delphi uygulaması, bir mobil uygulama veya bir tarayıcı sekmesi olabilir. Tanımı ve adayları dilediğiniz sinyalleşme kanalı üzerinden taşırsınız, bir WebSocket, bir HTTP uç noktası veya bir mesaj kuyruğu, tıpkı bir tarayıcı uygulamasının bunları kendi sinyalleşme sunucusu üzerinden taşıdığı gibi.

Bu, teklif veren taraftır. Bir ICE sunucusu ayarlayın, iki sinyalleşme olayını bağlayın, bir veri kanalı açın ve ardından teklifi oluşturun.

uses
  sgcP2P;

var
  oRTC: TsgcRTCPeerConnection;
begin
  oRTC := TsgcRTCPeerConnection.Create(nil);

  oRTC.RTCOptions.ICEServers.AddURL('stun:stun.l.google.com:19302');

  oRTC.OnLocalDescription := OnLocalDescriptionHandler;
  oRTC.OnICECandidate := OnICECandidateHandler;
  oRTC.OnConnectionStateChange := OnConnectionStateChangeHandler;
  oRTC.OnDataChannel := OnDataChannelHandler;

  oRTC.TrickleICE := True;

  oRTC.CreateDataChannel('chat'); // forces RTCOptions.DTLS on
  oRTC.CreateOffer;               // gathers candidates and builds the SDP offer
end;

procedure TForm1.OnLocalDescriptionHandler(Sender: TObject;
  const aType, aSDP: string);
begin
  // aType is 'offer' or 'answer'. Send both fields to the remote peer
  // over your own signalling channel.
  MySignalling.SendDescription(aType, aSDP);
end;

procedure TForm1.OnICECandidateHandler(Sender: TObject;
  const aCandidate, aSdpMid: string; aSdpMLineIndex: Integer);
begin
  // With TrickleICE on, candidates arrive one by one while the offer
  // is already on its way to the other peer.
  MySignalling.SendCandidate(aCandidate, aSdpMid, aSdpMLineIndex);
end;

Yanıt veren taraf geleni tüketir ve cevabını verir. Başka hiçbir şey değişmez.

// the remote description arrived over your signalling channel
oRTC.SetRemoteDescription('offer', vSDP);
oRTC.CreateAnswer;          // raises OnLocalDescription with 'answer'

// and every remote candidate as it arrives
oRTC.AddIceCandidate(vCandidate, vSdpMid, vSdpMLineIndex);

Yeniden müzakere, ICE yeniden başlatma ve W3C kusursuz müzakere çakışma kuralı yerleşiktir. Kurulmuş bir oturuma bir iz ekleyin, NegotiationNeeded true olur, OnNegotiationNeeded tetiklenir ve bir sonraki teklif yeni m-satırını taşır. İki eş aynı anda teklif verirse, Polite özelliği True olan taraf kendi teklifini geri alır ve karşı tarafınkini yanıtlar, böylece oturum kilitlenmek yerine çakışmadan sağ çıkar.

Bağlanma: ICE, STUN ve TURN

Aday toplama RFC 8445 belgesini izler. Ana makine adayları yerel arayüzlerden gelir, sunucu yansımalı adaylar bir STUN bağlama isteğinden gelir ve aktarılan adaylar, iki eş birbirine doğrudan ulaşmalarına izin vermeyen NAT arkasında kaldığında bir TURN tahsisinden gelir. ICE ardından her yerel adayı her uzak adayla eşleştirir ve biri işe yarayana kadar çiftleri sınar.

oRTC.RTCOptions.ICEServers.AddURL('stun:stun.l.google.com:19302');
oRTC.RTCOptions.ICEServers.AddURL('turn:turn.example.com:3478',
  'username', 'credential');

OnConnectionStateChange, taşımanın toplama, bağlanma ve bağlandı aşamalarından geçişini bildirir, SelectedLocalCandidate ve SelectedRemoteCandidate ise hangi çiftin kazandığını söyler, bu da bir çağrının doğrudan mı yoksa aktarıcı üzerinden mi gittiğini görmenin en hızlı yoludur.

procedure TForm1.OnConnectionStateChangeHandler(Sender: TObject;
  aState: TsgcRTCConnectionState);
begin
  case aState of
    rtccsGathering:    DoLog('gathering candidates');
    rtccsConnecting:   DoLog('checking candidate pairs');
    rtccsConnected:    DoLog('connected: ' + oRTC.SelectedRemoteCandidate);
    rtccsDisconnected: DoLog('disconnected');
    rtccsFailed:       DoLog('failed, try RestartIce');
  end;
end;

Karşı eş bir tarayıcı olduğunda iki seçenek önem kazanır. TrickleICE, adayları toplama bitene kadar beklemek yerine bulundukça yayımlar, TrickleICEAuto ise uzak tanım bunu bildirdiğinde seçeneği otomatik olarak açar. Her tarayıcı adayları damla damla gönderir, bu yüzden bir tarayıcı teklifine verilen yanıt, toplama zaman aşımından sonra değil hemen yola çıkar.

Güvenceye Alma: DTLS-SRTP, İsteğe Bağlı Değil

Medya şifrelemesi zorunludur, bir tarayıcının dayattığı modelin aynısı. Seçilen ICE çifti üzerinde bir DTLS el sıkışması çalışır, SRTP anahtarları bundan türetilir ve bağlantı üzerindeki her RTP, RTCP ve SCTP paketi ilk paketten itibaren şifrelenir. Uzak uç, SDP içinde taşınan sertifika parmak iziyle doğrulanır, WebRTC bunun için bir sertifika otoritesine ihtiyaç duymaz.

SCTP Üzerinden Veri Kanalları

CreateDataChannel, RFC 8832 belgesindeki DCEP açma el sıkışmasıyla, DTLS üzerinde SCTP kullanan bir RTCDataChannel açar. Kanal sıralı veya sırasız, tamamen güvenilir ya da bir yeniden gönderim sınırı veya ömür sınırıyla kısmen güvenilir olabilir. Geç gelen bir paketin taze olandan daha az değerli olduğu telemetri veya oyun durumu için isteyeceğiniz şey de budur.

uses
  sgcP2P, sgcP2P_DataChannel;

var
  vChat, vTelemetry: TsgcRTCDataChannel;
begin
  // ordered and reliable, the default
  vChat := oRTC.CreateDataChannel('chat');
  vChat.OnOpen := OnChannelOpen;
  vChat.OnMessage := OnChannelMessage;

  // unordered, no retransmissions: drop it rather than deliver it late
  vTelemetry := oRTC.CreateDataChannel('telemetry', False, 0);
end;

procedure TForm1.OnChannelOpen(Sender: TObject);
begin
  TsgcRTCDataChannel(Sender).Send('hello');
end;

procedure TForm1.OnChannelMessage(Sender: TObject; const aText: string);
begin
  DoLog('remote said: ' + aText);
end;

// a channel the remote peer opened arrives here
procedure TForm1.OnDataChannelHandler(Sender: TObject;
  aChannel: TsgcRTCDataChannel);
begin
  aChannel.OnMessage := OnChannelMessage;
  aChannel.OnMessageBinary := OnChannelMessageBinary;
end;

Send metin taşır, SendBytes ikili yükleri taşır. BufferedAmount kuyrukta hâlâ ne kadar veri olduğunu söyler, böylece bir dosya aktarımı birlikteliği boğmak yerine kendi hızını ayarlayabilir.

Ses, Video ve Ekran Paylaşımı

AddTrack bağlantıya bir medya izi ekler ve onu döndürür. İz, kendi kodlayıcısının ve kod çözücüsünün sahibidir, yani ham örnekleri veya kareleri içeri gönderirsiniz ve kodlanmış, şifrelenmiş RTP dışarı çıkar. Uzak eşten geleni ise iz olayları üzerinden kodu çözülmüş olarak alırsınız.

uses
  sgcP2P, sgcP2P_RTC_Media, sgcP2P_Codec_Types;

var
  vAudio, vVideo: TsgcRTCTrack;
begin
  vAudio := oRTC.AddTrack(rtctkAudio, cctAudioOpus);
  vVideo := oRTC.AddTrack(rtctkVideo, cctVideoH264);

  // what the remote peer sends, already decoded
  vAudio.OnAudio := OnRemoteAudio;
  vVideo.OnVideoFrame := OnRemoteVideoFrame;

  oRTC.CreateOffer;
end;

// push captured microphone samples into the audio track
procedure TForm1.OnMicrophoneCapture(Sender: TObject; const aPCM: TBytes;
  aSamplesPerChannel: Integer);
begin
  vAudio.SendPCM(aPCM, aSamplesPerChannel);
end;

// push captured camera or desktop frames into the video track
procedure TForm1.OnCameraCapture(Sender: TObject;
  const aFrame: TsgcVideoFrame);
begin
  vVideo.SendVideoFrame(aFrame);
end;

// draw what the remote peer sends
procedure TForm1.OnRemoteVideoFrame(Sender: TObject;
  const aFrame: TsgcVideoFrame);
begin
  MyRenderer.Render(aFrame);
end;

Sizin oluşturduğunuz değil de uzak eşin eklediği bir iz, müzakere edilen kodeke zaten bağlanmış aynı olaylarla OnTrack üzerinden gelir.

Ses Opus'tur, telefon sistemleriyle birlikte çalışmanız gerektiğinde u-law ve A-law çeşitleriyle G.711'dir. Video ise bir libvpx bağlaması üzerinden VP8, platformun sağladığı donanım kodlayıcısı üzerinden H.264, yani Windows'ta Media Foundation, macOS ve iOS'ta VideoToolbox, Android'de MediaCodec ve basit, yalnızca kare içi bir yolun yeterli olduğu durumlar için Windows'ta Motion JPEG'dir.

Mikrofon yakalama ve hoparlörden oynatma Windows, Linux, macOS, iOS ve Android için gelir. Kamera yakalama, masaüstü yakalama ve video görüntüleme Windows için gelir, burada TsgcScreenCapture_Win tüm masaüstünü, tek bir monitörü, tek bir pencereyi veya bir bölgeyi, imleçli ya da imleçsiz yakalar. Diğer platformlarda kodekler ve taşıma aynı şekilde çalışır, kareleri SendVideoFrame ile içeri verir ve OnVideoFrame ile geleni platformun size sunduğu araçlarla çizersiniz.

Gerçek Bir Ağda Ayakta Kalmak

Yalnızca sakin bir yerel ağda çalışan bir eşler arası bağlantının pek faydası yoktur. sgcWebRTC, bir tarayıcının kullandığı dayanıklılık araçlarının aynısını taşır ve her parçası RTCOptions.Media üzerinde bir anahtardır, yalnızca uzak tanım da bunu gösterdiğinde müzakere edilir.

oRTC.RTCOptions.Media.CongestionControl := True; // transport-cc, REMB fallback
oRTC.RTCOptions.Media.Pacing := True;            // smooth the outgoing packets
oRTC.RTCOptions.Media.RTX := True;               // RFC 4588 retransmission on NACK
oRTC.RTCOptions.Media.FEC := True;               // RED / ULPFEC forward error correction

Google Congestion Control tarzında gecikme tabanlı bir bant genişliği tahmincisi bağlantıyı izler ve video kodlayıcısının hedef bit hızını sürer, böylece bağlantı daraldığında görüntü takılıp kalmak yerine yumuşak biçimde bozulur. RTCP NACK ve PLI geri bildirimi, RFC 4588 yeniden gönderimi ve RED/ULPFEC ise altta yatan paket kaybını karşılar.

Sunucular da Pakete Dahil

Eşler arası bir bağlantı, iki eşi tanıştıracak bir sinyalleşme kanalına, genellikle bir STUN sunucusuna ve başka hiçbir şeyin geçemediği durumlar için bir TURN sunucusuna ihtiyaç duyar. Üçü de sgcWebSockets Enterprise içinde Delphi bileşeni olarak gelir, böylece altyapıyı kiralamak yerine tüm yığını kendiniz çalıştırabilirsiniz: sinyalleşme aktarıcısı olarak TsgcWSPServer_WebRTC, bağlanabilirlik için TsgcSTUNServer ve TsgcTURNServer. Bunun yerine istemciyi herkese açık bir STUN sunucusuna veya barındırılan bir TURN hizmetine yönlendirmenizin de önünde hiçbir engel yok, her iki durumda da standart protokol geçerlidir.

Standartlar

sgcWebRTC standartlara dayalı bir motordur, tescilli bir taşıma değil. ICE ve STUN için RFC 8445 ve RFC 8489, TURN için RFC 8656, DTLS ve DTLS-SRTP için RFC 8827 ve RFC 5764, RTP ve SRTP için RFC 3550 ve RFC 3711, veri kanalları için RFC 8831 ve RFC 8832, JSEP teklif/yanıt durum makinesi için RFC 8829 ve yeniden gönderim için RFC 4588 belgelerini uygular. Bir Delphi eşinin, arada bir çeviri katmanı olmadan bir tarayıcı eşiyle konuşmasını sağlayan şey de budur.

Demolar

Paketle birlikte, her biri tam kaynak koduyla dört demo gelir. Demos\35.P2P\05.RTCPeerConnection iki eşi birbirine bağlar ve yerel olarak çalıştırabileceğiniz küçük bir WebSocket sinyalleşme sunucusu içerir. Demos\35.P2P\06.DataChannel bir SCTP veri kanalı açar ve üzerinden metin ve ikili yükler gönderir. Demos\30.WebRTC_Protocol\03.AudioCall ve Demos\30.WebRTC_Protocol\02.VideoCall ise medya demolarıdır, mikrofondan hoparlöre ve kameradan ekrana.

Temin Edilebilirlik

sgcWebRTC, sgcWebSockets Enterprise için bir eklentidir. Standard veya Professional sürümleri için sunulmaz ve All-Access paketine dahildir. Single, Team ve Site lisansları mevcuttur, hepsi tam kaynak kodu ve bir yıllık güncelleme ile birlikte gelir.

Windows, Linux, macOS, iOS ve Android üzerinde Delphi 7'den Delphi 13 Florence'a kadar olan sürümleri ve eşleşen C++ Builder sürümlerini destekler. Ayrı bir indirme yok, IDE sürümünüz için hazırlanan deneme kurulumu bunu zaten içeriyor.

Medya motoru yalnızca Delphi ve C++ Builder içindir. sgcWebSockets .NET portu, klasik tarayıcıdan tarayıcıya senaryo için bir WebSocket sinyalleşme aktarıcısı olan TsgcWSProtocol_WebRTC_Server bileşenini içerir, ancak TsgcRTCPeerConnection sınıfının .NET karşılığı yoktur.

Ürün sayfası · Özellik dökümü · Denemeyi indirin · Fiyatlandırma

Sorularınız veya geri bildirimleriniz mi var? Bize ulaşın, kodu yazan kişilerden yanıt alacaksınız.