RTCRemoteOutboundRtpStreamStats
dictionary's
localId
property is a string which can be used to identify the
RTCInboundRtpStreamStats
object whose
remoteId
matches this value.
Together, these two objects provide statistics about the inbound and outbound sides of the same synchronization source (SSRC).
let localId = rtcRemoteOutboundRtpStreamStats.localId;
A
DOMString
which can be compared to the value of an
RTCInboundRtpStreamStats
对象的
remoteId
property to see if the two represent statistics for each of the two sides of the same set of data received by the local peer.
You can think of the local and remote views of the same RTP stream as pairs, each of which has a reference back to the other one. Thus, if an
RTCStatsReport
includes an
remote-outbound-rtp
statistics object (of type
RTCRemoteOutboundRtpStreamstats
), it should also have a corresponding
inbound-rtp
object. Both of these provide information about the same batch of packets being transmitted from the remote peer to the local device. The difference is that
remote-outbound-rtp
describes statistics about the transmission(s) from the perspective of the remote peer, while
inbound-rtp
offers statistics about the incoming data from the local peer's perspective.
You can examine, try out, and experiment with this example on Glitch.
In this example, we have a pair of functions: the first,
networkTestStart()
, captures an initial report, and the second,
networkTestStop()
, captures a second report, then uses the two reports to output some information about the network conditions... XXX ...
This function simply calls the
RTCPeerConnection
方法
getStats()
to request an
RTCStatsReport
and store it in the variable
startReport
.
let startReport;
async function networkTestStart(pc) {
if (pc) {
startReport = await pc.getStats();
}
}
Given an
RTCPeerConnection
,
pc
, this calls its
getStats()
method to obtain a statistics report object, which it stores in
startReport
for use once the end-of-test data has been collected by
networkTestStop()
.
networkTestStop()
function obtains a second report,
endReport
, then uses the two reports together to determine several... XXX ...
Each statistics record of
type
remote-outbound-rtp
(describing a remote peer's statistics about sending data to the local peer) has a corresponding record of type
inbound-rtp
which describes the local peer's perspective on the same data being moved between the two peers. Let's create a utility function to help us look up the value of a key in the paired statistics object.
findReportEntry()
function shown below examines an
RTCStatsReport
, returning the
RTCStats
-based statistics record which contains the specified
key
—
and
for which the key has the specified
value
. If no match is found (or the statistics report has no record corresponding to the statistics category indicated by
key
.
function findReportEntry(report, key, value) {
for (const stats of report.values()) {
if (stats[key] === value) {
return stats;
}
}
return null;
}
由于
RTCStatsReport
is a JavaScript
地图
, we can iterate over the map's
values()
to examine each of the
RTCStats
-based statistics records in the report until we find one that has the
key
property with the specified
value
. When a match is found, the statistics object is returned.
If no match is found, the function returns
null
.
Now let's look at the
networkTestStop()
function itself. It takes as input the
RTCPeerConnection
being tested, calls
getStats()
to get a new
RTCStatsReport
with current statistics, then computes the results it's looking for, outputting those results as appropriate to the user by appending appropriate HTML to the contents of the
<div>
element whose class is
stats-box
.
async function networkTestStop(pc) {
if (pc) {
let statsBox = document.querySelector(".stats-box");
let endReport = await pc.getStats();
for (let endRemoteOutbound of endReport.values()) {
if (endRemoteOutbound.type === "remote-outbound-rtp") {
let startRemoteOutbound = startReport.get(endRemoteOutbound.id);
if (startRemoteOutbound) {
let startInboundStats = findReportEntry(startReport, "remoteId", startRemoteOutbound.id);
let endInboundStats = findReportEntry(endReport, "remoteId", endRemoteOutbound.id);
let elapsedTime = (endRemoteOutbound.timestamp - startRemoteOutbound.timestamp) / 1000; /* in seconds */
let packetsSent = endRemoteOutbound.packetsSent - startRemoteOutbound.packetsSent;
let bytesSent = endRemoteOutbound.bytesSent - startRemoteOutbound.bytesSent;
let framesDecoded = endInboundStats.framesDecoded - startInboundStats.framesDecoded;
let frameRate = framesDecoded / elapsedTime;
let timeString = "";
if (!isNaN(elapsedTime)) {
timeString = ` representing ${elapsedTime}s`;
}
let frameString = "";
if (!isNaN(framesDecoded)) {
frameString = `Decoded ${framesDecoded} frames for a frame rate of ${frameRate.toFixed(2)} FPS.<br>`;
}
let logEntry = `<div class="stats-entry"><h2>Report ID: ${endRemoteOutbound.id}</h2>` +
`Remote peer sent ${packetsSent} packets ${timeString}.<br>` +
`${frameString}` +
`Data size: ${bytesSent} bytes.</div>`;
statsBox.innerHTML += logEntry;
} else {
statsBox.innerHTML += `<div class="stats-error">Unable to find initial statistics for ID ${endRemoteOutbound.id}.</div>`
}
}
statsBox.scrollTo(0, statsBox.scrollHeight);
}
}
}
Here's what's going on in the
networkTestStop()
function: after calling the
RTCPeerConnection
方法
getStats()
to get the latest statistics report for the connection and storing it in
endReport
, This is an
RTCStatsReport
object, which maps strings taken from the
RTCStatsType
enumerated type to objects of the corresponding
RTCStats
基类型。
Now we can begin to process the results, starting with the ending statistics found in
endReport
. In this case, we're looking for statistics records whose
type
is
remote-outbound-rtp
, so we iterate over the entries in the statistics report until we find an entry of that type. This object is, specifically, of type
RTCRemoteOutboundRtpStreamStats
, and it provides statistics giving details about the state of things
from the perspective of the remote peer
. This statistics record is stored in
endRemoteOutbound
.
Once the ending
remote-outbound-rtp
record is found, we use its
id
property to get its ID. WIth that in hand, we can look up the
remote-outbound-rtp
record in the starting statistics record (
startReport
), which we store into
startRemoteOutbound
.
Now we obtain the
inbound-rtp
statistics that correspond to these two
remote-outbound-rtp
records by finding the
remoteId
property within them whose value is the ID of the
remote-outbound-rtp
record. We use the
findReportEntry()
function described in the previous section for that, storing the located
inbound-rtp
records in
startInboundStats
and
endInboundStats
.
Now we have all the raw statistics needed to calculate the information we want to display, so we do so:
elapsedTime
—that elapsed between the two reports being sent by subtracting the
timestamp
startReport
from that of
endReport
. We then divide by 1000 to convert the result from milliseconds to seconds.
packetsSent
—by subtracting the two reports' values for the
packetsSent
特性。
bytesSent
—is calculated by subtracting the starting statistics object's
bytesSent
property from that of the ending statistics.
framesDecoded
—is determined by subtracting
startRecord
's
framesDecoded
from
endRecord.framesDecoded
.
framesDecoded
by
elapsedTime
.
The remainder of the
networkTestStop()
function constructs the HTML used to display the output of the collected and computed results to the user, then append it to the element
statsBox
, which we're using to show the status updates to the user.
The output log, given the styles used by the example, looks like this:
In the screenshot, we see a heading followed by the scrollable
<div>
we refer to as
statsBox
. The box contains a number of log entries, the last handful of which are visible. Each one represents approximately one second of time (since that's much time we're waiting between calling
networkTestStart()
and
networkTestStop()
).
This example is available on Glitch for you to try out , examine, or remix. You can also access it directly using Glitch's Git server.
| 规范 | 状态 | 注释 |
|---|---|---|
|
Identifiers for WebRTC's Statistics API
The definition of 'RTCRemoteOutboundRtpStreamStats.localId' in that specification. |
候选推荐 | 初始定义。 |
| 桌面 | 移动 | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
localId
|
Chrome No | Edge No | Firefox 68 | IE No | Opera No | Safari No | WebView Android No | Chrome Android No | Firefox Android 68 | Opera Android No | Safari iOS No | Samsung Internet Android No |
完整支持
不支持
RTCRemoteOutboundRtpStreamStats
localId
remoteTimestamp
reportsSent
MediaDevices.getUserMedia()
Navigator.mediaDevices
RTCCertificate
RTCDTMFSender
RTCDTMFToneChangeEvent
RTCDataChannel
RTCDataChannelEvent
RTCDtlsTransport
RTCErrorEvent
RTCIceCandidate
RTCIceTransport
RTCPeerConnection
RTCPeerConnectionIceErrorEvent
RTCPeerConnectionIceEvent
RTCRtpReceiver
RTCRtpSender
RTCRtpTransceiver
RTCSctpTransport
RTCSessionDescription
RTCStatsEvent
RTCStatsReport
RTCTrackEvent