v145 · Web APIs · WebRTC
Expose rtpTimestamp from WebRTC video frames via VideoFrame.metadata()
Chrome 145 adds rtpTimestamp to the metadata returned by VideoFrame.metadata() for WebRTC-sourced video frames, enabling web apps to correlate decoded frames with the original RTP packet timestamps.
background
When processing WebRTC video through the Insertable Streams API, frames arrive as VideoFrame objects. Previously, there was no way to determine which RTP packet a frame came from. The RTP timestamp is essential for A/V sync algorithms, jitter buffer analysis, and custom video processing pipelines that need to match frames to network-level events.
Chrome 145 exposes the rtpTimestamp field in the object returned by VideoFrame.metadata() for frames received via RTCRtpReceiver.
concepts
-
rtpTimestamp Demo
Uses a MediaStreamTrack processor to read
VideoFrame.metadata()from a local video stream and display thertpTimestampand other timing fields available. -
VideoFrame Metadata
Reference for all fields in the
VideoFrameMetadatadictionary —rtpTimestamp,captureTime,receiveTime,presentationTime, and how they relate to each other. -
Jitter Tracker
Computes RFC 3550 inter-arrival jitter across synthetic (or real-webcam)
rtpTimestampsamples and plots the result. Inject a network spike and watch the curve react. -
RTP Clock Converter
Convert an
rtpTimestampvalue to wall-clock seconds, compute inter-frame deltas, and use the frame-drop detector — which flags any gap larger than 1.5× the expected frame interval. Simulate a frame sequence and inject a drop to see the detector fire.
the change
// Chrome 145: rtpTimestamp available on WebRTC-received VideoFrames
const receiver = peerConnection.getReceivers()
.find(r => r.track.kind === 'video');
const streams = receiver.createEncodedStreams();
const transformer = new TransformStream({
transform(chunk, controller) {
// chunk is an EncodedVideoChunk — for decoded frames use MediaStreamTrackProcessor
controller.enqueue(chunk);
}
});
// Via MediaStreamTrackProcessor (decoded frames)
const processor = new MediaStreamTrackProcessor({ track: videoTrack });
const reader = processor.readable.getReader();
while (true) {
const { value: frame, done } = await reader.read();
if (done) break;
const meta = frame.metadata();
console.log('RTP timestamp:', meta.rtpTimestamp); // new in Chrome 145
console.log('Capture time:', meta.captureTime);
console.log('Receive time:', meta.receiveTime);
frame.close();
}