Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

media-tracks

Package Overview
Dependencies
Maintainers
1
Versions
19
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

media-tracks - npm Package Compare versions

Comparing version 0.1.2 to 0.2.0

dist/types/utils.d.ts

103

dist/audio-rendition-list.js

@@ -1,40 +0,79 @@

import { audioRenditionToList } from "./audio-rendition.js";
import { RenditionEvent } from "./rendition-event.js";
import { getPrivate } from "./utils.js";
function addRendition(track, rendition) {
const renditionList = getPrivate(track).media.audioRenditions;
if (!getPrivate(rendition).list) {
getPrivate(rendition).list = renditionList;
getPrivate(rendition).track = track;
}
const { collection } = getPrivate(renditionList);
collection.add(rendition);
const index = collection.size - 1;
if (!(index in AudioRenditionList.prototype)) {
Object.defineProperty(AudioRenditionList.prototype, index, {
get() {
return getCurrentRenditions(this)[index];
}
});
}
queueMicrotask(() => {
if (!track.enabled)
return;
renditionList.dispatchEvent(new RenditionEvent("addrendition", { rendition }));
});
}
function removeRendition(rendition) {
const renditionList = getPrivate(rendition).list;
const collection = getPrivate(renditionList).collection;
collection.delete(rendition);
queueMicrotask(() => {
const track = getPrivate(rendition).track;
if (!track.enabled)
return;
renditionList.dispatchEvent(new RenditionEvent("removerendition", { rendition }));
});
}
function selectedChanged(rendition) {
const renditionList = getPrivate(rendition).list;
if (!renditionList || getPrivate(renditionList).changeRequested)
return;
getPrivate(renditionList).changeRequested = true;
queueMicrotask(() => {
delete getPrivate(renditionList).changeRequested;
const track = getPrivate(rendition).track;
if (!track.enabled)
return;
renditionList.dispatchEvent(new Event("change"));
});
}
function getCurrentRenditions(renditionList) {
return [...getPrivate(renditionList).collection].filter((rendition) => {
return getPrivate(rendition).track.enabled;
});
}
class AudioRenditionList extends EventTarget {
#renditions = [];
#addRenditionCallback;
#removeRenditionCallback;
#changeCallback;
constructor() {
super();
getPrivate(this).collection = /* @__PURE__ */ new Set();
}
[Symbol.iterator]() {
return this.#renditions.values();
return getCurrentRenditions(this).values();
}
get length() {
return this.#renditions.length;
return getCurrentRenditions(this).length;
}
add(rendition) {
audioRenditionToList.set(rendition, this);
const length = this.#renditions.push(rendition);
const index = length - 1;
if (!(index in AudioRenditionList.prototype)) {
Object.defineProperty(AudioRenditionList.prototype, index, {
get() {
return this.#renditions[index];
}
});
}
queueMicrotask(() => {
this.dispatchEvent(new RenditionEvent("addrendition", { rendition }));
});
getRenditionById(id) {
return getCurrentRenditions(this).find((rendition) => `${rendition.id}` === `${id}`) ?? null;
}
remove(rendition) {
audioRenditionToList.delete(rendition);
this.#renditions.splice(this.#renditions.indexOf(rendition), 1);
this.dispatchEvent(new RenditionEvent("removerendition", { rendition }));
get selectedIndex() {
return getCurrentRenditions(this).findIndex((rendition) => rendition.selected);
}
getRenditionById(id) {
return this.#renditions.find((rendition) => `${rendition.id}` === `${id}`) ?? null;
set selectedIndex(index) {
for (const [i, rendition] of getCurrentRenditions(this).entries()) {
rendition.selected = i === index;
}
}
get activeIndex() {
return this.#renditions.findIndex((rendition) => rendition.active);
}
get onaddrendition() {

@@ -58,6 +97,3 @@ return this.#addRenditionCallback;

if (this.#removeRenditionCallback) {
this.removeEventListener(
"removerendition",
this.#removeRenditionCallback
);
this.removeEventListener("removerendition", this.#removeRenditionCallback);
this.#removeRenditionCallback = void 0;

@@ -85,3 +121,6 @@ }

export {
AudioRenditionList
AudioRenditionList,
addRendition,
removeRendition,
selectedChanged
};

@@ -1,3 +0,2 @@

const audioRenditionToList = /* @__PURE__ */ new Map();
const changeRequested = /* @__PURE__ */ new Map();
import { selectedChanged } from "./audio-rendition-list.js";
class AudioRendition {

@@ -8,47 +7,15 @@ src;

codec;
#enabled = false;
#active = false;
get enabled() {
return this.#enabled;
#selected = false;
get selected() {
return this.#selected;
}
set enabled(val) {
if (this.#enabled === val)
set selected(val) {
if (this.#selected === val)
return;
this.#enabled = val;
const renditionList = audioRenditionToList.get(this);
if (!renditionList || changeRequested.get(renditionList))
return;
changeRequested.set(renditionList, true);
queueMicrotask(() => {
changeRequested.delete(renditionList);
renditionList.dispatchEvent(new Event("change"));
});
this.#selected = val;
selectedChanged(this);
}
get active() {
return this.#active;
}
set active(val) {
if (this.#active === val)
return;
this.#active = val;
if (val !== true)
return;
const renditionList = audioRenditionToList.get(this) ?? [];
let hasInactivated = false;
for (const rendition of renditionList) {
if (rendition === this)
continue;
rendition.active = false;
hasInactivated = true;
}
if (hasInactivated) {
queueMicrotask(() => {
renditionList.dispatchEvent(new Event("renditionchange"));
});
}
}
}
export {
AudioRendition,
audioRenditionToList
AudioRendition
};

@@ -1,8 +0,52 @@

import { audioTrackToList } from "./audio-track.js";
import { TrackEvent } from "./track-event.js";
import { getPrivate } from "./utils.js";
function addAudioTrack(media, track) {
const trackList = media.audioTracks;
if (!getPrivate(track).list) {
getPrivate(track).list = trackList;
getPrivate(track).media = media;
}
const { collection } = getPrivate(trackList);
collection.add(track);
const index = collection.size - 1;
if (!(index in AudioTrackList.prototype)) {
Object.defineProperty(AudioTrackList.prototype, index, {
get() {
return [...collection][index];
}
});
}
queueMicrotask(() => {
trackList.dispatchEvent(new TrackEvent("addtrack", { track }));
});
}
function removeAudioTrack(track) {
const trackList = getPrivate(track).list;
const collection = getPrivate(trackList).collection;
collection.delete(track);
queueMicrotask(() => {
trackList.dispatchEvent(new TrackEvent("removetrack", { track }));
});
}
function enabledChanged(track) {
const trackList = getPrivate(track).list;
if (!trackList || getPrivate(trackList).changeRequested)
return;
getPrivate(trackList).changeRequested = true;
queueMicrotask(() => {
delete getPrivate(trackList).changeRequested;
trackList.dispatchEvent(new Event("change"));
});
}
class AudioTrackList extends EventTarget {
#tracks = [];
#addTrackCallback;
#removeTrackCallback;
#changeCallback;
constructor() {
super();
getPrivate(this).collection = /* @__PURE__ */ new Set();
}
get #tracks() {
return getPrivate(this).collection;
}
[Symbol.iterator]() {

@@ -12,26 +56,6 @@ return this.#tracks.values();

get length() {
return this.#tracks.length;
return this.#tracks.size;
}
add(track) {
audioTrackToList.set(track, this);
const length = this.#tracks.push(track);
const index = length - 1;
if (!(index in AudioTrackList.prototype)) {
Object.defineProperty(AudioTrackList.prototype, index, {
get() {
return this.#tracks[index];
}
});
}
queueMicrotask(() => {
this.dispatchEvent(new TrackEvent("addtrack", { track }));
});
}
remove(track) {
audioTrackToList.delete(track);
this.#tracks.splice(this.#tracks.indexOf(track), 1);
this.dispatchEvent(new TrackEvent("removetrack", { track }));
}
getTrackById(id) {
return this.#tracks.find((track) => track.id === id) ?? null;
return [...this.#tracks].find((track) => track.id === id) ?? null;
}

@@ -79,3 +103,6 @@ get onaddtrack() {

export {
AudioTrackList
AudioTrackList,
addAudioTrack,
enabledChanged,
removeAudioTrack
};
import { AudioRendition } from "./audio-rendition.js";
import { AudioRenditionList } from "./audio-rendition-list.js";
const audioTrackToList = /* @__PURE__ */ new Map();
const changeRequested = /* @__PURE__ */ new Map();
import { enabledChanged } from "./audio-track-list.js";
import { addRendition, removeRendition } from "./audio-rendition-list.js";
const AudioTrackKind = {

@@ -20,3 +19,2 @@ alternative: "alternative",

#enabled = false;
#renditions = new AudioRenditionList();
addRendition(src, codec, bitrate) {

@@ -27,7 +25,7 @@ const rendition = new AudioRendition();

rendition.bitrate = bitrate;
this.#renditions.add(rendition);
addRendition(this, rendition);
return rendition;
}
get renditions() {
return this.#renditions;
removeRendition(rendition) {
removeRendition(rendition);
}

@@ -41,10 +39,3 @@ get enabled() {

this.#enabled = val;
const trackList = audioTrackToList.get(this);
if (!trackList || changeRequested.get(trackList))
return;
changeRequested.set(trackList, true);
queueMicrotask(() => {
changeRequested.delete(trackList);
trackList.dispatchEvent(new Event("change"));
});
enabledChanged(this);
}

@@ -54,4 +45,3 @@ }

AudioTrack,
AudioTrackKind,
audioTrackToList
AudioTrackKind
};
export * from "./mixin.js";
export * from "./video-track.js";
export * from "./video-track-list.js";
export * from "./video-rendition.js";
export * from "./video-rendition-list.js";
export * from "./audio-track.js";
export * from "./audio-track-list.js";
export * from "./audio-rendition.js";
export * from "./audio-rendition-list.js";
export * from "./track-event.js";
export * from "./rendition-event.js";
import { VideoTrack } from "./video-track.js";
import { VideoTrackList } from "./video-track-list.js";
import { VideoRendition } from "./video-rendition.js";
import { VideoRenditionList } from "./video-rendition-list.js";
import { AudioTrack } from "./audio-track.js";
import { AudioTrackList } from "./audio-track-list.js";
import { AudioRendition } from "./audio-rendition.js";
import { AudioRenditionList } from "./audio-rendition-list.js";
import { TrackEvent } from "./track-event.js";
import { RenditionEvent } from "./rendition-event.js";
export {
AudioRendition,
AudioRenditionList,
AudioTrack,
AudioTrackList,
RenditionEvent,
TrackEvent,
VideoRendition,
VideoRenditionList,
VideoTrack,
VideoTrackList
};
import { VideoTrack } from "./video-track.js";
import { VideoTrackList } from "./video-track-list.js";
import { VideoTrackList, addVideoTrack, removeVideoTrack } from "./video-track-list.js";
import { AudioTrack } from "./audio-track.js";
import { AudioTrackList } from "./audio-track-list.js";
import { AudioTrackList, addAudioTrack, removeAudioTrack } from "./audio-track-list.js";
import { VideoRenditionList } from "./video-rendition-list.js";
import { AudioRenditionList } from "./audio-rendition-list.js";
import { getPrivate } from "./utils.js";
function MediaTracksMixin(MediaElementClass) {

@@ -35,3 +36,2 @@ if (!MediaElementClass?.prototype)

MediaElementClass.prototype.addVideoTrack = function(kind, label = "", language = "") {
const videoTrackList = initVideoTrackList(this);
const track = new VideoTrack();

@@ -41,9 +41,11 @@ track.kind = kind;

track.language = language;
videoTrackList.add(track);
addVideoTrack(this, track);
return track;
};
}
if (!("removeVideoTrack" in MediaElementClass.prototype)) {
MediaElementClass.prototype.removeVideoTrack = removeVideoTrack;
}
if (!("addAudioTrack" in MediaElementClass.prototype)) {
MediaElementClass.prototype.addAudioTrack = function(kind, label = "", language = "") {
const audioTrackList = initAudioTrackList(this);
const track = new AudioTrack();

@@ -53,19 +55,18 @@ track.kind = kind;

track.language = language;
audioTrackList.add(track);
addAudioTrack(this, track);
return track;
};
}
const videoTrackLists = /* @__PURE__ */ new WeakMap();
const audioTrackLists = /* @__PURE__ */ new WeakMap();
const videoRenditionLists = /* @__PURE__ */ new WeakMap();
const audioRenditionLists = /* @__PURE__ */ new WeakMap();
if (!("removeAudioTrack" in MediaElementClass.prototype)) {
MediaElementClass.prototype.removeAudioTrack = removeAudioTrack;
}
const initVideoTrackList = (media) => {
let tracks = videoTrackLists.get(media);
let tracks = getPrivate(media).videoTracks;
if (!tracks) {
tracks = new VideoTrackList();
videoTrackLists.set(media, tracks);
getPrivate(media).videoTracks = tracks;
if (getNativeVideoTracks) {
const nativeTracks = getNativeVideoTracks.call(media);
for (const nativeTrack of nativeTracks) {
tracks.add(nativeTrack);
addVideoTrack(media, nativeTrack);
}

@@ -77,7 +78,7 @@ nativeTracks.addEventListener("change", () => {

if (![...tracks].some((t) => t instanceof VideoTrack)) {
tracks.add(event.track);
addVideoTrack(media, event.track);
}
});
nativeTracks.addEventListener("removetrack", (event) => {
tracks.remove(event.track);
removeVideoTrack(event.track);
});

@@ -89,10 +90,10 @@ }

const initAudioTrackList = (media) => {
let tracks = audioTrackLists.get(media);
let tracks = getPrivate(media).audioTracks;
if (!tracks) {
tracks = new AudioTrackList();
audioTrackLists.set(media, tracks);
getPrivate(media).audioTracks = tracks;
if (getNativeAudioTracks) {
const nativeTracks = getNativeAudioTracks.call(media);
for (const nativeTrack of nativeTracks) {
tracks.add(nativeTrack);
addAudioTrack(media, nativeTrack);
}

@@ -104,7 +105,7 @@ nativeTracks.addEventListener("change", () => {

if (![...tracks].some((t) => t instanceof AudioTrack)) {
tracks.add(event.track);
addAudioTrack(media, event.track);
}
});
nativeTracks.addEventListener("removetrack", (event) => {
tracks.remove(event.track);
removeAudioTrack(event.track);
});

@@ -115,29 +116,29 @@ }

};
if (globalThis.VideoTrack && !("renditions" in globalThis.VideoTrack.prototype)) {
Object.defineProperty(globalThis.VideoTrack.prototype, "renditions", {
if (!("videoRenditions" in MediaElementClass.prototype)) {
Object.defineProperty(MediaElementClass.prototype, "videoRenditions", {
get() {
return initVideoRenditionList(this);
return initVideoRenditions(this);
}
});
}
if (globalThis.AudioTrack && !("renditions" in globalThis.AudioTrack.prototype)) {
Object.defineProperty(globalThis.AudioTrack.prototype, "renditions", {
get() {
return initAudioRenditionList(this);
}
});
}
const initVideoRenditionList = (track) => {
let renditions = videoRenditionLists.get(track);
const initVideoRenditions = (media) => {
let renditions = getPrivate(media).videoRenditions;
if (!renditions) {
renditions = new VideoRenditionList();
videoRenditionLists.set(track, renditions);
getPrivate(media).videoRenditions = renditions;
}
return renditions;
};
const initAudioRenditionList = (track) => {
let renditions = audioRenditionLists.get(track);
if (!("audioRenditions" in MediaElementClass.prototype)) {
Object.defineProperty(MediaElementClass.prototype, "audioRenditions", {
get() {
return initAudioRenditions(this);
}
});
}
const initAudioRenditions = (media) => {
let renditions = getPrivate(media).audioRenditions;
if (!renditions) {
renditions = new AudioRenditionList();
audioRenditionLists.set(track, renditions);
getPrivate(media).audioRenditions = renditions;
}

@@ -144,0 +145,0 @@ return renditions;

@@ -1,17 +0,29 @@

import { AudioRendition } from './audio-rendition.js';
import type { AudioTrack } from './audio-track.js';
import type { AudioRendition } from './audio-rendition.js';
export declare function addRendition(track: AudioTrack, rendition: AudioRendition): void;
export declare function removeRendition(rendition: AudioRendition): void;
export declare function selectedChanged(rendition: AudioRendition): void;
export declare class AudioRenditionList extends EventTarget {
#private;
[index: number]: AudioRendition;
constructor();
[Symbol.iterator](): IterableIterator<AudioRendition>;
get length(): number;
add(rendition: AudioRendition): void;
remove(rendition: AudioRendition): void;
getRenditionById(id: string): AudioRendition | null;
get activeIndex(): number;
get onaddrendition(): (() => void) | undefined;
set onaddrendition(callback: (() => void) | undefined);
get onremoverendition(): (() => void) | undefined;
set onremoverendition(callback: (() => void) | undefined);
get selectedIndex(): number;
set selectedIndex(index: number);
get onaddrendition(): ((event?: {
rendition: AudioRendition;
}) => void) | undefined;
set onaddrendition(callback: ((event?: {
rendition: AudioRendition;
}) => void) | undefined);
get onremoverendition(): ((event?: {
rendition: AudioRendition;
}) => void) | undefined;
set onremoverendition(callback: ((event?: {
rendition: AudioRendition;
}) => void) | undefined);
get onchange(): (() => void) | undefined;
set onchange(callback: (() => void) | undefined);
}

@@ -1,7 +0,4 @@

export declare const audioRenditionToList: Map<any, any>;
/**
* - There can only be 1 rendition active in a rendition list.
* - The consumer should use the `enabled` setter to select 1 or multiple
* - The consumer should use the `selected` setter to select 1 or multiple
* renditions that the engine is allowed to play.
* - The `active` setter should be used by the media engine implementation.
*/

@@ -14,6 +11,4 @@ export declare class AudioRendition {

codec?: string;
get enabled(): boolean;
set enabled(val: boolean);
get active(): boolean;
set active(val: boolean);
get selected(): boolean;
set selected(val: boolean);
}

@@ -1,16 +0,26 @@

import { AudioTrack } from './audio-track.js';
import type { AudioTrack } from './audio-track.js';
export declare function addAudioTrack(media: HTMLMediaElement, track: AudioTrack): void;
export declare function removeAudioTrack(track: AudioTrack): void;
export declare function enabledChanged(track: AudioTrack): void;
export declare class AudioTrackList extends EventTarget {
#private;
[index: number]: AudioTrack;
[Symbol.iterator](): IterableIterator<AudioTrack>;
get length(): number;
add(track: AudioTrack): void;
remove(track: AudioTrack): void;
constructor();
[Symbol.iterator](): any;
get length(): any;
getTrackById(id: string): AudioTrack | null;
get onaddtrack(): (() => void) | undefined;
set onaddtrack(callback: (() => void) | undefined);
get onremovetrack(): (() => void) | undefined;
set onremovetrack(callback: (() => void) | undefined);
get onaddtrack(): ((event?: {
track: AudioTrack;
}) => void) | undefined;
set onaddtrack(callback: ((event?: {
track: AudioTrack;
}) => void) | undefined);
get onremovetrack(): ((event?: {
track: AudioTrack;
}) => void) | undefined;
set onremovetrack(callback: ((event?: {
track: AudioTrack;
}) => void) | undefined);
get onchange(): (() => void) | undefined;
set onchange(callback: (() => void) | undefined);
}
import { AudioRendition } from './audio-rendition.js';
import { AudioRenditionList } from './audio-rendition-list.js';
export declare const audioTrackToList: Map<any, any>;
export declare const AudioTrackKind: {

@@ -20,5 +18,5 @@ alternative: string;

addRendition(src: string, codec?: string, bitrate?: number): AudioRendition;
get renditions(): AudioRenditionList;
removeRendition(rendition: AudioRendition): void;
get enabled(): boolean;
set enabled(val: boolean);
}
export * from './mixin.js';
export * from './video-track.js';
export * from './video-track-list.js';
export * from './video-rendition.js';
export * from './video-rendition-list.js';
export * from './audio-track.js';
export * from './audio-track-list.js';
export * from './audio-rendition.js';
export * from './audio-rendition-list.js';
export * from './track-event.js';
export * from './rendition-event.js';
export { VideoTrack } from './video-track.js';
export { VideoTrackList } from './video-track-list.js';
export { VideoRendition } from './video-rendition.js';
export { VideoRenditionList } from './video-rendition-list.js';
export { AudioTrack } from './audio-track.js';
export { AudioTrackList } from './audio-track-list.js';
export { AudioRendition } from './audio-rendition.js';
export { AudioRenditionList } from './audio-rendition-list.js';
export { TrackEvent } from './track-event.js';
export { RenditionEvent } from './rendition-event.js';

@@ -5,2 +5,4 @@ import { VideoTrack } from './video-track.js';

import { AudioTrackList } from './audio-track-list.js';
import { VideoRenditionList } from './video-rendition-list.js';
import { AudioRenditionList } from './audio-rendition-list.js';
type VideoTrackType = typeof VideoTrack;

@@ -14,4 +16,8 @@ type AudioTrackType = typeof AudioTrack;

audioTracks: AudioTrackList;
addVideoTrack(kind: string, label?: string, language?: string): VideoTrack;
addAudioTrack(kind: string, label?: string, language?: string): AudioTrack;
addVideoTrack(kind: string, label?: string, language?: string): VideoTrack;
removeVideoTrack(track: VideoTrack): void;
removeAudioTrack(track: AudioTrack): void;
videoRenditions: VideoRenditionList;
audioRenditions: AudioRenditionList;
}

@@ -18,0 +24,0 @@ }

@@ -1,17 +0,29 @@

import { VideoRendition } from './video-rendition.js';
import type { VideoTrack } from './video-track.js';
import type { VideoRendition } from './video-rendition.js';
export declare function addRendition(track: VideoTrack, rendition: VideoRendition): void;
export declare function removeRendition(rendition: VideoRendition): void;
export declare function selectedChanged(rendition: VideoRendition): void;
export declare class VideoRenditionList extends EventTarget {
#private;
[index: number]: VideoRendition;
constructor();
[Symbol.iterator](): IterableIterator<VideoRendition>;
get length(): number;
add(rendition: VideoRendition): void;
remove(rendition: VideoRendition): void;
getRenditionById(id: string): VideoRendition | null;
get activeIndex(): number;
get onaddrendition(): (() => void) | undefined;
set onaddrendition(callback: (() => void) | undefined);
get onremoverendition(): (() => void) | undefined;
set onremoverendition(callback: (() => void) | undefined);
get selectedIndex(): number;
set selectedIndex(index: number);
get onaddrendition(): ((event?: {
rendition: VideoRendition;
}) => void) | undefined;
set onaddrendition(callback: ((event?: {
rendition: VideoRendition;
}) => void) | undefined);
get onremoverendition(): ((event?: {
rendition: VideoRendition;
}) => void) | undefined;
set onremoverendition(callback: ((event?: {
rendition: VideoRendition;
}) => void) | undefined);
get onchange(): (() => void) | undefined;
set onchange(callback: (() => void) | undefined);
}

@@ -1,7 +0,4 @@

export declare const videoRenditionToList: Map<any, any>;
/**
* - There can only be 1 rendition active in a rendition list.
* - The consumer should use the `enabled` setter to select 1 or multiple
* - The consumer should use the `selected` setter to select 1 or multiple
* renditions that the engine is allowed to play.
* - The `active` setter should be used by the media engine implementation.
*/

@@ -17,6 +14,4 @@ export declare class VideoRendition {

codec?: string;
get enabled(): boolean;
set enabled(val: boolean);
get active(): boolean;
set active(val: boolean);
get selected(): boolean;
set selected(val: boolean);
}

@@ -1,17 +0,27 @@

import { VideoTrack } from './video-track.js';
import type { VideoTrack } from './video-track.js';
export declare function addVideoTrack(media: HTMLMediaElement, track: VideoTrack): void;
export declare function removeVideoTrack(track: VideoTrack): void;
export declare function selectedChanged(selected: VideoTrack): void;
export declare class VideoTrackList extends EventTarget {
#private;
[index: number]: VideoTrack;
[Symbol.iterator](): IterableIterator<VideoTrack>;
get length(): number;
add(track: VideoTrack): void;
remove(track: VideoTrack): void;
constructor();
[Symbol.iterator](): any;
get length(): any;
getTrackById(id: string): VideoTrack | null;
get selectedIndex(): number;
get onaddtrack(): (() => void) | undefined;
set onaddtrack(callback: (() => void) | undefined);
get onremovetrack(): (() => void) | undefined;
set onremovetrack(callback: (() => void) | undefined);
get onaddtrack(): ((event?: {
track: VideoTrack;
}) => void) | undefined;
set onaddtrack(callback: ((event?: {
track: VideoTrack;
}) => void) | undefined);
get onremovetrack(): ((event?: {
track: VideoTrack;
}) => void) | undefined;
set onremovetrack(callback: ((event?: {
track: VideoTrack;
}) => void) | undefined);
get onchange(): (() => void) | undefined;
set onchange(callback: (() => void) | undefined);
}
import { VideoRendition } from './video-rendition.js';
import { VideoRenditionList } from './video-rendition-list.js';
export declare const videoTrackToList: Map<any, any>;
export declare const VideoTrackKind: {

@@ -20,5 +18,5 @@ alternative: string;

addRendition(src: string, width?: number, height?: number, codec?: string, bitrate?: number, frameRate?: number): VideoRendition;
get renditions(): VideoRenditionList;
removeRendition(rendition: VideoRendition): void;
get selected(): boolean;
set selected(val: boolean);
}

@@ -1,40 +0,79 @@

import { videoRenditionToList } from "./video-rendition.js";
import { RenditionEvent } from "./rendition-event.js";
import { getPrivate } from "./utils.js";
function addRendition(track, rendition) {
const renditionList = getPrivate(track).media.videoRenditions;
if (!getPrivate(rendition).list) {
getPrivate(rendition).list = renditionList;
getPrivate(rendition).track = track;
}
const { collection } = getPrivate(renditionList);
collection.add(rendition);
const index = collection.size - 1;
if (!(index in VideoRenditionList.prototype)) {
Object.defineProperty(VideoRenditionList.prototype, index, {
get() {
return getCurrentRenditions(this)[index];
}
});
}
queueMicrotask(() => {
if (!track.selected)
return;
renditionList.dispatchEvent(new RenditionEvent("addrendition", { rendition }));
});
}
function removeRendition(rendition) {
const renditionList = getPrivate(rendition).list;
const collection = getPrivate(renditionList).collection;
collection.delete(rendition);
queueMicrotask(() => {
const track = getPrivate(rendition).track;
if (!track.selected)
return;
renditionList.dispatchEvent(new RenditionEvent("removerendition", { rendition }));
});
}
function selectedChanged(rendition) {
const renditionList = getPrivate(rendition).list;
if (!renditionList || getPrivate(renditionList).changeRequested)
return;
getPrivate(renditionList).changeRequested = true;
queueMicrotask(() => {
delete getPrivate(renditionList).changeRequested;
const track = getPrivate(rendition).track;
if (!track.selected)
return;
renditionList.dispatchEvent(new Event("change"));
});
}
function getCurrentRenditions(renditionList) {
return [...getPrivate(renditionList).collection].filter((rendition) => {
return getPrivate(rendition).track.selected;
});
}
class VideoRenditionList extends EventTarget {
#renditions = [];
#addRenditionCallback;
#removeRenditionCallback;
#changeCallback;
constructor() {
super();
getPrivate(this).collection = /* @__PURE__ */ new Set();
}
[Symbol.iterator]() {
return this.#renditions.values();
return getCurrentRenditions(this).values();
}
get length() {
return this.#renditions.length;
return getCurrentRenditions(this).length;
}
add(rendition) {
videoRenditionToList.set(rendition, this);
const length = this.#renditions.push(rendition);
const index = length - 1;
if (!(index in VideoRenditionList.prototype)) {
Object.defineProperty(VideoRenditionList.prototype, index, {
get() {
return this.#renditions[index];
}
});
}
queueMicrotask(() => {
this.dispatchEvent(new RenditionEvent("addrendition", { rendition }));
});
getRenditionById(id) {
return getCurrentRenditions(this).find((rendition) => `${rendition.id}` === `${id}`) ?? null;
}
remove(rendition) {
videoRenditionToList.delete(rendition);
this.#renditions.splice(this.#renditions.indexOf(rendition), 1);
this.dispatchEvent(new RenditionEvent("removerendition", { rendition }));
get selectedIndex() {
return getCurrentRenditions(this).findIndex((rendition) => rendition.selected);
}
getRenditionById(id) {
return this.#renditions.find((rendition) => `${rendition.id}` === `${id}`) ?? null;
set selectedIndex(index) {
for (const [i, rendition] of getCurrentRenditions(this).entries()) {
rendition.selected = i === index;
}
}
get activeIndex() {
return this.#renditions.findIndex((rendition) => rendition.active);
}
get onaddrendition() {

@@ -58,6 +97,3 @@ return this.#addRenditionCallback;

if (this.#removeRenditionCallback) {
this.removeEventListener(
"removerendition",
this.#removeRenditionCallback
);
this.removeEventListener("removerendition", this.#removeRenditionCallback);
this.#removeRenditionCallback = void 0;

@@ -85,3 +121,6 @@ }

export {
VideoRenditionList
VideoRenditionList,
addRendition,
removeRendition,
selectedChanged
};

@@ -1,3 +0,2 @@

const videoRenditionToList = /* @__PURE__ */ new Map();
const changeRequested = /* @__PURE__ */ new Map();
import { selectedChanged } from "./video-rendition-list.js";
class VideoRendition {

@@ -11,47 +10,15 @@ src;

codec;
#enabled = false;
#active = false;
get enabled() {
return this.#enabled;
#selected = false;
get selected() {
return this.#selected;
}
set enabled(val) {
if (this.#enabled === val)
set selected(val) {
if (this.#selected === val)
return;
this.#enabled = val;
const renditionList = videoRenditionToList.get(this);
if (!renditionList || changeRequested.get(renditionList))
return;
changeRequested.set(renditionList, true);
queueMicrotask(() => {
changeRequested.delete(renditionList);
renditionList.dispatchEvent(new Event("change"));
});
this.#selected = val;
selectedChanged(this);
}
get active() {
return this.#active;
}
set active(val) {
if (this.#active === val)
return;
this.#active = val;
if (val !== true)
return;
const renditionList = videoRenditionToList.get(this) ?? [];
let hasInactivated = false;
for (const rendition of renditionList) {
if (rendition === this)
continue;
rendition.active = false;
hasInactivated = true;
}
if (hasInactivated) {
queueMicrotask(() => {
renditionList.dispatchEvent(new Event("renditionchange"));
});
}
}
}
export {
VideoRendition,
videoRenditionToList
VideoRendition
};

@@ -1,8 +0,61 @@

import { videoTrackToList } from "./video-track.js";
import { TrackEvent } from "./track-event.js";
import { getPrivate } from "./utils.js";
function addVideoTrack(media, track) {
const trackList = media.videoTracks;
if (!getPrivate(track).list) {
getPrivate(track).list = trackList;
getPrivate(track).media = media;
}
const { collection } = getPrivate(trackList);
collection.add(track);
const index = collection.size - 1;
if (!(index in VideoTrackList.prototype)) {
Object.defineProperty(VideoTrackList.prototype, index, {
get() {
return [...collection][index];
}
});
}
queueMicrotask(() => {
trackList.dispatchEvent(new TrackEvent("addtrack", { track }));
});
}
function removeVideoTrack(track) {
const trackList = getPrivate(track).list;
const collection = getPrivate(trackList).collection;
collection.delete(track);
queueMicrotask(() => {
trackList.dispatchEvent(new TrackEvent("removetrack", { track }));
});
}
function selectedChanged(selected) {
const trackList = getPrivate(selected).list ?? [];
let hasUnselected = false;
for (const track of trackList) {
if (track === selected)
continue;
track.selected = false;
hasUnselected = true;
}
if (hasUnselected) {
if (getPrivate(trackList).changeRequested)
return;
getPrivate(trackList).changeRequested = true;
queueMicrotask(() => {
delete getPrivate(trackList).changeRequested;
trackList.dispatchEvent(new Event("change"));
});
}
}
class VideoTrackList extends EventTarget {
#tracks = [];
#addTrackCallback;
#removeTrackCallback;
#changeCallback;
constructor() {
super();
getPrivate(this).collection = /* @__PURE__ */ new Set();
}
get #tracks() {
return getPrivate(this).collection;
}
[Symbol.iterator]() {

@@ -12,29 +65,9 @@ return this.#tracks.values();

get length() {
return this.#tracks.length;
return this.#tracks.size;
}
add(track) {
videoTrackToList.set(track, this);
const length = this.#tracks.push(track);
const index = length - 1;
if (!(index in VideoTrackList.prototype)) {
Object.defineProperty(VideoTrackList.prototype, index, {
get() {
return this.#tracks[index];
}
});
}
queueMicrotask(() => {
this.dispatchEvent(new TrackEvent("addtrack", { track }));
});
}
remove(track) {
videoTrackToList.delete(track);
this.#tracks.splice(this.#tracks.indexOf(track), 1);
this.dispatchEvent(new TrackEvent("removetrack", { track }));
}
getTrackById(id) {
return this.#tracks.find((track) => track.id === id) ?? null;
return [...this.#tracks].find((track) => track.id === id) ?? null;
}
get selectedIndex() {
return this.#tracks.findIndex((track) => track.selected);
return [...this.#tracks].findIndex((track) => track.selected);
}

@@ -82,3 +115,6 @@ get onaddtrack() {

export {
VideoTrackList
VideoTrackList,
addVideoTrack,
removeVideoTrack,
selectedChanged
};

@@ -0,5 +1,4 @@

import { selectedChanged } from "./video-track-list.js";
import { VideoRendition } from "./video-rendition.js";
import { VideoRenditionList } from "./video-rendition-list.js";
const videoTrackToList = /* @__PURE__ */ new Map();
const changeRequested = /* @__PURE__ */ new Map();
import { addRendition, removeRendition } from "./video-rendition-list.js";
const VideoTrackKind = {

@@ -20,3 +19,2 @@ alternative: "alternative",

#selected = false;
#renditions = new VideoRenditionList();
addRendition(src, width, height, codec, bitrate, frameRate) {

@@ -30,7 +28,7 @@ const rendition = new VideoRendition();

rendition.codec = codec;
this.#renditions.add(rendition);
addRendition(this, rendition);
return rendition;
}
get renditions() {
return this.#renditions;
removeRendition(rendition) {
removeRendition(rendition);
}

@@ -46,19 +44,3 @@ get selected() {

return;
const trackList = videoTrackToList.get(this) ?? [];
let hasUnselected = false;
for (const track of trackList) {
if (track === this)
continue;
track.selected = false;
hasUnselected = true;
}
if (hasUnselected) {
if (changeRequested.get(trackList))
return;
changeRequested.set(trackList, true);
queueMicrotask(() => {
changeRequested.delete(trackList);
trackList.dispatchEvent(new Event("change"));
});
}
selectedChanged(this);
}

@@ -68,4 +50,3 @@ }

VideoTrack,
VideoTrackKind,
videoTrackToList
VideoTrackKind
};
{
"name": "media-tracks",
"version": "0.1.2",
"version": "0.2.0",
"description": "Polyfill audio and video tracks with renditions.",

@@ -5,0 +5,0 @@ "type": "module",

@@ -27,9 +27,27 @@ # Media Tracks

interface HTMLMediaElement {
videoTracks: VideoTrackList;
audioTracks: AudioTrackList;
videoTracks: VideoTrackList;
addVideoTrack(kind: string, label?: string, language?: string): VideoTrack;
addAudioTrack(kind: string, label?: string, language?: string): AudioTrack;
addVideoTrack(kind: string, label?: string, language?: string): VideoTrack;
removeVideoTrack(track: VideoTrack): void;
removeAudioTrack(track: AudioTrack): void;
videoRenditions: VideoRenditionList;
audioRenditions: AudioRenditionList;
}
}
declare class VideoTrackList extends EventTarget {
[index: number]: VideoTrack;
[Symbol.iterator](): IterableIterator<VideoTrack>;
get length(): number;
getTrackById(id: string): VideoTrack | null;
get selectedIndex(): number;
get onaddtrack(): ((event?: { track: VideoTrack }) => void) | undefined;
set onaddtrack(callback: ((event?: { track: VideoTrack }) => void) | undefined);
get onremovetrack(): ((event?: { track: VideoTrack }) => void) | undefined;
set onremovetrack(callback: ((event?: { track: VideoTrack }) => void) | undefined);
get onchange(): (() => void) | undefined;
set onchange(callback: (() => void) | undefined);
}
declare const VideoTrackKind: {

@@ -51,3 +69,3 @@ alternative: string;

addRendition(src: string, width?: number, height?: number, codec?: string, bitrate?: number, frameRate?: number): VideoRendition;
get renditions(): VideoRenditionList;
removeRendition(rendition: AudioRendition): void;
get selected(): boolean;

@@ -58,12 +76,12 @@ set selected(val: boolean);

declare class VideoRenditionList extends EventTarget {
[index: number]: VideoRendition;
[Symbol.iterator](): IterableIterator<VideoRendition>;
get length(): number;
add(rendition: VideoRendition): void;
remove(rendition: VideoRendition): void;
getRenditionById(id: string): VideoRendition | null;
get activeIndex(): number;
get onaddrendition(): (() => void) | undefined;
set onaddrendition(callback: (() => void) | undefined);
get onremoverendition(): (() => void) | undefined;
set onremoverendition(callback: (() => void) | undefined);
get selectedIndex(): number;
set selectedIndex(index: number);
get onaddrendition(): ((event?: { rendition: VideoRendition }) => void) | undefined;
set onaddrendition(callback: ((event?: { rendition: VideoRendition }) => void) | undefined);
get onremoverendition(): ((event?: { rendition: VideoRendition }) => void) | undefined;
set onremoverendition(callback: ((event?: { rendition: VideoRendition }) => void) | undefined);
get onchange(): (() => void) | undefined;

@@ -73,3 +91,3 @@ set onchange(callback: (() => void) | undefined);

export declare class VideoRendition {
declare class VideoRendition {
src?: string;

@@ -82,8 +100,63 @@ id?: string;

codec?: string;
get selected(): boolean;
set selected(val: boolean);
}
declare class AudioTrackList extends EventTarget {
[index: number]: AudioTrack;
[Symbol.iterator](): IterableIterator<AudioTrack>;
get length(): number;
getTrackById(id: string): AudioTrack | null;
get onaddtrack(): ((event?: { track: AudioTrack }) => void) | undefined;
set onaddtrack(callback: ((event?: { track: AudioTrack }) => void) | undefined);
get onremovetrack(): ((event?: { track: AudioTrack }) => void) | undefined;
set onremovetrack(callback: ((event?: { track: AudioTrack }) => void) | undefined);
get onchange(): (() => void) | undefined;
set onchange(callback: (() => void) | undefined);
}
declare const AudioTrackKind: {
alternative: string;
descriptions: string;
main: string;
'main-desc': string;
translation: string;
commentary: string;
};
declare class AudioTrack {
id?: string;
kind?: string;
label: string;
language: string;
sourceBuffer?: SourceBuffer;
addRendition(src: string, codec?: string, bitrate?: number): AudioRendition;
removeRendition(rendition: AudioRendition): void;
get enabled(): boolean;
set enabled(val: boolean);
get active(): boolean;
set active(val: boolean);
}
declare class AudioRenditionList extends EventTarget {
[index: number]: AudioRendition;
[Symbol.iterator](): IterableIterator<AudioRendition>;
get length(): number;
getRenditionById(id: string): AudioRendition | null;
get selectedIndex(): number;
set selectedIndex(index: number);
get onaddrendition(): ((event?: { rendition: VideoRendition }) => void) | undefined;
set onaddrendition(callback: ((event?: { rendition: VideoRendition }) => void) | undefined);
get onremoverendition(): ((event?: { rendition: VideoRendition }) => void) | undefined;
set onremoverendition(callback: ((event?: { rendition: VideoRendition }) => void) | undefined);
get onchange(): (() => void) | undefined;
set onchange(callback: (() => void) | undefined);
}
declare class AudioRendition {
src?: string;
id?: string;
bitrate?: number;
codec?: string;
get selected(): boolean;
set selected(val: boolean);
}
```
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc