Skip to content

Commit

Permalink
Multi-DRM Support (#4930)
Browse files Browse the repository at this point in the history
* Add support for com.apple.fps keySystem

* Improve support for DRM key-systems and key handling
Resolves #2833 #2737 #4318 #4538

* Update README `licenseXhrSetup` example

* Update api-extractor markdown

* Attach CDM on start when even when initial fragments do not have a key associated with them

* Handle expired key status correctly

* Map key-sessions by key ID and log key ID more often than URI

* Support "clear-lead" key-session creation without new config

* Emit and handle FRAG_PARSING_ERROR from transmuxers (#5018)

* Emit and handle FRAG_PARSING_ERROR from transmuxers
Related to #5011
* Switch levels on Key and Fragment parsing errors or escalate to fatal error

* Route all key-system errors to `onFragmentOrKeyLoadError`

* Populate EMEKeyError.err for better demo error logging

* Remove `useEmeEncryptedEvent` and mark `widevineLicenseUrl` as deprecated in API.md

* Add support for EXT-X-SESSION-KEY tags (for key-system access on manifest loaded)
#4927

* Throw before licenseXhrSetup if key was removed

* Make key session promise chain more consice

* Stop on fatal key system errors

* Only request access to key-systems for keys matching those found in the config one at time (to avoid gaining access to WV and PR on Edge)

* Modify key-system helpers so that it's easier to support additional key-system strings

* Add undocumented `generateRequest` ("Content ID") filter

Co-authored-by: Vincent Valot <vincent.valot@bedrockstreaming.com>
  • Loading branch information
robwalch and valotvince committed Dec 15, 2022
1 parent ece5004 commit 800c35f
Show file tree
Hide file tree
Showing 42 changed files with 3,631 additions and 1,352 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ HLS.js is written in [ECMAScript6] (`*.js`) and [TypeScript] (`*.ts`) (strongly
- AES-128 decryption
- SAMPLE-AES decryption (only supported if using MPEG-2 TS container)
- Encrypted media extensions (EME) support for DRM (digital rights management)
- Widevine CDM (only tested with [shaka-packager](https://github.com/google/shaka-packager) test-stream on [the demo page](https://hls-js.netlify.app/demo/?src=https%3A%2F%2Fstorage.googleapis.com%2Fshaka-demo-assets%2Fangel-one-widevine-hls%2Fhls.m3u8&demoConfig=eyJlbmFibGVTdHJlYW1pbmciOnRydWUsImF1dG9SZWNvdmVyRXJyb3IiOnRydWUsInN0b3BPblN0YWxsIjpmYWxzZSwiZHVtcGZNUDQiOmZhbHNlLCJsZXZlbENhcHBpbmciOi0xLCJsaW1pdE1ldHJpY3MiOi0xfQ==))
- FairPlay, PlayReady, Widevine CDMs with fmp4 segments
- CEA-608/708 captions
- WebVTT subtitles
- Alternate Audio Track Rendition (Master Playlist with Alternative Audio) for VoD and Live playlists
Expand Down Expand Up @@ -113,14 +113,16 @@ The following tags are added to their respective fragment's attribute list but a

For a complete list of issues, see ["Top priorities" in the Release Planning and Backlog project tab](https://github.com/video-dev/hls.js/projects/6). Codec support is dependent on the runtime environment (for example, not all browsers on the same OS support HEVC).

- FairPlay and PlayReady DRM ( See [#3779](https://github.com/video-dev/hls.js/issues/2360) and [issues labeled DRM](https://github.com/video-dev/hls.js/issues?q=is%3Aissue+is%3Aopen+label%3ADRM))
- Advanced variant selection based on runtime media capabilities (See issues labeled [`media-capabilities`](https://github.com/video-dev/hls.js/labels/media-capabilities))
- HLS Content Steering
- HLS Interstitials
- `#EXT-X-DEFINE` variable substitution
- `#EXT-X-GAP` filling [#2940](https://github.com/video-dev/hls.js/issues/2940)
- `#EXT-X-I-FRAME-STREAM-INF` I-frame Media Playlist files
- `SAMPLE-AES` with fmp4, aac, mp3, vtt... segments (MPEG-2 TS only)
- FairPlay, PlayReady, Widevine DRM with MPEG-2 TS segments
- Advanced variant selection based on runtime media capabilities (See issues labeled [`media-capabilities`](https://github.com/video-dev/hls.js/labels/media-capabilities))
- MP3 elementary stream audio in IE and Edge (<=18) on Windows 10 (See [#1641](https://github.com/video-dev/hls.js/issues/1641) and [Microsoft answers forum](https://answers.microsoft.com/en-us/ie/forum/all/ie11-on-windows-10-cannot-play-hls-with-mp3/2da994b5-8dec-4ae9-9201-7d138ede49d9))

### Server-side-rendering (SSR) and `require` from a Node.js runtime

Expand Down
121 changes: 90 additions & 31 deletions api-extractor/report/hls.js.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,12 @@ export class DateRange {
export type DRMSystemOptions = {
audioRobustness?: string;
videoRobustness?: string;
audioEncryptionScheme?: string | null;
videoEncryptionScheme?: string | null;
persistentState?: MediaKeysRequirement;
distinctiveIdentifier?: MediaKeysRequirement;
sessionTypes?: string[];
sessionType?: string;
};

// Warning: (ae-missing-release-tag) "ElementaryStreamInfo" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
Expand Down Expand Up @@ -352,10 +358,11 @@ export enum ElementaryStreamTypes {
//
// @public (undocumented)
export type EMEControllerConfig = {
licenseXhrSetup?: (xhr: XMLHttpRequest, url: string) => void;
licenseResponseCallback?: (xhr: XMLHttpRequest, url: string) => ArrayBuffer;
licenseXhrSetup?: (this: Hls, xhr: XMLHttpRequest, url: string, keyContext: MediaKeySessionContext, licenseChallenge: Uint8Array) => void | Promise<Uint8Array | void>;
licenseResponseCallback?: (this: Hls, xhr: XMLHttpRequest, url: string, keyContext: MediaKeySessionContext) => ArrayBuffer;
emeEnabled: boolean;
widevineLicenseUrl?: string;
drmSystems: DRMSystemsConfiguration;
drmSystemOptions: DRMSystemOptions;
requestMediaKeySystemAccessFunc: MediaKeyFunc | null;
};
Expand All @@ -369,6 +376,8 @@ export interface ErrorData {
// (undocumented)
bytes?: number;
// (undocumented)
chunkMeta?: ChunkMetadata;
// (undocumented)
context?: PlaylistLoaderContext;
// (undocumented)
details: ErrorDetails;
Expand Down Expand Up @@ -457,6 +466,16 @@ export enum ErrorDetails {
// (undocumented)
KEY_SYSTEM_NO_SESSION = "keySystemNoSession",
// (undocumented)
KEY_SYSTEM_SERVER_CERTIFICATE_REQUEST_FAILED = "keySystemServerCertificateRequestFailed",
// (undocumented)
KEY_SYSTEM_SERVER_CERTIFICATE_UPDATE_FAILED = "keySystemServerCertificateUpdateFailed",
// (undocumented)
KEY_SYSTEM_SESSION_UPDATE_FAILED = "keySystemSessionUpdateFailed",
// (undocumented)
KEY_SYSTEM_STATUS_INTERNAL_ERROR = "keySystemStatusInternalError",
// (undocumented)
KEY_SYSTEM_STATUS_OUTPUT_RESTRICTED = "keySystemStatusOutputRestricted",
// (undocumented)
LEVEL_EMPTY_ERROR = "levelEmptyError",
// (undocumented)
LEVEL_LOAD_ERROR = "levelLoadError",
Expand Down Expand Up @@ -733,7 +752,6 @@ export class Fragment extends BaseSegment {
cc: number;
// (undocumented)
clearElementaryStreamInfo(): void;
createInitializationVector(segmentNumber: number): Uint8Array;
// (undocumented)
data?: Uint8Array;
// (undocumented)
Expand All @@ -754,12 +772,16 @@ export class Fragment extends BaseSegment {
endPTS?: number;
// (undocumented)
initSegment: Fragment | null;
// Warning: (ae-forgotten-export) The symbol "KeyLoaderContext" needs to be exported by the entry point hls.d.ts
//
// (undocumented)
keyLoader: Loader<KeyLoaderContext> | null;
// (undocumented)
level: number;
// (undocumented)
levelkey?: LevelKey;
levelkeys?: {
[key: string]: LevelKey;
};
// (undocumented)
loader: Loader<FragmentLoaderContext> | null;
// (undocumented)
Expand All @@ -770,10 +792,11 @@ export class Fragment extends BaseSegment {
programDateTime: number | null;
// (undocumented)
rawProgramDateTime: string | null;
setDecryptDataFromLevelKey(levelkey: LevelKey, segmentNumber: number): LevelKey;
// (undocumented)
setElementaryStreamInfo(type: ElementaryStreamTypes, startPTS: number, endPTS: number, startDTS: number, endDTS: number, partial?: boolean): void;
// (undocumented)
setKeyFormat(keyFormat: KeySystemFormats): void;
// (undocumented)
sn: number | 'initSegment';
// (undocumented)
start: number;
Expand Down Expand Up @@ -889,7 +912,7 @@ class Hls implements HlsEventEmitter {
// (undocumented)
readonly config: HlsConfig;
// (undocumented)
createController(ControllerClass: any, fragmentTracker: any, components: any): any;
createController(ControllerClass: any, components: any): any;
get currentLevel(): number;
// Warning: (ae-setter-with-docs) The doc comment for the property "currentLevel" must appear on the getter, not the setter.
set currentLevel(newLevel: number);
Expand Down Expand Up @@ -1221,26 +1244,42 @@ export interface InitPTSFoundData {
export interface KeyLoadedData {
// (undocumented)
frag: Fragment;
// Warning: (ae-forgotten-export) The symbol "KeyLoaderInfo" needs to be exported by the entry point hls.d.ts
//
// (undocumented)
keyInfo: KeyLoaderInfo;
}

// Warning: (ae-missing-release-tag) "KeyLoaderContext" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
// Warning: (ae-missing-release-tag) "KeyLoadingData" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export interface KeyLoaderContext extends FragmentLoaderContext {
export interface KeyLoadingData {
// (undocumented)
frag: Fragment;
}

// Warning: (ae-missing-release-tag) "KeyLoadingData" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
// Warning: (ae-missing-release-tag) "KeySystemFormats" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export interface KeyLoadingData {
export enum KeySystemFormats {
// (undocumented)
frag: Fragment;
CLEARKEY = "org.w3.clearkey",
// (undocumented)
FAIRPLAY = "com.apple.streamingkeydelivery",
// (undocumented)
PLAYREADY = "com.microsoft.playready",
// (undocumented)
WIDEVINE = "urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed"
}

// Warning: (ae-missing-release-tag) "KeySystems" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export enum KeySystems {
// (undocumented)
CLEARKEY = "org.w3.clearkey",
// (undocumented)
FAIRPLAY = "com.apple.fps",
// (undocumented)
PLAYREADY = "com.microsoft.playready",
// (undocumented)
Expand Down Expand Up @@ -1402,6 +1441,8 @@ export class LevelDetails {
// (undocumented)
get edge(): number;
// (undocumented)
encryptedFragments: Fragment[];
// (undocumented)
endCC: number;
// (undocumented)
endSN: number;
Expand Down Expand Up @@ -1471,28 +1512,38 @@ export class LevelDetails {
version: number | null;
}

// Warning: (ae-forgotten-export) The symbol "DecryptData" needs to be exported by the entry point hls.d.ts
// Warning: (ae-missing-release-tag) "LevelKey" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export class LevelKey {
export class LevelKey implements DecryptData {
constructor(method: string, uri: string, format: string, formatversions?: number[], iv?: Uint8Array | null);
// (undocumented)
static fromURI(uri: string): LevelKey;
static clearKeyUriToKeyIdMap(): void;
// (undocumented)
static fromURL(baseUrl: string, relativeUrl: string): LevelKey;
readonly encrypted: boolean;
// (undocumented)
getDecryptData(sn: number | 'initSegment'): LevelKey | null;
// (undocumented)
readonly isCommonEncryption: boolean;
// (undocumented)
isSupported(): boolean;
// (undocumented)
iv: Uint8Array | null;
// (undocumented)
key: Uint8Array | null;
// (undocumented)
keyFormat: string | null;
readonly keyFormat: string;
// (undocumented)
readonly keyFormatVersions: number[];
// (undocumented)
keyFormatVersions: string | null;
keyId: Uint8Array | null;
// (undocumented)
keyID: string | null;
readonly method: string;
// (undocumented)
method: string | null;
pssh: Uint8Array | null;
// (undocumented)
get uri(): string | null;
readonly uri: string;
}

// Warning: (ae-missing-release-tag) "LevelLoadedData" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
Expand Down Expand Up @@ -1792,6 +1843,8 @@ export interface ManifestLoadedData {
// (undocumented)
sessionData: Record<string, AttrList> | null;
// (undocumented)
sessionKeys: LevelKey[] | null;
// (undocumented)
stats: LoaderStats;
// (undocumented)
subtitles?: MediaPlaylist[];
Expand Down Expand Up @@ -1822,6 +1875,10 @@ export interface ManifestParsedData {
// (undocumented)
levels: Level[];
// (undocumented)
sessionData: Record<string, AttrList> | null;
// (undocumented)
sessionKeys: LevelKey[] | null;
// (undocumented)
stats: LoaderStats;
// (undocumented)
subtitleTracks: MediaPlaylist[];
Expand Down Expand Up @@ -2236,18 +2293,20 @@ export interface UserdataSample {

// Warnings were encountered during analysis:
//
// src/config.ts:169:3 - (ae-forgotten-export) The symbol "ILogger" needs to be exported by the entry point hls.d.ts
// src/config.ts:179:3 - (ae-forgotten-export) The symbol "AudioStreamController" needs to be exported by the entry point hls.d.ts
// src/config.ts:180:3 - (ae-forgotten-export) The symbol "AudioTrackController" needs to be exported by the entry point hls.d.ts
// src/config.ts:182:3 - (ae-forgotten-export) The symbol "SubtitleStreamController" needs to be exported by the entry point hls.d.ts
// src/config.ts:183:3 - (ae-forgotten-export) The symbol "SubtitleTrackController" needs to be exported by the entry point hls.d.ts
// src/config.ts:184:3 - (ae-forgotten-export) The symbol "TimelineController" needs to be exported by the entry point hls.d.ts
// src/config.ts:186:3 - (ae-forgotten-export) The symbol "EMEController" needs to be exported by the entry point hls.d.ts
// src/config.ts:189:3 - (ae-forgotten-export) The symbol "CMCDController" needs to be exported by the entry point hls.d.ts
// src/config.ts:191:3 - (ae-forgotten-export) The symbol "AbrController" needs to be exported by the entry point hls.d.ts
// src/config.ts:192:3 - (ae-forgotten-export) The symbol "BufferController" needs to be exported by the entry point hls.d.ts
// src/config.ts:193:3 - (ae-forgotten-export) The symbol "CapLevelController" needs to be exported by the entry point hls.d.ts
// src/config.ts:194:3 - (ae-forgotten-export) The symbol "FPSController" needs to be exported by the entry point hls.d.ts
// src/config.ts:87:3 - (ae-forgotten-export) The symbol "MediaKeySessionContext" needs to be exported by the entry point hls.d.ts
// src/config.ts:102:3 - (ae-forgotten-export) The symbol "DRMSystemsConfiguration" needs to be exported by the entry point hls.d.ts
// src/config.ts:205:3 - (ae-forgotten-export) The symbol "ILogger" needs to be exported by the entry point hls.d.ts
// src/config.ts:215:3 - (ae-forgotten-export) The symbol "AudioStreamController" needs to be exported by the entry point hls.d.ts
// src/config.ts:216:3 - (ae-forgotten-export) The symbol "AudioTrackController" needs to be exported by the entry point hls.d.ts
// src/config.ts:218:3 - (ae-forgotten-export) The symbol "SubtitleStreamController" needs to be exported by the entry point hls.d.ts
// src/config.ts:219:3 - (ae-forgotten-export) The symbol "SubtitleTrackController" needs to be exported by the entry point hls.d.ts
// src/config.ts:220:3 - (ae-forgotten-export) The symbol "TimelineController" needs to be exported by the entry point hls.d.ts
// src/config.ts:222:3 - (ae-forgotten-export) The symbol "EMEController" needs to be exported by the entry point hls.d.ts
// src/config.ts:225:3 - (ae-forgotten-export) The symbol "CMCDController" needs to be exported by the entry point hls.d.ts
// src/config.ts:227:3 - (ae-forgotten-export) The symbol "AbrController" needs to be exported by the entry point hls.d.ts
// src/config.ts:228:3 - (ae-forgotten-export) The symbol "BufferController" needs to be exported by the entry point hls.d.ts
// src/config.ts:229:3 - (ae-forgotten-export) The symbol "CapLevelController" needs to be exported by the entry point hls.d.ts
// src/config.ts:230:3 - (ae-forgotten-export) The symbol "FPSController" needs to be exported by the entry point hls.d.ts

// (No @packageDocumentation comment for this package)

Expand Down

0 comments on commit 800c35f

Please sign in to comment.