JavaScript HLS client using MediaSourceExtension for smooth video stream playback
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
HLS.js provides utilities for detecting browser capabilities and MediaSource Extensions support to ensure compatibility before initializing playback.
Check browser compatibility and feature support.
/**
* Check complete HLS.js support including MSE and codec support
* @returns true if HLS.js is fully supported
*/
function isSupported(): boolean;
/**
* Check MediaSource Extensions support
* @returns true if MSE is available
*/
function isMSESupported(): boolean;
/**
* Get MediaSource constructor if available
* @returns MediaSource constructor or undefined
*/
function getMediaSource(): typeof MediaSource | undefined;Usage Examples:
import Hls, { isSupported, isMSESupported, getMediaSource } from "hls.js";
// Check full HLS.js support
if (isSupported()) {
console.log("HLS.js is fully supported");
const hls = new Hls();
// Use HLS.js for playback
} else {
console.log("HLS.js not supported, check for native support");
// Check for native HLS support (Safari)
const video = document.createElement("video");
if (video.canPlayType("application/vnd.apple.mpegurl")) {
console.log("Native HLS support available");
video.src = "https://example.com/stream.m3u8";
} else {
console.error("No HLS support available");
}
}
// Check MSE support specifically
if (isMSESupported()) {
console.log("MediaSource Extensions supported");
} else {
console.log("MSE not supported");
}
// Get MediaSource constructor
const MediaSourceClass = getMediaSource();
if (MediaSourceClass) {
console.log("MediaSource available:", MediaSourceClass.isTypeSupported("video/mp4"));
}Access support detection through the Hls class.
declare class Hls {
/**
* Check complete HLS.js support
* @returns true if fully supported
*/
static isSupported(): boolean;
/**
* Check MediaSource Extensions support
* @returns true if MSE is available
*/
static isMSESupported(): boolean;
/**
* Get MediaSource constructor
* @returns MediaSource constructor or undefined
*/
static getMediaSource(): typeof MediaSource | undefined;
}Usage Examples:
// Using static methods
if (Hls.isSupported()) {
const hls = new Hls();
// Initialize HLS.js
} else if (Hls.isMSESupported()) {
console.log("MSE available but HLS.js not fully supported");
} else {
console.log("No MSE support");
}
// Check MediaSource capabilities
const MediaSource = Hls.getMediaSource();
if (MediaSource) {
console.log("MP4 support:", MediaSource.isTypeSupported('video/mp4; codecs="avc1.42E01E,mp4a.40.2"'));
console.log("WebM support:", MediaSource.isTypeSupported('video/webm; codecs="vp9,opus"'));
}Check support for specific codecs and formats.
// Check codec support through MediaSource
function checkCodecSupport(): void {
const MediaSource = getMediaSource();
if (!MediaSource) return;
// Common HLS codecs
const codecs = [
'video/mp4; codecs="avc1.42E01E,mp4a.40.2"', // H.264 + AAC
'video/mp4; codecs="avc1.4d401f,mp4a.40.2"', // H.264 Main + AAC
'video/mp4; codecs="hev1.1.6.L93.B0,mp4a.40.2"', // H.265 + AAC
'audio/mp4; codecs="mp4a.40.2"', // AAC audio
'audio/mpeg' // MP3 audio
];
codecs.forEach(codec => {
console.log(`${codec}: ${MediaSource.isTypeSupported(codec)}`);
});
}Check for additional browser features used by HLS.js.
/**
* Check if Fetch API is supported for loading
* @returns true if fetch is available
*/
function fetchSupported(): boolean;Usage Examples:
import { fetchSupported } from "hls.js";
// Check loader support
if (fetchSupported()) {
console.log("Fetch API available - will use FetchLoader");
} else {
console.log("Fetch API not available - will use XhrLoader");
}
// Configure loader preference
const hls = new Hls({
// Force specific loader
loader: fetchSupported() ? FetchLoader : XhrLoader
});Implement progressive enhancement based on capabilities.
function setupVideoPlayer(videoElement: HTMLVideoElement, manifestUrl: string): void {
if (Hls.isSupported()) {
// Use HLS.js with full features
const hls = new Hls({
// Enable advanced features for supported browsers
enableWorker: true,
enableSoftwareAES: true,
lowLatencyMode: true
});
hls.attachMedia(videoElement);
hls.loadSource(manifestUrl);
console.log("Using HLS.js with advanced features");
} else if (videoElement.canPlayType("application/vnd.apple.mpegurl")) {
// Native HLS support (Safari)
videoElement.src = manifestUrl;
console.log("Using native HLS support");
} else {
// No HLS support - show error or fallback
console.error("HLS not supported");
videoElement.innerHTML = `
<p>Your browser does not support HLS video playback.</p>
<p>Please use a modern browser or try a different video format.</p>
`;
}
}Handle browser-specific behaviors and limitations.
function getBrowserCapabilities(): {
hasNativeHLS: boolean;
hasMSE: boolean;
hasWorkerSupport: boolean;
hasWasm: boolean;
} {
const video = document.createElement("video");
return {
hasNativeHLS: video.canPlayType("application/vnd.apple.mpegurl") !== "",
hasMSE: isMSESupported(),
hasWorkerSupport: typeof Worker !== "undefined",
hasWasm: typeof WebAssembly !== "undefined"
};
}
// Use capabilities for configuration
const capabilities = getBrowserCapabilities();
const hls = new Hls({
enableWorker: capabilities.hasWorkerSupport,
enableSoftwareAES: !capabilities.hasWasm, // Use SW AES if no WASM
// Safari-specific adjustments
...(capabilities.hasNativeHLS && {
manifestLoadingTimeOut: 30000,
fragLoadingTimeOut: 60000
})
});Handle graceful degradation when features aren't supported.
function createHlsWithFallbacks(config?: Partial<HlsConfig>): Hls | null {
if (!isSupported()) {
console.warn("HLS.js not supported");
return null;
}
const capabilities = getBrowserCapabilities();
const safeConfig: Partial<HlsConfig> = {
...config,
// Disable features that may not be supported
enableWorker: capabilities.hasWorkerSupport && (config?.enableWorker ?? true),
enableSoftwareAES: config?.enableSoftwareAES ?? true,
// Conservative settings for older browsers
maxBufferLength: capabilities.hasMSE ? (config?.maxBufferLength ?? 30) : 10,
maxBufferSize: capabilities.hasMSE ? (config?.maxBufferSize ?? 60 * 1000 * 1000) : 10 * 1000 * 1000
};
try {
return new Hls(safeConfig);
} catch (error) {
console.error("Failed to create HLS instance:", error);
return null;
}
}HLS.js supports modern browsers with MediaSource Extensions:
interface MediaCapabilitiesInfo {
supported: boolean;
smooth: boolean;
powerEfficient: boolean;
}
interface MediaDecodingConfiguration {
type: "media-source" | "file";
video?: VideoConfiguration;
audio?: AudioConfiguration;
}
interface VideoConfiguration {
contentType: string;
width: number;
height: number;
bitrate: number;
framerate: number;
}
interface AudioConfiguration {
contentType: string;
channels?: string;
bitrate?: number;
samplerate?: number;
}