the Chromium logo

The Chromium Projects


Everything you need to know about audio/video inside Chromium and Chromium OS!

Whom To Contact

It's best to have discussions on or for media specific matters.

We are component Internals>Media on the Chromium bug tracker.


See media/ For historical reference, here's the original design doc for HTML5 audio/video.

Codec and Container Support

Container formats

Codec formats (Decode Only)



Code Location


media/ - Home to all things media! media/audio - OS audio input/output abstractions media/video/capture - OS camera input abstraction media/video - software/hardware video decoder interfaces + implementations third_party/ffmpeg - Chromium's copy of FFmpeg third_party/libvpx - Chromium's copy of libvpx


third_party/blink/renderer/core/html/media/html_media_element.{cpp,h,idl} - media element base class

third_party/blink/renderer/core/html/media/html_audio_element.{cpp,h,idl} - audio element implementation

third_party/blink/renderer/core/html/media/html_video_element.{cpp,h,idl} - video element implementation

Particularly Interesting Bits

media/base/ - defines canPlayType() behaviour and file extension mapping

media/blink/buffered_data_source.{cc,h} - Chromium's main implementation of DataSource for the media pipeline

media/blink/buffered_resource_loader.{cc,h} - Implements the sliding window buffering strategy (see below)

third_party/blink/public/platform/web_media_player.h - Blink's media player interface for providing HTML5 audio/video functionality

media/blink/webmediaplayer_impl.{cc,h} - Chromium's main implementation of WebMediaPlayer

How does everything get instantiated?

WebFrameClient::createMediaPlayer() is the Blink embedder API for creating a WebMediaPlayer and passing it back to Blink. Every HTML5 audio/video element will ask the embedder to create a WebMediaPlayer.

For Chromium this is handled in RenderFrameImpl.

GN Flags

There are a few GN flags which can alter the behaviour of Chromium's HTML5 audio/video implementation.


Overrides which version of FFmpeg to use

Default: $(branding)


Chrome - includes additional proprietary codecs (MP3, etc..) for use with Google Chrome

Chromium - builds default set of codecs


Alters the list of codecs Chromium claims to support, which affects <source> and canPlayType() behaviour

Default: 0(gyp)/false(gn)


0/false - <source> and canPlayType() assume the default set of codecs

1/true - <source> and canPlayType() assume they support additional proprietary codecs

How the %#$& does buffering work?

Chromium uses a combination of range requests and an in-memory sliding window to buffer media. We have a low and high watermark that is used to determine when to purposely stall the HTTP request and when to resume the HTTP request.

It's complicated, so here's a picture: