MediaCapabilities
Ask the engine whether a codec, resolution and bitrate will actually decode smoothly and on hardware - before committing to it. The question canPlayType() never answered.
@inject Bit.Butil.MediaCapabilities mediaCapabilitiesMDN reference
True when the runtime exposes navigator.mediaCapabilities.decodingInfo. Broadly available, but not on every engine, so keep a fallback path that simply tries to play.
@inject Bit.Butil.MediaCapabilities mediaCapabilities
var isSupported = await mediaCapabilities.IsSupported();A full configuration in, three flags out: supported at all, smooth (no dropped frames), and power-efficient (hardware rather than CPU). Pick a rung of the ladder and see what the engine says about it - a null answer means the configuration itself was rejected as malformed.
var info = await mediaCapabilities.DecodingInfo(new MediaDecodingConfiguration
{
Type = MediaDecodingType.MediaSource,
Video = new VideoConfiguration
{
ContentType = "video/mp4;codecs=avc1.42E01E",
Width = 1920,
Height = 1080,
Bitrate = 5_000_000,
Framerate = 30
}
});
if (info is { Supported: true, Smooth: true, PowerEfficient: true })
{
// safe to offer this rendition, even on battery
}The same three flags for encoding - what to consult before choosing a MediaRecorder container or a WebCodecs configuration. Support is thinner than for decoding: an engine that answers decoding questions may refuse this one entirely.
var info = await mediaCapabilities.EncodingInfo(new MediaEncodingConfiguration
{
Type = MediaEncodingType.Record,
Video = new VideoConfiguration
{
ContentType = "video/webm;codecs=vp9",
Width = 1280,
Height = 720,
Bitrate = 2_500_000,
Framerate = 30
}
});A query needs at least one track, and audio alone is a valid question. Adding a key-system configuration asks something different again: whether the codec plays smoothly under DRM, which is not the same as whether it plays smoothly in the clear.
var audio = await mediaCapabilities.DecodingInfo(new MediaDecodingConfiguration
{
Type = MediaDecodingType.File,
Audio = new AudioConfiguration { ContentType = "audio/mp4;codecs=mp4a.40.2", Channels = "2", Samplerate = 48000 }
});
var drm = await mediaCapabilities.DecodingInfo(new MediaDecodingConfiguration
{
Type = MediaDecodingType.MediaSource,
Video = new VideoConfiguration { ContentType = "video/mp4;codecs=avc1.640028", Width = 1920, Height = 1080, Bitrate = 6_000_000, Framerate = 30 },
KeySystemConfiguration = new MediaCapabilitiesKeySystemConfiguration
{
KeySystem = "com.widevine.alpha",
InitDataType = "cenc",
VideoRobustness = "HW_SECURE_ALL",
VideoEncryptionScheme = "cenc"
}
});API reference
ValueTask<bool> IsSupported()ValueTask<MediaCapabilitiesInfo?> DecodingInfo(MediaDecodingConfiguration configuration)ValueTask<MediaCapabilitiesInfo?> EncodingInfo(MediaEncodingConfiguration configuration)Type, Video, Audio, KeySystemConfigurationType, Video, AudioContentType, Width, Height, Bitrate, Framerate, HasAlphaChannel, HdrMetadataType, ColorGamut, TransferFunction, ScalabilityMode, SpatialScalabilityContentType, Channels, Bitrate, Samplerate, SpatialRenderingKeySystem, InitDataType, DistinctiveIdentifier, PersistentState, SessionTypes, AudioRobustness, VideoRobustness, AudioEncryptionScheme, VideoEncryptionSchemeSupported, Smooth, PowerEfficient, KeySystemAccessible