← WebRTC 1.0 Spesifikasyonu

RTP Medya API

W3C WebRTC 1.0 Spesifikasyonu — Türkçe Çeviri

5. RTP Medya API

RTP medya API’si, bir web uygulamasının eşler arası bir bağlantı üzerinden MediaStreamTrack’ler göndermesine ve almasına olanak tanır. İzler bir RTCPeerConnection’a eklendiğinde sinyalleşmeye yol açar; bu sinyalleşme uzak bir eşe iletildiğinde, uzak tarafta karşılık gelen izlerin oluşturulmasına neden olur.

Bir RTCPeerConnection tarafından gönderilen izler ile diğeri tarafından alınan izler arasında bire bir (1:1) tam bir eşleşme yoktur. Öncelikle, gönderilen izlerin kimlikleri alınan izlerin kimlikleriyle eşleşmez. Ayrıca, replaceTrack, bir RTCRtpSender tarafından gönderilen izi, alıcı tarafında yeni bir iz oluşturmadan değiştirir; karşılık gelen RTCRtpReceiver yalnızca tek bir ize sahip olur ve bu iz, potansiyel olarak bir araya getirilmiş birden fazla medya kaynağını temsil edebilir. Hem addTransceiver hem de replaceTrack, aynı izin birden fazla kez gönderilmesine neden olacak şekilde kullanılabilir; bu durum alıcı tarafında, her biri kendi ayrı izine sahip birden fazla alıcı olarak gözlemlenir. Bu nedenle, gerekirse RTCRtpTransceiver’ın mid’i kullanılarak göndericiler ve alıcılar eşleştirilmek suretiyle, bir taraftaki bir RTCRtpSender ile diğer taraftaki bir RTCRtpReceiver’ın izi arasında bire bir bir ilişki olduğunu düşünmek daha doğrudur.

Medya gönderilirken, göndericinin; SDP tarafından müzakere edilen zarf, kodlayıcının hizalama kısıtları ya da hatta CPU aşırı kullanım tespiti veya bant genişliği kestirimi gibi çeşitli gereksinimleri karşılamak için medyayı yeniden ölçeklendirmesi veya yeniden örneklemesi gerekebilir.

[RFC9429]’daki kurallara (bölüm 3.6.) uygun olarak, video AZALTILABİLİR. Girdi kaynağında meydana gelmemiş sahte veriler oluşturmak için medya BÜYÜTÜLMEMELİDİR; piksel sayıları üzerindeki kısıtları karşılamak için gerekli olanlar dışında medya KIRPILMAMALIDIR ve en-boy oranı DEĞİŞTİRİLMEMELİDİR.

WebRTC Çalışma Grubu, bu durumun daha karmaşık bir şekilde ele alınmasının gerekliliği ve zamanlaması konusunda uygulama geri bildirimi aramaktadır. Olası bazı tasarımlar GitHub issue 1283 içinde tartışılmıştır.

Video, scaleResolutionDownBy sonucunda yeniden ölçeklendirildiğinde, ortaya çıkan genişlik veya yüksekliğin bir tam sayı olmadığı durumlar meydana gelebilir. Kullanıcı aracısı, bir kodlayıcının asgari çözünürlüğüne uymak dışında, scaleResolutionDownBy’dan elde edilen ölçeklenmiş genişlik ve yüksekliğin tam sayı kısmından daha büyük video GÖNDERMEMELİDİR. Ölçeklenmiş genişlik veya yüksekliğin tam sayı kısmının sıfır olması durumunda neyin gönderileceği uygulamaya bağlıdır.

MediaStreamTrack’lerin gerçek kodlanması ve iletimi RTCRtpSender olarak adlandırılan nesneler aracılığıyla yönetilir. Benzer şekilde, MediaStreamTrack’lerin alınması ve kod çözümü RTCRtpReceiver olarak adlandırılan nesneler aracılığıyla yönetilir. Her RTCRtpSender en fazla bir izle ilişkilidir ve alınacak her iz tam olarak bir RTCRtpReceiver ile ilişkilidir.

Her bir MediaStreamTrack’in kodlanması ve iletimi, özelliklerinin (video izleri için width, height ve frameRate; ses izleri için sampleSize, sampleRate ve channelCount) makul bir ölçüde uzak tarafta oluşturulan iz tarafından korunacak şekilde YAPILMALIDIR. Bunun geçerli olmadığı durumlar vardır; örneğin her iki uçta ya da ağda kaynak kısıtları olabilir veya uygulamanın farklı davranmasını talimatlandıran RTCRtpSender ayarları uygulanmış olabilir.

Bir RTCPeerConnection nesnesi, eşleştirilmiş göndericileri ve alıcıları bazı paylaşılan durumlarla temsil eden bir RTCRtpTransceiver kümesi içerir. Bu küme, RTCPeerConnection nesnesi oluşturulduğunda boş küme olarak başlatılır. RTCRtpSender’lar ve RTCRtpReceiver’lar her zaman bir RTCRtpTransceiver ile aynı anda oluşturulur ve yaşam süreleri boyunca ona bağlı kalırlar. RTCRtpTransceiver’lar, uygulama addTrack() yöntemi aracılığıyla bir MediaStreamTrack’i bir RTCPeerConnection’a bağladığında örtük olarak ya da uygulama addTransceiver yöntemini kullandığında açıkça oluşturulur. Ayrıca, yeni bir medya tanımı içeren bir uzak tanım uygulandığında da oluşturulurlar. Ek olarak, uzak uç noktanın gönderilecek medyası olduğunu belirten bir uzak tanım uygulandığında, ilgili MediaStreamTrack ve RTCRtpReceiver, track olayı aracılığıyla uygulamaya sunulur.

Bir RTCRtpTransceiver’ın başka bir uç nokta ile medya gönderebilmesi ve/veya alabilmesi için, her iki uç noktanın da aynı medya tanımıyla ilişkilendirilmiş bir RTCRtpTransceiver nesnesine sahip olacak şekilde SDP ile müzakere edilmesi gerekir.

Bir teklif oluşturulurken, o uçtaki tüm transceiver’ları kapsayacak kadar medya tanımı üretilecektir. Bu teklif yerel tanım olarak ayarlandığında, ilişkilendirilmemiş tüm transceiver’lar teklifteki medya tanımlarıyla ilişkilendirilir.

Bir teklif uzak tanım olarak ayarlandığında, içindeki ve henüz bir transceiver ile ilişkilendirilmemiş tüm medya tanımları yeni veya mevcut bir transceiver ile ilişkilendirilir. Bu durumda yalnızca addTrack() yöntemiyle oluşturulmuş ve ilişkilendirilmemiş transceiver’lar ilişkilendirilebilir. Buna karşılık, addTransceiver() yöntemiyle oluşturulmuş ve ilişkilendirilmemiş transceiver’lar, uzak teklifte medya tanımları mevcut olsa bile ilişkilendirilmez. Bunun yerine, yeterli sayıda addTrack() ile oluşturulmuş transceiver yoksa, yeni transceiver’lar oluşturulur ve ilişkilendirilir. Bu durum, addTrack() ile oluşturulan ve addTransceiver() ile oluşturulan transceiver’ları, özniteliklerine bakılarak gözlemlenemeyen kritik bir şekilde birbirinden ayırır.

Bir yanıt oluşturulurken, yalnızca teklifte mevcut olan medya tanımları yanıtta listelenebilir. Bunun bir sonucu olarak, uzak teklif ayarlanırken ilişkilendirilmemiş olan tüm transceiver’lar, yerel yanıt ayarlandıktan sonra da ilişkilendirilmemiş olarak kalır. Bu durum, yanıtlayanın bir takip teklifi oluşturmasıyla, başka bir teklif/yanıt değişimini başlatmasıyla ya da addTrack() ile oluşturulmuş transceiver’lar kullanılıyorsa, ilk değişimde yeterli sayıda medya tanımının sunulduğundan emin olunmasıyla giderilebilir.

5.4 RTCRtpTransceiver Arayüzü

RTCRtpTransceiver arayüzü, ortak bir ortam akışı "tanımlama-etiketi"ni paylaşan bir RTCRtpSender ve bir RTCRtpReceiver birleşimini temsil eder. [RFC9429]’da (bölüm 3.4.1.) tanımlandığı üzere, bir RTCRtpTransceiver, "mid" özelliği null değilse ve ortam tanımındaki bir ortam akışı "tanımlama-etiketi" ile eşleşiyorsa, bir ortam tanımıyla ilişkili kabul edilir; aksi halde bu ortam tanımıyla ilişkisiz olduğu söylenir.

Bir RTCRtpTransceiver, geçerli tanımla hâlâ ilişkisiz durumdayken RFC9429’daki yeni bir bekleyen tanımla ilişkili hâle gelebilir. Bu durum, müzakerenin gerekli olup olmadığının kontrol edilmesi sırasında meydana gelebilir.

Bir RTCRtpTransceiver nesnesinin transceiver türü, ilişkili RTCRtpReceiver nesnesinin MediaStreamTrack öğesinin türü tarafından tanımlanır.

Bir RTCRtpReceiver nesnesi receiver, bir RTCRtpSender nesnesi sender ve bir RTCRtpTransceiverDirection değeri direction ile bir RTCRtpTransceiver oluşturmak için aşağıdaki adımları çalıştırın:

  1. transceiver, yeni bir RTCRtpTransceiver nesnesi olsun.
  2. transceiver nesnesinin [[Sender]] iç yuvası sender ile başlatılsın.
  3. transceiver nesnesinin [[Receiver]] iç yuvası receiver ile başlatılsın.
  4. transceiver nesnesinin [[Stopping]] iç yuvası false ile başlatılsın.
  5. transceiver nesnesinin [[Stopped]] iç yuvası false ile başlatılsın.
  6. transceiver nesnesinin [[Direction]] iç yuvası direction ile başlatılsın.
  7. transceiver nesnesinin [[Receptive]] iç yuvası false ile başlatılsın.
  8. transceiver nesnesinin [[CurrentDirection]] iç yuvası null ile başlatılsın.
  9. transceiver nesnesinin [[FiredDirection]] iç yuvası null ile başlatılsın.
  10. transceiver nesnesinin [[PreferredCodecs]] iç yuvası boş bir liste ile başlatılsın.
  11. transceiver nesnesinin [[JsepMid]] iç yuvası null ile başlatılsın. Bu, [RFC9429]’da (bölüm 5.2.1. ve bölüm 5.3.1.) tanımlanan "RtpTransceiver mid özelliği"dir ve yalnızca orada değiştirilir.
  12. transceiver nesnesinin [[Mid]] iç yuvası null ile başlatılsın.
  13. transceiver nesnesini döndürün.
Bir transceiver oluşturmak, alttaki RTCDtlsTransport ve RTCIceTransport nesnelerini oluşturmaz. Bu yalnızca bir oturum tanımı ayarlama sürecinin parçası olarak gerçekleşir.
WebIDL[Exposed=Window]
                        interface RTCRtpTransceiver {
                          readonly attribute DOMString? mid;
                          [SameObject] readonly attribute RTCRtpSender sender;
                          [SameObject] readonly attribute RTCRtpReceiver receiver;
                          attribute RTCRtpTransceiverDirection direction;
                          readonly attribute RTCRtpTransceiverDirection? currentDirection;
                          undefined stop();
                          undefined setCodecPreferences(sequence<RTCRtpCodec> codecs);
                        };

Öznitelikler

mid türü DOMString, salt okunur, null olabilir

mid özniteliği, yerel ve uzak tanımlarda müzakere edilmiş ve mevcut olan ortam akışı "tanımlama-etiketi"dir. Alınırken, bu öznitelik [[Mid]] yuvasının değerini MUST döndürmelidir.

sender türü RTCRtpSender, salt okunur

sender özniteliği, mid = [[Mid]] ile gönderilebilecek RTP ortamına karşılık gelen RTCRtpSender nesnesini ortaya çıkarır. Alınırken, bu öznitelik [[Sender]] yuvasının değerini MUST döndürmelidir.

receiver türü RTCRtpReceiver, salt okunur

receiver özniteliği, mid = [[Mid]] ile alınabilecek RTP ortamına karşılık gelen RTCRtpReceiver nesnesidir. Alınırken bu öznitelik [[Receiver]] yuvasının değerini MUST döndürmelidir.

direction türü RTCRtpTransceiverDirection

[RFC9429] (bölüm 4.2.4.)’te tanımlandığı üzere, direction özniteliği bu alıcı-vericinin tercih edilen yönünü belirtir ve bu yön, createOffer ve createAnswer çağrılarında kullanılır. Yönlülüğün güncellenmesi hemen etkili olmaz. Bunun yerine, createOffer ve createAnswer için yapılacak gelecekteki çağrılar, ilgili ortam tanımını [RFC9429]’da tanımlandığı şekilde sendrecv, sendonly, recvonly veya inactive olarak işaretler (bölüm 5.2.2. ve bölüm 5.3.2.).

Get işlemi sırasında, kullanıcı aracısı aşağıdaki adımları MUST çalıştırmalıdır:

  1. Getter’ın çağrıldığı RTCRtpTransceiver nesnesi transceiver olsun.
  2. Eğer transceiver.[[Stopping]] true ise, "stopped" döndür.
  3. Aksi halde, [[Direction]] yuvasının değerini döndür.

Set işlemi sırasında, kullanıcı aracısı aşağıdaki adımları MUST çalıştırmalıdır:

  1. Setter’ın çağrıldığı RTCRtpTransceiver nesnesi transceiver olsun.
  2. transceiver ile ilişkili RTCPeerConnection nesnesi connection olsun.
  3. Eğer transceiver.[[Stopping]] true ise, bir InvalidStateError fırlat.
  4. Setter’a verilen argüman newDirection olsun.
  5. Eğer newDirection, transceiver.[[Direction]] ile eşitse, bu adımları durdur.
  6. Eğer newDirection "stopped" ise, bir TypeError fırlat.
  7. transceiver.[[Direction]] değerini newDirection olarak ayarla.
  8. connection için müzakere-gerekli bayrağını güncelle.

currentDirection türü RTCRtpTransceiverDirection, salt-okunur, nullable

[RFC9429] (bölüm 4.2.5.)’te tanımlandığı üzere, currentDirection özniteliği bu alıcı-verici için müzakere edilmiş geçerli yönü belirtir. currentDirection değeri, RTCRtpEncodingParameters.active değerinden bağımsızdır; çünkü birinden diğeri çıkarılamaz. Bu alıcı-verici hiç bir teklif/yanıt değişiminde temsil edilmemişse, değer null olur. Alıcı-verici stopped durumundaysa, değer "stopped" olur.

Get işlemi sırasında, kullanıcı aracısı aşağıdaki adımları MUST çalıştırmalıdır:

  1. Getter’ın çağrıldığı RTCRtpTransceiver nesnesi transceiver olsun.
  2. Eğer transceiver.[[Stopped]] true ise, "stopped" döndür.
  3. Aksi halde, [[CurrentDirection]] yuvasının değerini döndür.

Yöntemler

stop

Alıcı-vericiyi, zaten stopped durumda değilse, geri döndürülemez biçimde stopping olarak işaretler. Bu, alıcı-vericinin göndericisinin artık gönderim yapmamasına ve alıcısının artık alım yapmamasına derhal neden olur. stop() çağrılması ayrıca RTCRtpTransceiver ile ilişkili RTCPeerConnection için müzakere-gerekli bayrağını da günceller.

Durdurulmakta olan bir alıcı-verici, [RFC9429]’da tanımlandığı üzere (bölüm 4.2.1.), createOffer için yapılacak gelecekteki çağrıların, ilgili alıcı-verici için ortam tanımında sıfır port üretmesine neden olur (kullanıcı aracısı MUST bu durumda RFC9429 amaçları için stopping durumundaki bir alıcı-vericiyi stopped olarak ele almalıdır). Ancak, [RFC8843] ile ilgili sorunlardan kaçınmak için, stopping durumda olup stopped olmayan bir alıcı-verici createAnswer’ı etkilemez.

stopped durumundaki bir alıcı-verici, [RFC9429]’da tanımlandığı üzere (bölüm 4.2.1.), createOffer veya createAnswer için yapılacak gelecekteki çağrıların, ilgili alıcı-verici için ortam tanımında sıfır port üretmesine neden olur.

Alıcı-verici, uzak bir teklif veya yanıtta reddedilmiş bir m-line’ın setRemoteDescription tarafından işlenmesi sonucu stopped durumuna geçmedikçe stopping durumunda kalır.

stopping durumunda olup stopped olmayan bir alıcı-verici her zaman müzakereye ihtiyaç duyar. Pratikte bu, bir alıcı-vericide stop() çağrılmasının, müzakerenin her iki uçta da tamamlanmasına izin verildiği sürece, alıcı-vericinin sonunda stopped durumuna geçmesine neden olacağı anlamına gelir.

stop yöntemi çağrıldığında, kullanıcı aracısı aşağıdaki adımları MUST çalıştırmalıdır:

  1. Yöntemin çağrıldığı RTCRtpTransceiver nesnesi transceiver olsun.
  2. transceiver ile ilişkili RTCPeerConnection nesnesi connection olsun.
  3. Eğer connection.[[IsClosed]] true ise, bir InvalidStateError fırlat.
  4. Eğer transceiver.[[Stopping]] true ise, bu adımları durdur.
  5. transceiver ile gönderim ve alımı durdur.
  6. connection için müzakere-gerekli bayrağını güncelle.

Bir transceiver verildiğinde ve isteğe bağlı olarak varsayılanı false olan bir disappear boolean’ı ile gönderim ve alımı durdurma algoritması aşağıdaki gibidir:

  1. transceiver.[[Sender]] değeri sender olsun.
  2. transceiver.[[Receiver]] değeri receiver olsun.
  3. Paralel olarak, sender ile ortam göndermeyi durdur ve [RFC3550]’de belirtildiği üzere sender tarafından gönderilmekte olan her RTP akışı için bir RTCP BYE gönder.
  4. Paralel olarak, receiver ile ortam alımını durdur.
  5. Eğer disappear false ise, receiver.[[ReceiverTrack]] için sonlandırılmış olma adımlarını yürüt. Bu bir olay tetikler.
  6. transceiver.[[Direction]] değerini "inactive" olarak ayarla.
  7. transceiver.[[Stopping]] değerini true olarak ayarla.

Bir transceiver verildiğinde ve isteğe bağlı olarak varsayılanı false olan bir disappear boolean’ı ile RTCRtpTransceiver’ı durdurma algoritması aşağıdaki gibidir:

  1. Eğer transceiver.[[Stopping]] false ise, transceiver ve disappear ile gönderim ve alımı durdur.
  2. transceiver.[[Stopped]] değerini true olarak ayarla.
  3. transceiver.[[Receptive]] değerini false olarak ayarla.
  4. transceiver.[[CurrentDirection]] değerini null olarak ayarla.
setCodecPreferences

Aday Ek 51:setCodecPreferences, gönderme ve alma kodeklerinin her ikisini de (yön ile filtrelenmiş olarak) destekler (PR #3018)

setCodecPreferences yöntemi, kullanıcı aracısı tarafından müzakereye girdi olarak kullanılan varsayılan kodek tercihlerini geçersiz kılar. createOffer veya createAnswer kullanılarak bir oturum tanımı üretilirken, kullanıcı aracısı tercih edilen kodekleri direction’a göre MUST filtrelemeli ve bu işlem boş olmayan bir listeyle sonuçlanırsa, bu RTCRtpTransceiver’a karşılık gelen ortam bölümü için codecs argümanının sırasına göre belirtilen kodekleri MUST kullanmalıdır.

Bu yöntem, uygulamaların belirli kodeklerin (RTX/RED/FEC dahil) müzakere edilmesini devre dışı bırakmasına olanak tanır; devre dışı bırakılacak olanlar dışındaki tüm kodekler listelenerek yapılır.

m= bölümü alım için kullanılıyorsa, SDP’deki kodeklerin sırası (hem teklif hem de yanıt için) uzak uç noktaya yerel uç noktanın hangi kodeği almayı tercih ettiğini bildirir. m= bölümü alım için kullanılmasa bile, kendi kodek tercihleri olmayan bir yanıtlayıcı, SDP yanıtı için varsayılan olarak aynı sırayı kullanır.
Bir RTCRtpSender, varsayılan olarak uzak uç noktanın almayı tercih ettiğini belirttiği kodeği gönderir; ancak uygulama, setParameters çağırarak ve hangi codec’in gönderileceğini belirterek, müzakere edilmiş codecs arasından hangi kodeğin gönderileceğini değiştirebilir. Bir RTCRtpReceiver, müzakere edilmiş herhangi bir kodeği almaya hazırdır.

Kodek tercihleri, bu RTCRtpTransceiver’ı içeren tüm createOffer ve createAnswer çağrıları için, bu yöntem tekrar çağrılana kadar geçerliliğini korur. codecs’un boş bir diziye ayarlanması ya da direction filtrelemesinden sonra boş hale gelmesi, varsayılan kodek tercihlerine yol açar.

Kodeklerin payload türleri SDP’de her m= bölümünün altında listelenir ve payload türleri ile kodekler arasındaki eşlemeyi tanımlar. Bu payload türlerine, tercih sırasına göre m=video veya m=audio satırları tarafından başvurulur ve müzakere edilmeyen kodekler, [RFC9429]’un bölüm 5.2.1’inde tanımlandığı üzere bu listede yer almaz. Önceden müzakere edilmiş olup sonradan kaldırılan bir kodek, m=video veya m=audio satırından kaybolur ve payload türü gelecekteki teklif veya yanıtlarda yeniden kullanılmaması gerekirken, payload türü SDP’deki payload türleri eşlemesinden de kaldırılabilir.

setCodecPreferences, RTCRtpTransceiver’ın türü olan kind için, RTCRtpSender.getCapabilities(kind) veya RTCRtpReceiver.getCapabilities(kind) içinde bulunmayan kodeklerle eşleşmeyen codecs ayarlama girişimlerini reddeder.

[SDP]’deki bir öneri nedeniyle, createAnswer çağrıları yalnızca kodek tercihleri ile teklifte yer alan kodeklerin ortak alt kümesini kullanmalıdır (SHOULD). Örneğin, kodek tercihleri "C, B, A" ise ancak teklifte yalnızca "A, B" kodekleri sunulmuşsa, yanıt yalnızca "B, A" kodeklerini içermelidir. Ancak, [RFC8829] (bölüm 5.3.1.) teklifte yer almayan kodeklerin eklenmesine izin verir; dolayısıyla uygulamalar farklı davranabilir.

setCodecPreferences() çağrıldığında, kullanıcı aracısı aşağıdaki adımları MUST çalıştırmalıdır:

  1. Bu yöntemin çağrıldığı RTCRtpTransceiver nesnesi transceiver olsun.
  2. İlk argüman codecs olsun.
  3. Eğer codecs boş bir listeyse, transceiver.[[PreferredCodecs]] değerini codecs olarak ayarla ve bu adımları durdur.
  4. codecs içindeki yinelenen değerleri kaldır. Kodeklerin önceliği korunacak şekilde listenin arkasından başla; bir kodeğin listedeki ilk görüldüğü indeks bu adımdan önce ve sonra aynı kalsın.
  5. codecs içindeki yinelenen değerleri kaldır ve her değerin ilk görülme yerinin yerinde kalmasını sağla.
  6. transceiver’ın alıcı-verici türü kind olsun.
  7. codecs ile RTCRtpSender.getCapabilities(kind).codecs kesişimi ya da codecs ile RTCRtpReceiver.getCapabilities(kind).codecs kesişimi yalnızca RTX, RED veya FEC kodeklerini içeriyorsa ya da boş bir küme ise, InvalidModificationError fırlat. Bu, transceiver.direction değerinden bağımsız olarak her zaman sunulacak bir şey olmasını sağlar.
  8. RTCRtpSender.getCapabilities(kind).codecs ile RTCRtpReceiver.getCapabilities(kind).codecs birleşimi codecCapabilities olsun.
  9. codecs içindeki her codec için,
  10. Eğer codec, codecCapabilities içinde değilse, InvalidModificationError fırlat.
  11. codecs içindeki her codec için,
  12. Eğer codec, codecCapabilities içindeki herhangi bir kodekle eşleşmiyorsa, InvalidModificationError fırlat.
  13. Eğer codecs yalnızca RTX, RED, FEC veya Comfort Noise girdilerini içeriyorsa ya da boş bir küme ise, InvalidModificationError fırlat. Bu, transceiver.direction değerinden bağımsız olarak her zaman sunulacak bir şey olmasını sağlar.
  14. transceiver.[[PreferredCodecs]] değerini codecs olarak ayarla.

İki RTCRtpCodec sözlüğü first ve second verildiğinde ve belirtilmemişse varsayılanı false olan bir ignoreLevels boolean’ı ile kodek sözlüğü eşleştirme algoritması aşağıdaki gibidir:

  1. Eğer first.mimeType, second.mimeType ile ASCII büyük/küçük harf duyarsız bir eşleşme değilse, false döndür.
  2. Eğer first.clockRate, second.clockRate’ten farklıysa, false döndür.
  3. Eğer first.channels ile second.channels’tan yalnızca biri mevcut değilse ya da her ikisi de mevcut olup first.channels, second.channels’ten farklıysa, false döndür.
  4. Eğer first.sdpFmtpLine ile second.sdpFmtpLine’dan yalnızca biri mevcut değilse, false döndür.
  5. Eğer hem first.sdpFmtpLine hem de second.sdpFmtpLine mevcutsa, aşağıdaki adımları çalıştır:
  6. Eğer first.sdpFmtpLine veya second.sdpFmtpLine anahtar-değer biçiminde değilse, first.sdpFmtpLine ile second.sdpFmtpLine arasında bir eşitlik karşılaştırması yapılmasının sonucunu döndür.
  7. first.sdpFmtpLine’dan oluşturulan ortam biçimlerinin anahtar-değer eşlemesi firstMediaFormat, second.sdpFmtpLine’dan oluşturulan ortam biçimlerinin anahtar-değer eşlemesi secondMediaFormat olsun.
Hangi FMTP parametrelerinin ortam biçimini oluşturduğu kodeğe özgüdür. Bazı durumlarda bir parametre atlanabilir ve yine de çıkarım yapılabilir; bu durumda o parametre de ilgili kodeğin ortam biçiminin bir parçasıdır.
  1. Eğer firstMediaFormat, secondMediaFormat ile eşit değilse, false döndür.
  2. Aday Düzeltme 52: level-id aynı olmasa bile iki kodek aynı kabul edilir (PR #3023)
  3. Eğer ignoreLevels false ise ve first.sdpFmtpLine ile second.sdpFmtpLine’dan çıkarılan en yüksek uyumlu bit akışı seviyeleri farklıysa, false döndür.

ignoreLevels true olsa bile, bazı kodekler (H.264 gibi) ortam biçiminin içinde seviyeleri içerir; bu nedenle seviyeyi yok saymak kodeğe özgü ayrıştırma gerektirir.
  1. true döndür.
Ayarlanmışsa, teklifi yapanın alma kodek tercihleri, teklifteki kodeklerin sırasını belirler. Yanıtlayıcının herhangi bir kodek tercihi yoksa, yanıtta da aynı sıra kullanılır. Ancak yanıtlayıcının da kodek tercihleri varsa, bu tercihler yanıttaki sırayı geçersiz kılar. Bu durumda, teklifi yapanın tercihleri hangi kodeklerin sunulduğunu etkiler, ancak nihai sırayı etkilemez.

5.4.1 Simulcast işlevselliği

Simulcast gönderme işlevselliği, RTCPeerConnection nesnesinin yöntemleri olan addTransceiver yöntemi aracılığıyla sendEncodings argümanı üzerinden ya da simulcast alımı için uzak bir teklif ile setRemoteDescription yöntemi aracılığıyla etkinleştirilir. Ayrıca, her bir RTCRtpSender nesnesindeki setParameters yöntemi, bu işlevselliği incelemek ve değiştirmek için kullanılabilir.

Bir RTCRtpSender nesnesinin simulcast zarfı, unicast yerine simulcast göndermeyi içeren ilk başarılı müzakere sırasında belirlenir ve gönderilebilecek maksimum simulcast akışı sayısını ve encodings sıralamasını içerir. Bu simulcast zarfı, sonraki yeniden müzakerelerde daraltılabilir (katman sayısı azaltılarak), ancak yeniden genişletilemez. Bireysel simulcast akışlarının özellikleri setParameters yöntemi kullanılarak değiştirilebilir, ancak simulcast zarfının kendisi bu yöntemle değiştirilemez.

Simulcast yapılandırmanın bir yolu, addTransceiver() için sendEncodings seçeneğini kullanmaktır. addTrack() yöntemi simulcast yapılandırmak için gerekli olan sendEncodings bağımsız değişkenine sahip olmasa da, kullanıcı aracısı answerer olduğunda göndericiler simulcast’e terfi ettirilebilir. Simulcast almayı teklif eden bir uzak teklif ile setRemoteDescription yöntemi çağrıldığında, belirtilen oturum açıklamasında tanımlanan katmanları içerecek şekilde bir RTCRtpSender üzerinde önerilen bir zarf yapılandırılır. Bu açıklama geri alınmadığı sürece, müzakere tamamlandığında önerilen zarf RTCRtpSender nesnesinin simulcast zarfı hâline gelir. Yukarıda belirtildiği gibi, bu simulcast zarfı sonraki yeniden müzakerelerde daraltılabilir, ancak yeniden genişletilemez.

setParameters simulcast simulcast zarfını, değiştiremezken, yine de gönderilen akış sayısını ve bu akışların özelliklerini kontrol etmek mümkündür. setParameters kullanılarak, active üyesi false olarak ayarlanarak simulcast akışları pasif hâle getirilebilir veya active üyesi true olarak ayarlanarak yeniden etkinleştirilebilir. [[RFC7728] (RTP Durdur/Devam) desteklenmemektedir; SDP Offer/Answer aracılığıyla durdurma/devam sinyallemesi de desteklenmez.] setParameters kullanılarak, maxBitrate gibi öznitelikler değiştirilerek akış özellikleri değiştirilebilir.

Simulcast, sıklıkla bir SFU’ya birden fazla kodlama göndermek için kullanılır; SFU daha sonra simulcast akışlarından birini son kullanıcıya iletir. Bu nedenle kullanıcı aracısının, tüm simulcast akışlarının tek başına kullanılabilir olacağı şekilde kodlamalar arasında bant genişliği tahsis etmesi beklenir; örneğin iki simulcast akışı aynı maxBitrate değerine sahipse, her iki akışta da benzer bir bit hızı görülmesi beklenir. Bant genişliği tüm simulcast akışlarının kullanılabilir bir biçimde gönderilmesine izin vermiyorsa, kullanıcı aracısının simulcast akışlarından bazılarını göndermeyi durdurması beklenir.

[RFC9429] (bölüm 3.7.)’da tanımlandığı üzere, bir kullanıcı aracısından gelen bir teklif a=simulcast satırında yalnızca bir "send" açıklaması içerir ve herhangi bir "recv" açıklaması içermez. Alternatifler ve kısıtlamalar ([RFC8853]’te açıklananlar) desteklenmemektedir.

Bu belirtim, createOffer, createAnswer veya addTransceiver kullanılarak birden fazla RTP kodlamasının alımının nasıl yapılandırılacağını tanımlamaz. Ancak [RFC9429]’da tanımlandığı üzere birden fazla RTP kodlaması gönderebilen karşılık gelen bir uzak açıklama ile setRemoteDescription çağrıldığında ve tarayıcı birden fazla RTP kodlamasını almayı desteklediğinde, RTCRtpReceiver birden fazla RTP kodlaması alabilir ve transceiver’ın receiver.getParameters() yöntemiyle alınan parametreler müzakere edilen kodlamaları yansıtır.

Bir RTCRtpReceiver, Seçmeli Yönlendirme Birimi (SFU) tarafından kullanıcı aracılarından aldığı simulcast akışları arasında geçiş yapıldığı bir senaryoda birden fazla RTP akışı alabilir. SFU, iletmeden önce geçiş yapılan akışları tek bir RTP akışı hâline getirecek şekilde RTP başlıklarını yeniden yazmazsa, RTCRtpReceiver her biri kendi SSRC’sine ve sıra numarası uzayına sahip olan farklı RTP akışlarından paketler alır. SFU herhangi bir anda yalnızca tek bir RTP akışını iletebilse bile, yeniden sıralama nedeniyle birden fazla RTP akışından gelen paketler alıcıda birbirine karışabilir. Bu nedenle birden fazla RTP akışını almaya uygun bir RTCRtpReceiver, alınan paketleri doğru şekilde sıralayabilmeli, olası kayıp olaylarını tanıyabilmeli ve bunlara tepki verebilmelidir. Bu senaryoda doğru çalışma trivial değildir ve bu nedenle bu belirtimin uygulamaları için isteğe bağlıdır.

5.4.1.1 Kodlama Parametresi Örnekleri

Bu bölüm normatif değildir.

Kodlama parametreleri ile uygulanmış simulcast senaryolarına örnekler:

// En düşük çözünürlüklü katman hariç tüm katmanları devre dışı bırakılmış 3 katmanlı mekânsal simulcast örneği
                        var encodings = [
                          {rid: 'q', active: true, scaleResolutionDownBy: 4.0}
                          {rid: 'h', active: false, scaleResolutionDownBy: 2.0},
                          {rid: 'f', active: false},
                        ];

5.4.2 "Hold" işlevselliği

Bu bölüm normatif değildir.

Birlikte ele alındığında, direction özniteliği ve replaceTrack yöntemi geliştiricilerin "hold" senaryolarını uygulamasını sağlar.

Bir eşe müzik göndermek ve alınan sesi çalmayı durdurmak için (bekletme müziği):

async function playMusicOnHold() {
                          try {
                            // Bir ses transceiver’ına ve musicTrack adlı bir müzik parçasına sahip olduğumuzu varsayalım
                            await audio.sender.replaceTrack(musicTrack);
                            // Alınan sesi sustur
                            audio.receiver.track.enabled = false;
                            // Yalnızca gönderim yönünü ayarla (müzakere gerektirir)
                            audio.direction = 'sendonly';
                          } catch (err) {
                            console.error(err);
                          }
                        }

Uzak bir eşin "sendonly" teklifine yanıt vermek için:

async function handleSendonlyOffer() {
                          try {
                            // Önce sendonly teklifini uygula,
                            // alıcının ICE adayları için hazır olmasını sağlamak adına.
                            await pc.setRemoteDescription(sendonlyOffer);
                            // Ses göndermeyi durdur
                            await audio.sender.replaceTrack(null);
                            // Daha fazla müzakereyi önlemek için yönümüzü hizala
                            audio.direction = 'recvonly';
                            // createAnswer çağır ve recvonly bir yanıt gönder
                            await doAnswer();
                          } catch (err) {
                            // sinyalleme hatasını ele al
                          }
                        }

Müzik göndermeyi durdurmak ve mikrofondan yakalanan sesi göndermek ile birlikte alınan sesi çalmak için:

async function stopOnHoldMusic() {
                          // Bir ses transceiver’ına ve micTrack adlı bir mikrofon parçasına sahip olduğumuzu varsayalım
                          await audio.sender.replaceTrack(micTrack);
                          // Alınan sesi aç
                          audio.receiver.track.enabled = true;
                          // Yönü sendrecv olarak ayarla (müzakere gerektirir)
                          audio.direction = 'sendrecv';
                        }

Uzak bir eş tarafından beklemeden çıkarılmaya yanıt vermek için:

async function onOffHold() {
                          try {
                            // Önce sendrecv teklifini uygula; alıcının ICE adayları için hazır olmasını sağlamak adına.
                            await pc.setRemoteDescription(sendrecvOffer);
                            // Ses göndermeye başla
                            await audio.sender.replaceTrack(micTrack);
                            // Yönü sendrecv olarak ayarla (yanıt için tam zamanında)
                            audio.direction = 'sendrecv';
                            // createAnswer çağır ve sendrecv bir yanıt gönder
                            await doAnswer();
                          } catch (err) {
                            // sinyalleme hatasını ele al
                          }
                        }