8. İstatistik Modeli
8.1 Giriş
Temel istatistik modeli, tarayıcının izlenen nesneler için, istatistik nesnesiler biçiminde bir dizi istatistik tutmasıdır.
İlgili nesnelerden oluşan bir grup bir seçici tarafından referans alınabilir. Seçici, örneğin bir
MediaStreamTrack olabilir. Bir iz (track) geçerli bir seçici olabilmesi için, istatistik
isteğinin verildiği RTCPeerConnection nesnesi tarafından gönderilen veya alınan bir
MediaStreamTrack OLMAK ZORUNDADIR. Çağrıyı yapan Web uygulaması
seçiciyi getStats() yöntemine sağlar ve tarayıcı istatistik seçme algoritmasına göre seçiciyle
ilgili olan bir istatistik kümesini yayımlar.
İstatistik nesnesiler içinde döndürülen
istatistikler, tekrarlanan sorguların RTCStats id sözlük üyesi ile
ilişkilendirilebilmesine olanak tanıyacak şekilde tasarlanmıştır. Böylece bir Web uygulaması, belirli bir
zaman aralığının başında ve sonunda ölçümler isteyerek bu zaman aralığı boyunca ölçümler yapabilir.
Birkaç istisna dışında, izlenen
nesneler bir kez oluşturulduktan sonra, ilişkili oldukları RTCPeerConnection süresi
boyunca var olurlar. Bu, ilişkili eş bağlantısı close edildikten sonra bile
getStats() sonucunda bu nesnelere ait istatistiklerin kullanılabilir olmasını sağlar.
Yalnızca birkaç izlenen nesnenin daha kısa yaşam
süreleri vardır. Bu nesnelere ait istatistikler, sonraki getStats() sonuçlarında artık
mevcut değildir. [WEBRTC-STATS] içindeki nesne açıklamaları, bu izlenen nesnelerin ne zaman silindiğini
açıklar.
8.2 RTCPeerConnection Arayüzü Genişletmeleri
İstatistikler API'si, RTCPeerConnection arayüzünü aşağıda açıklandığı şekilde genişletir.
WebIDLpartial interface RTCPeerConnection {
Promise<RTCStatsReport> getStats(optional MediaStreamTrack? selector = null);
};
8.2.1 Yöntemler
getStats()Verilen seçici için istatistikleri toplar ve sonucu eşzamansız olarak bildirir.
getStats() yöntemi çağrıldığında, kullanıcı aracısı aşağıdaki adımları
ÇALIŞTIRMAK ZORUNDADIR:
selectorArg, yöntemin ilk bağımsız değişkeni olsun.connection, yöntemin çağrıldığıRTCPeerConnectionnesnesi olsun.selectorArgnullise,selectornullolsun.selectorArgbirMediaStreamTrackise,selector,tracközniteliğiselectorArgile eşleşenconnectionüzerindeki birRTCRtpSenderveyaRTCRtpReceiverolsun. Böyle bir gönderici veya alıcı yoksa ya da bu ölçütlere uyan birden fazla gönderici veya alıcı varsa, yeni oluşturulmuş birInvalidAccessErrorile reddedilmiş bir promise döndür.pyeni bir promise olsun.- Aşağıdaki adımları paralel olarak çalıştır:
- İstatistik seçme algoritmasına göre
selectortarafından belirtilen istatistikleri topla. - Geçerli realm'in küresel nesnesini
globalolarak alıp ağ görev kaynağında küresel bir görev sıraya koy vep'yi, toplanan istatistikleri içeren sonuçRTCStatsReportnesnesi ile çöz.
- İstatistik seçme algoritmasına göre
p'yi döndür.
8.3 RTCStatsReport Nesnesi
getStats() yöntemi, başarılı bir sonucu RTCStatsReport nesnesi biçiminde sunar. Bir
RTCStatsReport nesnesi, incelenen nesneleri tanımlayan dizgiler (RTCStats
örneklerindeki id özniteliği) ile bunlara karşılık gelen RTCStats türevi sözlükler
arasında bir eşlemedir.
Bir RTCStatsReport, uygulamanın seçici için ilgili olduğunu düşündüğü her bir temel nesne için
istatistik raporlayan birden fazla RTCStats türevi sözlükten oluşabilir. Seçici için toplam
değer, belirli bir türdeki tüm istatistikler toplanarak elde edilir; örneğin bir RTCRtpSender,
izini ağ üzerinden taşımak için birden fazla SSRC kullanıyorsa, RTCStatsReport SSRC başına bir
RTCStats türevi sözlük içerebilir.
WebIDL[Exposed=Window]
interface RTCStatsReport {
readonly maplike<DOMString, object>;
};
Bu istatistik raporunun oluşturulduğu RTCStats'ten türemiş çeşitli sözlükleri almak için
bunları kullanın. Desteklenen özellik adları kümesi [WEBIDL], bu istatistik raporu için üretilmiş tüm
RTCStats türevi sözlüklerin kimlikleri olarak tanımlanır.
8.4 RTCStats Sözlüğü
Bir RTCStats sözlüğü, belirli bir izlenen nesne incelenerek oluşturulan
istatistik nesnesini temsil eder.
RTCStats sözlüğü, timestamp ve type gibi bir dizi varsayılan
özniteliği belirten bir temel türdür. Belirli istatistikler, RTCStats sözlüğü genişletilerek
eklenir.
İstatistik adları standartlaştırılmış olsa da, herhangi bir uygulama deneysel değerler veya Web uygulaması tarafından henüz bilinmeyen değerler kullanıyor olabilir. Bu nedenle uygulamalar, bilinmeyen istatistiklerle başa çıkmaya HAZIR OLMAK ZORUNDADIR.
İstatistiklerin hesaplamada makul değerler vermesi için birbirleriyle senkronize edilmesi gerekir; örneğin
bytesSent ve packetsSent her ikisi de raporlanıyorsa, her ikisinin de aynı zaman
aralığı için raporlanması gerekir. Bu nedenle uygulamalar, bir RTCStats türevi sözlükteki tüm
istatistikler için senkronize değerler DÖNDÜRMEK ZORUNDADIR.
WebIDLdictionary RTCStats {
required DOMHighResTimeStamp timestamp;
required RTCStatsType type;
required DOMString id;
};
8.4.1 RTCStats Sözlüğü Üyeleri
timestamp · DOMHighResTimeStampZaman damgaları DOMHighResTimeStamp ile ifade edilir [[HIGHRES-TIME]],
Performance.timeOrigin + bilginin toplandığı andaki
Performance.now() olarak tanımlanır.
Uzak bir kaynaktan gelen istatistikler için (örneğin alınan RTCP paketlerinden),
timestamp, bilginin yerel uç noktaya ulaştığı zamanı temsil eder. Uzak zaman damgası,
uygunsa RTCStats türevi bir sözlükte ek bir alanda bulunabilir.
type · RTCStatsTypeBu nesnenin türü. type özniteliği, bu RTCStats sözlüğünün temsil ettiği en
özgül türün adıyla BAŞLATILMAK ZORUNDADIR.
id · DOMStringBu RTCStats nesnesini üretmek için incelenen nesneyle ilişkili benzersiz bir
id. İki farklı RTCStatsReport nesnesinden çıkarılan iki
RTCStats nesnesi, aynı temel nesnenin incelenmesiyle üretilmişlerse aynı kimliğe sahip
OLMAK ZORUNDADIR.
İstatistik kimlikleri bir uygulama tarafından tahmin edilebilir OLMAMALIDIR.
getStats() çağrıları arasında kararlı kimliklere sahip olmasını garanti etmeyi
kolaylaştırabilir.
RTCStatsType için geçerli değerler kümesi ve bunların işaret ettiği RTCStats'ten türemiş
sözlükler [WEBRTC-STATS] içinde belgelenmiştir.
8.5 İstatistik seçme algoritması
İstatistik seçme algoritması aşağıdaki gibidir:
resultboş birRTCStatsReportolsun.selectornullise, tümconnectioniçin istatistikleri topla,result'a ekle,result'ı döndür ve bu adımları sonlandır.selectorbirRTCRtpSenderise, aşağıdaki nesneler için istatistikleri topla veresult'a ekle:selectortarafından gönderilen RTP akışlarını temsil eden tümRTCOutboundRtpStreamStatsnesneleri.- Eklenen
RTCOutboundRtpStreamStatsnesneleri tarafından doğrudan veya dolaylı olarak referans verilen tüm istatistik nesneleri.
selectorbirRTCRtpReceiverise, aşağıdaki nesneler için istatistikleri topla veresult'a ekle:selectortarafından alınan RTP akışlarını temsil eden tümRTCInboundRtpStreamStatsnesneleri.- Eklenen
RTCInboundRtpStreamStatstarafından doğrudan veya dolaylı olarak referans verilen tüm istatistik nesneleri.
result'ı döndür.
8.6 Uygulanması Zorunlu İstatistikler
[WEBRTC-STATS] içinde listelenen istatistikler, geniş bir kullanım senaryosu yelpazesini kapsamak üzere tasarlanmıştır. Bunların tümünün her WebRTC uygulaması tarafından uygulanması gerekmez.
Bir uygulama, ilgili nesneler bir RTCPeerConnection üzerinde mevcut olduğunda, aşağıdaki
type'larda istatistik üretimini DESTEKLEMEK ZORUNDADIR:
RTCStatsType |
Sözlük | Alanlar |
|---|---|---|
"codec" |
RTCCodecStats |
payloadType, mimeType, clockRate, channels,
sdpFmtpLine |
"inbound-rtp" |
RTCRtpStreamStats ·
RTCReceivedRtpStreamStats ·
RTCInboundRtpStreamStats |
ssrc, kind, transportId, codecId,
packetsReceived, packetsLost, jitter,
trackIdentifier, remoteId, framesDecoded,
framesDropped, nackCount, framesReceived,
bytesReceived, totalAudioEnergy, totalSamplesDuration,
packetsDiscarded |
"outbound-rtp" |
RTCRtpStreamStats ·
RTCSentRtpStreamStats ·
RTCOutboundRtpStreamStats |
ssrc, kind, transportId, codecId,
packetsSent, bytesSent, remoteId,
framesEncoded, nackCount, framesSent |
"remote-inbound-rtp" |
RTCRtpStreamStats ·
RTCReceivedRtpStreamStats ·
RTCRemoteInboundRtpStreamStats |
ssrc, kind, transportId, codecId,
packetsReceived, packetsLost, jitter,
localId, roundTripTime |
"remote-outbound-rtp" |
RTCRtpStreamStats ·
RTCSentRtpStreamStats ·
RTCRemoteOutboundRtpStreamStats |
ssrc, kind, transportId, codecId,
packetsSent, bytesSent, localId,
remoteTimestamp |
"media-source" |
RTCMediaSourceStats ·
RTCAudioSourceStats ·
RTCVideoSourceStats |
trackIdentifier, kind, totalAudioEnergy,
totalSamplesDuration (ses);
width, height, framesPerSecond (video) |
"peer-connection" |
RTCPeerConnectionStats |
dataChannelsOpened, dataChannelsClosed |
"data-channel" |
RTCDataChannelStats |
label, protocol, dataChannelIdentifier,
state, messagesSent, bytesSent,
messagesReceived, bytesReceived |
"transport" |
RTCTransportStats |
bytesSent, bytesReceived, selectedCandidatePairId,
localCertificateId, remoteCertificateId |
"candidate-pair" |
RTCIceCandidatePairStats |
transportId, localCandidateId, remoteCandidateId,
state, nominated, bytesSent, bytesReceived,
totalRoundTripTime, responsesReceived,
currentRoundTripTime |
"local-candidate" |
RTCIceCandidateStats |
address, port, protocol, candidateType,
url |
"remote-candidate" |
RTCIceCandidateStats |
address, port, protocol, candidateType,
url |
"certificate" |
RTCCertificateStats |
fingerprint, fingerprintAlgorithm, base64Certificate,
issuerCertificateId |
Bir uygulama, [WEBRTC-STATS] içinde tanımlanan herhangi başka bir istatistiğin üretilmesini DESTEKLEYEBİLİR ve belgelenmemiş istatistikler de ÜRETEBİLİR.
8.7 GetStats Örneği
Kullanıcının kötü ses kalitesi yaşadığı ve uygulamanın bunun nedeninin paket kaybı olup olmadığını belirlemek istediği durumu ele alalım. Aşağıdaki örnek kod bu amaçla kullanılabilir:
async function gatherStats(pc) {
try {
const [sender] = pc.getSenders();
const baselineReport = await sender.getStats();
await new Promise(resolve => setTimeout(resolve, aBit)); // biraz bekle
const currentReport = await sender.getStats();
// geçerli rapordaki öğeleri temel rapor ile karşılaştır
for (const now of currentReport.values()) {
if (now.type != 'outbound-rtp') continue;
// temel rapordan karşılık gelen istatistikleri al
const base = baselineReport.get(now.id);
if (!base) continue;
const remoteNow = currentReport.get(now.remoteId);
const remoteBase = baselineReport.get(base.remoteId);
const packetsSent = now.packetsSent - base.packetsSent;
const packetsReceived = remoteNow.packetsReceived -
remoteBase.packetsReceived;
const fractionLost = (packetsSent - packetsReceived) / packetsSent;
if (fractionLost > 0.3) {
// fractionLost > 0.3 ise, muhtemelen sorumluyu bulmuşuzdur
}
}
} catch (err) {
console.error(err);
}
}