@mango-iiif/av 0.1.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/README.md +1 -0
- package/dist/annotations.d.ts +2 -2
- package/dist/annotations.js +3 -3
- package/dist/chapters.d.ts +2 -2
- package/dist/chapters.js +3 -3
- package/dist/{chunk-FF6BLZ6W.js → chunk-4NOWGMI5.js} +9 -1
- package/dist/chunk-4NOWGMI5.js.map +1 -0
- package/dist/{chunk-4FBOXHMO.js → chunk-4V6FME6B.js} +76 -20
- package/dist/chunk-4V6FME6B.js.map +1 -0
- package/dist/{chunk-P7TOB5QS.js → chunk-C4H46HDS.js} +4 -3
- package/dist/chunk-C4H46HDS.js.map +1 -0
- package/dist/{chunk-5BWGKBKC.js → chunk-CIAQZ2EB.js} +2 -2
- package/dist/{chunk-HHDOPDXV.js → chunk-EHIKFRFV.js} +3 -3
- package/dist/{chunk-3PDSZOH3.js → chunk-ELGGWWDS.js} +48 -9
- package/dist/chunk-ELGGWWDS.js.map +1 -0
- package/dist/{chunk-5YLZTGEM.js → chunk-FVYEV2LO.js} +4 -4
- package/dist/{chunk-PI3ID6LG.js → chunk-YX32ZQPR.js} +3 -3
- package/dist/{chunk-2CWHBQQY.js → chunk-YX6L6CUF.js} +81 -21
- package/dist/chunk-YX6L6CUF.js.map +1 -0
- package/dist/{controller-BLA8XNsG.d.ts → controller-SkwGkVE8.d.ts} +8 -0
- package/dist/{controller-element-BY0157ve.d.ts → controller-element-CkXIA6w2.d.ts} +1 -1
- package/dist/core.d.ts +2 -2
- package/dist/core.js +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +9 -9
- package/dist/media.d.ts +1 -1
- package/dist/media.js +4 -4
- package/dist/player.d.ts +2 -2
- package/dist/player.js +5 -5
- package/dist/transcript-element.d.ts +2 -2
- package/dist/transcript-element.js +4 -4
- package/docs/API.md +7 -1
- package/package.json +2 -1
- package/dist/chunk-2CWHBQQY.js.map +0 -1
- package/dist/chunk-3PDSZOH3.js.map +0 -1
- package/dist/chunk-4FBOXHMO.js.map +0 -1
- package/dist/chunk-FF6BLZ6W.js.map +0 -1
- package/dist/chunk-P7TOB5QS.js.map +0 -1
- /package/dist/{chunk-5BWGKBKC.js.map → chunk-CIAQZ2EB.js.map} +0 -0
- /package/dist/{chunk-HHDOPDXV.js.map → chunk-EHIKFRFV.js.map} +0 -0
- /package/dist/{chunk-5YLZTGEM.js.map → chunk-FVYEV2LO.js.map} +0 -0
- /package/dist/{chunk-PI3ID6LG.js.map → chunk-YX32ZQPR.js.map} +0 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## Unreleased
|
|
4
|
+
|
|
5
|
+
- Fixed `<mango-av-player>` failing to resolve and attach media when given an already-loaded `AVPlayerController`.
|
|
6
|
+
- Audio artwork no longer displays the Canvas label as a visible title by default. Hosts can opt in to custom text with `audioArt.title`.
|
|
7
|
+
- Fixed a cross-origin audio regression where enabling audio artwork visualization could route otherwise playable media through a CORS-unsafe Web Audio graph and produce silence. Visualizer loads now establish their CORS policy before assigning the source URL and automatically fall back once to ordinary HTML audio for servers without CORS support.
|
package/README.md
CHANGED
package/dist/annotations.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { A as AVControllerElement } from './controller-element-
|
|
2
|
-
import { k as AVPlayerEventMap } from './controller-
|
|
1
|
+
import { A as AVControllerElement } from './controller-element-CkXIA6w2.js';
|
|
2
|
+
import { k as AVPlayerEventMap } from './controller-SkwGkVE8.js';
|
|
3
3
|
|
|
4
4
|
declare class MangoAVAnnotationsElement extends AVControllerElement {
|
|
5
5
|
#private;
|
package/dist/annotations.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
MangoAVAnnotationsElement,
|
|
3
3
|
defineMangoAVAnnotations
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-YX32ZQPR.js";
|
|
5
5
|
import "./chunk-CDLYT3KB.js";
|
|
6
|
-
import "./chunk-
|
|
7
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-C4H46HDS.js";
|
|
7
|
+
import "./chunk-4NOWGMI5.js";
|
|
8
8
|
|
|
9
9
|
// src/annotations.ts
|
|
10
10
|
if (typeof window !== "undefined" && "customElements" in window) defineMangoAVAnnotations();
|
package/dist/chapters.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { A as AVControllerElement } from './controller-element-
|
|
2
|
-
import { k as AVPlayerEventMap } from './controller-
|
|
1
|
+
import { A as AVControllerElement } from './controller-element-CkXIA6w2.js';
|
|
2
|
+
import { k as AVPlayerEventMap } from './controller-SkwGkVE8.js';
|
|
3
3
|
|
|
4
4
|
declare class MangoAVChaptersElement extends AVControllerElement {
|
|
5
5
|
#private;
|
package/dist/chapters.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
MangoAVChaptersElement,
|
|
3
3
|
defineMangoAVChapters
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
6
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-EHIKFRFV.js";
|
|
5
|
+
import "./chunk-C4H46HDS.js";
|
|
6
|
+
import "./chunk-4NOWGMI5.js";
|
|
7
7
|
|
|
8
8
|
// src/chapters.ts
|
|
9
9
|
if (typeof window !== "undefined" && "customElements" in window) defineMangoAVChapters();
|
|
@@ -74,6 +74,7 @@ var defaultConfig = {
|
|
|
74
74
|
showSearchMarkers: true
|
|
75
75
|
},
|
|
76
76
|
audioArt: {
|
|
77
|
+
title: "",
|
|
77
78
|
transcript: false,
|
|
78
79
|
visualizer: false
|
|
79
80
|
},
|
|
@@ -693,8 +694,10 @@ var AVPlayerController = class extends EventTarget {
|
|
|
693
694
|
#timelineScale = 1;
|
|
694
695
|
#pendingTime;
|
|
695
696
|
#boundListeners = /* @__PURE__ */ new Map();
|
|
697
|
+
#crossoriginExplicit;
|
|
696
698
|
constructor(config = {}) {
|
|
697
699
|
super();
|
|
700
|
+
this.#crossoriginExplicit = Object.hasOwn(config, "crossorigin");
|
|
698
701
|
this.#config = mergeConfig(defaultConfig, config);
|
|
699
702
|
this.#state.autoAdvance = this.#config.autoAdvance;
|
|
700
703
|
this.#state.repeat = this.#config.repeat;
|
|
@@ -717,12 +720,17 @@ var AVPlayerController = class extends EventTarget {
|
|
|
717
720
|
get media() {
|
|
718
721
|
return this.#media;
|
|
719
722
|
}
|
|
723
|
+
/** Whether the host explicitly selected the media element CORS policy. */
|
|
724
|
+
get crossoriginExplicit() {
|
|
725
|
+
return this.#crossoriginExplicit;
|
|
726
|
+
}
|
|
720
727
|
on(type, listener) {
|
|
721
728
|
const eventListener = listener;
|
|
722
729
|
this.addEventListener(type, eventListener);
|
|
723
730
|
return () => this.removeEventListener(type, eventListener);
|
|
724
731
|
}
|
|
725
732
|
configure(config) {
|
|
733
|
+
if (Object.hasOwn(config, "crossorigin")) this.#crossoriginExplicit = true;
|
|
726
734
|
this.#config = mergeConfig(
|
|
727
735
|
this.#config,
|
|
728
736
|
config
|
|
@@ -1079,4 +1087,4 @@ export {
|
|
|
1079
1087
|
normalizeManifest,
|
|
1080
1088
|
AVPlayerController
|
|
1081
1089
|
};
|
|
1082
|
-
//# sourceMappingURL=chunk-
|
|
1090
|
+
//# sourceMappingURL=chunk-4NOWGMI5.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/types.ts","../src/utils.ts","../src/iiif/normalize.ts","../src/controller.ts"],"sourcesContent":["export type JsonObject = { [key: string]: unknown };\nexport type IIIFPresentationVersion = 2 | 3;\nexport type MediaKind = 'audio' | 'video';\n\nexport interface LocalizedValue {\n language?: string;\n value: string;\n}\n\nexport interface TimeSpan {\n start: number;\n end?: number;\n}\n\nexport interface MediaSource {\n id: string;\n src: string;\n kind: MediaKind;\n format?: string;\n label?: string;\n width?: number;\n height?: number;\n duration?: number;\n quality?: string;\n isHls: boolean;\n segment?: TimeSpan;\n canvasTarget?: TimeSpan;\n timeMode?: 'trim' | 'scale' | 'loop';\n}\n\nexport type TextTrackKind = 'captions' | 'subtitles' | 'descriptions' | 'metadata';\n\nexport interface TextTrack {\n id: string;\n src: string;\n kind: TextTrackKind;\n label: string;\n language?: string;\n format?: string;\n default?: boolean;\n forced?: boolean;\n}\n\nexport interface TranscriptResource {\n id: string;\n src?: string;\n label: string;\n format?: string;\n language?: string;\n machineGenerated: boolean;\n cues?: TranscriptCue[];\n}\n\nexport type TranscriptCueType = 'cue' | 'note' | 'metadata' | 'text';\n\nexport interface TranscriptCue {\n id: string;\n start?: number;\n end?: number;\n text: string;\n speaker?: string;\n type: TranscriptCueType;\n}\n\nexport interface AVAnnotation {\n id: string;\n canvasId: string;\n motivation: string[];\n purpose: string[];\n label?: string;\n text: string;\n time?: TimeSpan;\n tags: string[];\n sourcePageId?: string;\n}\n\nexport interface AVAnnotationDraft {\n motivation?: string[];\n purpose?: string[];\n label?: string;\n text: string;\n time?: TimeSpan;\n tags?: string[];\n}\n\nexport interface AVAnnotationAdapter {\n create?: (canvas: AVCanvas, annotation: AVAnnotationDraft) => Promise<AVAnnotation>;\n update?: (canvas: AVCanvas, annotation: AVAnnotation) => Promise<AVAnnotation>;\n remove?: (canvas: AVCanvas, annotation: AVAnnotation) => Promise<void>;\n}\n\nexport interface DownloadResource {\n id: string;\n label: string;\n format?: string;\n filename?: string;\n}\n\nexport interface MetadataEntry {\n label: string;\n values: LocalizedValue[];\n}\n\nexport interface AuthService {\n id: string;\n profile?: string;\n label?: string;\n serviceType: 'probe' | 'access' | 'token' | 'logout' | 'unknown';\n services: AuthService[];\n}\n\nexport interface AVCanvas {\n id: string;\n index: number;\n label: string;\n summary?: string;\n duration?: number;\n width?: number;\n height?: number;\n behavior: string[];\n sources: MediaSource[];\n tracks: TextTrack[];\n transcripts: TranscriptResource[];\n annotations: AVAnnotation[];\n rendering: DownloadResource[];\n metadata: MetadataEntry[];\n poster?: string;\n accompanyingCanvas?: string;\n homepage?: string;\n authServices: AuthService[];\n}\n\nexport interface Chapter {\n id: string;\n label: string;\n canvasId?: string;\n time?: TimeSpan;\n behavior: string[];\n summary?: string;\n homepage?: string;\n children: Chapter[];\n}\n\nexport interface AVManifest {\n id: string;\n type: 'Manifest';\n version: IIIFPresentationVersion;\n label: string;\n summary?: string;\n behavior: string[];\n start?: { canvasId: string; time?: number };\n canvases: AVCanvas[];\n chapters: Chapter[];\n metadata: MetadataEntry[];\n rendering: DownloadResource[];\n rights?: string;\n requiredStatement?: MetadataEntry;\n homepage?: string;\n logo?: string;\n}\n\nexport interface AVControlsConfig {\n navigation?: boolean;\n autoAdvance?: boolean;\n seek?: boolean;\n volume?: boolean;\n captions?: boolean;\n playbackRate?: boolean;\n pictureInPicture?: boolean;\n fullscreen?: boolean;\n sourceSelector?: boolean;\n download?: boolean;\n skipSeconds?: number;\n}\n\nexport interface AVPanelsConfig {\n chapters?: boolean;\n transcript?: boolean;\n annotations?: boolean;\n metadata?: boolean;\n supplementalFiles?: boolean;\n}\n\nexport interface AVTranscriptConfig {\n autoScroll?: boolean;\n search?: boolean;\n download?: boolean;\n showNotes?: boolean;\n showMetadata?: boolean;\n showSearchMarkers?: boolean;\n}\n\nexport interface AVAudioArtConfig {\n title?: string;\n transcript?: boolean;\n visualizer?: boolean | AVAudioVisualizerMode;\n}\n\nexport type AVAudioVisualizerMode = 'pulse' | 'waveform' | 'spectrum';\n\nexport interface AVResumeConfig {\n enabled?: boolean;\n maxItems?: number;\n ttlDays?: number;\n prompt?: boolean;\n}\n\n/** Package-owned interface strings. Values may contain `{name}` placeholders. */\nexport interface AVStrings {\n chapters: string;\n transcript: string;\n annotations: string;\n metadata: string;\n files: string;\n rights: string;\n previous: string;\n next: string;\n previousSection: string;\n nextSection: string;\n autoAdvance: string;\n mediaPlayer: string;\n mediaSource: string;\n mediaInformation: string;\n download: string;\n downloadMediaFile: string;\n searchTranscript: string;\n transcriptSearchMatches: string;\n searchMatchAt: string;\n resumePrompt: string;\n resume: string;\n startOver: string;\n loadingManifest: string;\n loadingTranscript: string;\n unableToLoadPlayer: string;\n unableToLoadMedia: string;\n noMediaLoaded: string;\n noPlayableMedia: string;\n noManifest: string;\n noTranscript: string;\n noAnnotations: string;\n noMetadata: string;\n noChapters: string;\n noSupplementalFiles: string;\n autoSource: string;\n sourceNumber: string;\n transcriptNumber: string;\n sectionNumber: string;\n chapterNumber: string;\n untitledManifest: string;\n unableToLoadManifest: string;\n expectedManifest: string;\n manifestWithoutCanvases: string;\n}\n\nexport interface AVPlayerConfig {\n controls?: AVControlsConfig;\n panels?: AVPanelsConfig;\n transcript?: AVTranscriptConfig;\n audioArt?: AVAudioArtConfig;\n resume?: AVResumeConfig;\n strings?: Partial<AVStrings>;\n preferredLanguages?: string[];\n autoAdvance?: boolean;\n repeat?: boolean;\n startCanvasId?: string;\n startTime?: number;\n activePanel?: 'chapters' | 'transcript' | 'annotations' | 'metadata' | 'files' | 'none';\n crossorigin?: 'anonymous' | 'use-credentials' | '';\n preload?: 'none' | 'metadata' | 'auto';\n playbackRates?: number[];\n fetch?: typeof globalThis.fetch;\n requestInit?: RequestInit;\n resolveRequest?: (url: string, context: { manifest?: AVManifest; canvas?: AVCanvas }) => string | Promise<string>;\n annotationAdapter?: AVAnnotationAdapter;\n}\n\nexport interface AVPlayerState {\n status: 'idle' | 'loading' | 'ready' | 'playing' | 'paused' | 'ended' | 'error';\n manifest?: AVManifest;\n canvasIndex: number;\n sourceIndex: number;\n currentTime: number;\n duration: number;\n volume: number;\n muted: boolean;\n playbackRate: number;\n autoAdvance: boolean;\n repeat: boolean;\n error?: Error;\n}\n\nexport interface AVPlayerEventMap {\n 'av-loadstart': { source: string | JsonObject };\n 'av-ready': { manifest: AVManifest };\n 'av-error': { error: Error };\n 'av-canvaschange': { canvas: AVCanvas; canvasIndex: number };\n 'av-sourcechange': { source: MediaSource; sourceIndex: number };\n 'av-play': { canvasId: string; time: number };\n 'av-pause': { canvasId: string; time: number };\n 'av-timeupdate': { canvasId: string; time: number; duration: number };\n 'av-seek': { canvasId: string; from: number; to: number };\n 'av-ended': { canvasId: string };\n 'av-annotationschange': { canvasId: string; annotations: AVAnnotation[] };\n 'av-configchange': { config: Readonly<AVPlayerConfig> };\n 'av-statechange': AVPlayerState;\n 'av-visualizerfallback': { canvasId: string; sourceUrl: string; reason: 'cors' };\n}\n\nexport const defaultStrings: AVStrings = {\n chapters: 'Chapters',\n transcript: 'Transcript',\n annotations: 'Annotations',\n metadata: 'Metadata',\n files: 'Files',\n rights: 'Rights',\n previous: 'Previous',\n next: 'Next',\n previousSection: 'Previous section',\n nextSection: 'Next section',\n autoAdvance: 'Auto-advance',\n mediaPlayer: 'Media player',\n mediaSource: 'Media source',\n mediaInformation: 'Media information',\n download: 'Download',\n downloadMediaFile: 'Download media file',\n searchTranscript: 'Search transcript',\n transcriptSearchMatches: 'Transcript search matches',\n searchMatchAt: 'Search match at {time}',\n resumePrompt: 'Resume from {time}?',\n resume: 'Resume',\n startOver: 'Start over',\n loadingManifest: 'Loading IIIF manifest…',\n loadingTranscript: 'Loading transcript…',\n unableToLoadPlayer: 'Unable to load the player.',\n unableToLoadMedia: 'Unable to load media.',\n noMediaLoaded: 'No media loaded',\n noPlayableMedia: 'No playable audio or video source',\n noManifest: 'No manifest is loaded.',\n noTranscript: 'No transcript is available.',\n noAnnotations: 'No annotations are available.',\n noMetadata: 'No metadata is available.',\n noChapters: 'No structured navigation is available.',\n noSupplementalFiles: 'No supplemental files are available.',\n autoSource: 'Auto',\n sourceNumber: 'Source {number}',\n transcriptNumber: 'Transcript {number}',\n sectionNumber: 'Section {number}',\n chapterNumber: 'Chapter {number}',\n untitledManifest: 'Untitled manifest',\n unableToLoadManifest: 'Unable to load IIIF manifest ({status} {statusText}).',\n expectedManifest: 'Expected a IIIF Manifest, received {type}.',\n manifestWithoutCanvases: 'The IIIF Manifest does not contain any Canvases.',\n};\n\nexport const defaultConfig: Required<\n Pick<AVPlayerConfig, 'controls' | 'panels' | 'transcript' | 'audioArt' | 'resume' | 'strings' | 'preferredLanguages' | 'autoAdvance' | 'repeat' | 'activePanel' | 'crossorigin' | 'preload' | 'playbackRates'>\n> = {\n controls: {\n navigation: false,\n autoAdvance: false,\n seek: true,\n volume: true,\n captions: true,\n playbackRate: true,\n pictureInPicture: true,\n fullscreen: true,\n sourceSelector: true,\n download: false,\n skipSeconds: 10,\n },\n panels: {\n chapters: true,\n transcript: true,\n annotations: true,\n metadata: true,\n supplementalFiles: true,\n },\n transcript: {\n autoScroll: true,\n search: true,\n download: true,\n showNotes: false,\n showMetadata: false,\n showSearchMarkers: true,\n },\n audioArt: {\n title: '',\n transcript: false,\n visualizer: false,\n },\n resume: {\n enabled: false,\n maxItems: 200,\n ttlDays: 30,\n prompt: true,\n },\n strings: defaultStrings,\n preferredLanguages: ['en', 'none'],\n autoAdvance: false,\n repeat: false,\n activePanel: 'chapters',\n crossorigin: '',\n preload: 'metadata',\n playbackRates: [0.5, 0.75, 1, 1.25, 1.5, 2],\n};\n","import type { AVStrings, JsonObject, LocalizedValue, TimeSpan } from './types';\nimport { defaultStrings } from './types';\n\nexport const asObject = (value: unknown): JsonObject | undefined =>\n value !== null && typeof value === 'object' && !Array.isArray(value)\n ? (value as JsonObject)\n : undefined;\n\nexport const asArray = <T>(value: T | T[] | null | undefined): T[] => {\n if (value === null || value === undefined) return [];\n return Array.isArray(value) ? value : [value];\n};\n\nexport const readId = (value: unknown): string | undefined => {\n if (typeof value === 'string') return value;\n const object = asObject(value);\n const id = object?.id ?? object?.['@id'];\n return typeof id === 'string' ? id : undefined;\n};\n\nexport const readType = (value: unknown): string | undefined => {\n const object = asObject(value);\n const type = object?.type ?? object?.['@type'];\n return typeof type === 'string' ? type : undefined;\n};\n\nexport const languageValues = (value: unknown): LocalizedValue[] => {\n if (typeof value === 'string') return [{ value }];\n if (Array.isArray(value)) {\n return value.flatMap((item) => languageValues(item));\n }\n const object = asObject(value);\n if (!object) return [];\n if (typeof object['@value'] === 'string') {\n const result: LocalizedValue = { value: object['@value'] };\n if (typeof object['@language'] === 'string') result.language = object['@language'];\n return [result];\n }\n return Object.entries(object).flatMap(([language, values]) =>\n asArray(values).flatMap((item) =>\n typeof item === 'string'\n ? [{ language, value: item }]\n : languageValues(item).map((entry) => ({ ...entry, language: entry.language ?? language })),\n ),\n );\n};\n\nexport const label = (\n value: unknown,\n preferredLanguages: string[] = ['en', 'none'],\n fallback = '',\n): string => {\n const values = languageValues(value);\n for (const language of preferredLanguages) {\n const match = values.find((item) => item.language === language);\n if (match) return match.value;\n }\n return values[0]?.value ?? fallback;\n};\n\nexport const parseTime = (value: string | number | undefined): number | undefined => {\n if (typeof value === 'number') return Number.isFinite(value) ? value : undefined;\n if (!value) return undefined;\n if (/^\\d+(?:\\.\\d+)?$/.test(value)) return Number(value);\n const parts = value.replace(',', '.').split(':').map(Number);\n if (parts.some((part) => !Number.isFinite(part))) return undefined;\n if (parts.length === 3) return (parts[0] ?? 0) * 3600 + (parts[1] ?? 0) * 60 + (parts[2] ?? 0);\n if (parts.length === 2) return (parts[0] ?? 0) * 60 + (parts[1] ?? 0);\n return undefined;\n};\n\nexport const parseTemporalFragment = (target: unknown): TimeSpan | undefined => {\n let fragment: string | undefined;\n if (typeof target === 'string') fragment = target.split('#')[1];\n const object = asObject(target);\n if (!fragment && object) {\n const selector = asObject(object.selector);\n const value = selector?.value;\n if (typeof value === 'string') fragment = value.replace(/^#/, '');\n if (selector?.type === 'PointSelector' && typeof selector.t === 'number') {\n return { start: selector.t };\n }\n }\n const time = fragment?.match(/(?:^|&)t=([^&]+)/)?.[1];\n if (!time) return undefined;\n const [startValue, endValue] = time.split(',');\n const start = parseTime(startValue);\n const end = parseTime(endValue);\n if (start === undefined) return undefined;\n return end === undefined ? { start } : { start, end };\n};\n\nexport const withoutFragment = (value: string): string => value.split('#')[0] ?? value;\n\nexport const isHls = (src: string, format?: string): boolean =>\n /(?:\\.m3u8)(?:$|[?#])/i.test(src) ||\n format === 'application/vnd.apple.mpegurl' ||\n format === 'application/x-mpegURL';\n\nexport const mediaKind = (type?: string, format?: string, src = ''): 'audio' | 'video' | undefined => {\n const normalizedType = type?.toLowerCase().trim();\n const normalizedFormat = format?.toLowerCase().split(';', 1)[0]?.trim();\n const typeName = normalizedType?.split(/[:/#]/).pop();\n\n // IIIF type and MIME metadata are authoritative. Sound and MovingImage are\n // the Presentation 2/DCMI aliases for Audio and Video resources.\n if (typeName === 'audio' || typeName === 'sound' || normalizedFormat?.startsWith('audio/')) return 'audio';\n if (\n typeName === 'video' ||\n typeName === 'movingimage' ||\n normalizedFormat?.startsWith('video/') ||\n normalizedFormat === 'application/vnd.apple.mpegurl' ||\n normalizedFormat === 'application/x-mpegurl'\n ) return 'video';\n if (normalizedType || normalizedFormat) return undefined;\n\n // With no metadata, inspect only the resource path's extension. Directory\n // names such as `/video/poster.png` must not determine the media kind.\n const pathname = src.toLowerCase().split(/[?#]/, 1)[0] ?? '';\n if (/\\.(?:mp3|m4a|wav|aac)$/.test(pathname)) return 'audio';\n if (/\\.(?:mp4|webm|m3u8)$/.test(pathname)) return 'video';\n return undefined;\n};\n\nexport const formatTime = (seconds: number): string => {\n if (!Number.isFinite(seconds)) return '0:00';\n const value = Math.max(0, Math.floor(seconds));\n const hours = Math.floor(value / 3600);\n const minutes = Math.floor((value % 3600) / 60);\n const remaining = value % 60;\n return hours > 0\n ? `${hours}:${String(minutes).padStart(2, '0')}:${String(remaining).padStart(2, '0')}`\n : `${minutes}:${String(remaining).padStart(2, '0')}`;\n};\n\nexport const resolveStrings = (strings: Partial<AVStrings> = {}): AVStrings => ({\n ...defaultStrings,\n ...strings,\n});\n\nexport const formatString = (\n template: string,\n values: Record<string, string | number> = {},\n): string => template.replace(/\\{(\\w+)\\}/g, (placeholder, name: string) =>\n Object.prototype.hasOwnProperty.call(values, name) ? String(values[name]) : placeholder,\n);\n\nexport const mergeConfig = <T extends Record<string, unknown>>(base: T, update: Partial<T>): T => {\n const result = { ...base } as T;\n for (const [key, value] of Object.entries(update)) {\n if (value !== undefined && asObject(value) && asObject(result[key])) {\n result[key as keyof T] = mergeConfig(\n asObject(result[key]) as Record<string, unknown>,\n asObject(value) as Record<string, unknown>,\n ) as T[keyof T];\n } else if (value !== undefined) {\n result[key as keyof T] = value as T[keyof T];\n }\n }\n return result;\n};\n\nexport const escapeHtml = (value: string): string =>\n value.replace(/[&<>'\"]/g, (character) => ({\n '&': '&',\n '<': '<',\n '>': '>',\n \"'\": ''',\n '\"': '"',\n })[character] ?? character);\n","import type {\n AVAnnotation,\n AVCanvas,\n AVManifest,\n AVStrings,\n AuthService,\n Chapter,\n DownloadResource,\n JsonObject,\n MediaSource,\n MetadataEntry,\n TextTrack,\n TranscriptCue,\n TranscriptResource,\n} from '../types';\nimport {\n asArray,\n asObject,\n formatString,\n isHls,\n label,\n languageValues,\n mediaKind,\n parseTemporalFragment,\n readId,\n readType,\n resolveStrings,\n withoutFragment,\n} from '../utils';\n\nexport interface NormalizeOptions {\n fetch?: typeof globalThis.fetch;\n requestInit?: RequestInit;\n preferredLanguages?: string[];\n loadExternalAnnotations?: boolean;\n strings?: Partial<AVStrings>;\n}\n\nconst strings = (value: unknown): string[] =>\n asArray(value).flatMap((item) => (typeof item === 'string' ? [item] : []));\n\nconst number = (value: unknown): number | undefined =>\n typeof value === 'number' && Number.isFinite(value) ? value : undefined;\n\nconst readFormat = (object: JsonObject): string | undefined =>\n typeof object.format === 'string' ? object.format : undefined;\n\nconst metadata = (value: unknown, languages: string[], ui: AVStrings): MetadataEntry[] =>\n asArray(value).flatMap((item) => {\n const object = asObject(item);\n if (!object) return [];\n const values = languageValues(object.value);\n if (values.length === 0) return [];\n return [{ label: label(object.label, languages, ui.metadata), values }];\n });\n\nconst downloads = (value: unknown, languages: string[], ui: AVStrings): DownloadResource[] =>\n asArray(value).flatMap((item) => {\n const object = asObject(item);\n const id = readId(item);\n if (!object || !id) return [];\n const result: DownloadResource = {\n id,\n label: label(object.label, languages, id.split('/').pop() ?? ui.download),\n };\n const format = readFormat(object);\n if (format) result.format = format;\n const filename = typeof object.filename === 'string' ? object.filename : undefined;\n if (filename) result.filename = filename;\n return [result];\n });\n\nconst renderingTranscripts = (value: unknown, languages: string[], ui: AVStrings): TranscriptResource[] =>\n asArray(value).flatMap((item, index) => {\n const object = asObject(item);\n const id = readId(item);\n if (!object || !id) return [];\n const format = readFormat(object)?.toLowerCase().split(';', 1)[0]?.trim();\n const pathname = id.toLowerCase().split(/[?#]/, 1)[0] ?? '';\n if (!format?.startsWith('text/') && !/\\.(?:txt|vtt|srt)$/.test(pathname)) return [];\n const transcript: TranscriptResource = {\n id: `${id}#transcript`,\n src: id,\n label: label(object.label, languages, formatString(ui.transcriptNumber, { number: index + 1 })),\n machineGenerated: false,\n };\n if (format) transcript.format = format;\n const language = typeof object.language === 'string' ? object.language : undefined;\n if (language) transcript.language = language;\n return [transcript];\n });\n\nconst services = (value: unknown, languages: string[]): AuthService[] =>\n asArray(value).flatMap((item) => {\n const object = asObject(item);\n const id = readId(item);\n if (!object || !id) return [];\n const profile = typeof object.profile === 'string' ? object.profile : undefined;\n const type = `${readType(object) ?? ''} ${profile ?? ''}`.toLowerCase();\n let serviceType: AuthService['serviceType'] = 'unknown';\n if (type.includes('probe')) serviceType = 'probe';\n else if (type.includes('token')) serviceType = 'token';\n else if (type.includes('logout')) serviceType = 'logout';\n else if (type.includes('access') || type.includes('login') || type.includes('clickthrough') || type.includes('kiosk')) serviceType = 'access';\n const result: AuthService = {\n id,\n serviceType,\n services: services(object.service, languages),\n };\n if (profile) result.profile = profile;\n const serviceLabel = label(object.label, languages);\n if (serviceLabel) result.label = serviceLabel;\n return [result];\n });\n\nconst firstContentId = (canvasValue: unknown): string | undefined => {\n const canvas = asObject(canvasValue);\n if (!canvas) return undefined;\n const v3Page = asObject(asArray(canvas.items)[0]);\n const v3Annotation = asObject(asArray(v3Page?.items)[0]);\n const v3Body = asObject(asArray(v3Annotation?.body)[0]);\n const v2Annotation = asObject(asArray(canvas.images)[0]);\n const v2Body = asObject(v2Annotation?.resource);\n return readId(v3Body) ?? readId(v2Body);\n};\n\nconst bodyItems = (body: unknown): JsonObject[] => {\n const values = asArray(body).flatMap((item) => {\n const object = asObject(item);\n if (!object) return [];\n const type = readType(object)?.toLowerCase();\n if (type?.includes('choice') || Array.isArray(object.items) || Array.isArray(object.item)) {\n return asArray(object.items ?? object.item ?? object.default).flatMap((choice) => {\n const choiceObject = asObject(choice);\n return choiceObject ? [choiceObject] : [];\n });\n }\n return [object];\n });\n return values;\n};\n\nconst sourceFromBody = (\n body: JsonObject,\n canvas: JsonObject,\n target: unknown,\n languages: string[],\n index: number,\n ui: AVStrings,\n annotationTimeMode?: unknown,\n): MediaSource | undefined => {\n const originalId = readId(body);\n if (!originalId) return undefined;\n const format = readFormat(body);\n const kind = mediaKind(readType(body), format, originalId);\n if (!kind) return undefined;\n const result: MediaSource = {\n id: originalId,\n src: withoutFragment(originalId),\n kind,\n isHls: isHls(originalId, format),\n };\n if (format) result.format = format;\n const bodyLabel = label(body.label, languages, index === 0\n ? ui.autoSource\n : formatString(ui.sourceNumber, { number: index + 1 }));\n if (bodyLabel) result.label = bodyLabel;\n const width = number(body.width) ?? number(canvas.width);\n const height = number(body.height) ?? number(canvas.height);\n const duration = number(body.duration) ?? number(canvas.duration);\n if (width !== undefined) result.width = width;\n if (height !== undefined) result.height = height;\n if (duration !== undefined) result.duration = duration;\n const quality = typeof body.quality === 'string' ? body.quality : undefined;\n if (quality) result.quality = quality;\n const segment = parseTemporalFragment(originalId);\n if (segment) result.segment = segment;\n const canvasTarget = parseTemporalFragment(target);\n if (canvasTarget) result.canvasTarget = canvasTarget;\n const timeMode = body.timeMode ?? annotationTimeMode;\n if (timeMode === 'trim' || timeMode === 'scale' || timeMode === 'loop') result.timeMode = timeMode;\n return result;\n};\n\nconst textualBodies = (body: unknown): JsonObject[] =>\n bodyItems(body).filter((item) => {\n const type = readType(item)?.toLowerCase();\n return type?.includes('textualbody') || typeof item.value === 'string';\n });\n\nconst annotationMotivations = (annotation: JsonObject): string[] => strings(annotation.motivation);\n\nconst annotationFrom = (\n value: unknown,\n canvasId: string,\n pageId: string | undefined,\n languages: string[],\n index: number,\n): AVAnnotation | undefined => {\n const annotation = asObject(value);\n if (!annotation) return undefined;\n const bodies = textualBodies(annotation.body ?? annotation.resource);\n const text = bodies\n .flatMap((body) => (typeof body.value === 'string' ? [body.value] : languageValues(body.chars).map((entry) => entry.value)))\n .join('\\n');\n if (!text) return undefined;\n const motivation = annotationMotivations(annotation);\n const purpose = bodies.flatMap((body) => strings(body.purpose));\n const tags = bodies\n .filter((body) => strings(body.purpose).includes('tagging'))\n .flatMap((body) => (typeof body.value === 'string' ? [body.value] : []));\n const id = readId(annotation) ?? `${canvasId}/annotation/${index}`;\n const result: AVAnnotation = {\n id,\n canvasId,\n motivation,\n purpose,\n text,\n tags,\n };\n const annotationLabel = label(annotation.label, languages);\n if (annotationLabel) result.label = annotationLabel;\n const time = parseTemporalFragment(annotation.target ?? annotation.on);\n if (time) result.time = time;\n if (pageId) result.sourcePageId = pageId;\n return result;\n};\n\nconst classifySupplement = (\n body: JsonObject,\n annotation: JsonObject,\n canvasId: string,\n languages: string[],\n index: number,\n ui: AVStrings,\n): { track?: TextTrack; transcript?: TranscriptResource } => {\n const id = readId(body);\n if (!id) return {};\n const format = readFormat(body);\n const bodyLabel = label(body.label, languages, formatString(ui.transcriptNumber, { number: index + 1 }));\n const language = typeof body.language === 'string' ? body.language : undefined;\n const purpose = strings(body.purpose);\n const lower = `${bodyLabel} ${id} ${purpose.join(' ')}`.toLowerCase();\n const isTimedTrack = format === 'text/vtt' || /\\.vtt(?:$|[?#])/.test(id);\n let kind: TextTrack['kind'] = 'subtitles';\n if (lower.includes('caption')) kind = 'captions';\n if (lower.includes('description')) kind = 'descriptions';\n const result: { track?: TextTrack; transcript?: TranscriptResource } = {};\n if (isTimedTrack) {\n const track: TextTrack = { id, src: id, kind, label: bodyLabel };\n if (language) track.language = language;\n if (format) track.format = format;\n if (lower.includes('forced')) track.forced = true;\n result.track = track;\n }\n const transcript: TranscriptResource = {\n id: `${canvasId}/transcript/${index}`,\n src: id,\n label: bodyLabel,\n machineGenerated: /\\(machine[ -]generated\\)/i.test(bodyLabel),\n };\n if (format) transcript.format = format;\n if (language) transcript.language = language;\n result.transcript = transcript;\n return result;\n};\n\nconst annotationPageItems = (page: JsonObject): unknown[] => asArray(page.items ?? page.resources);\n\nconst collectSupplementing = (\n pages: JsonObject[],\n canvasId: string,\n languages: string[],\n ui: AVStrings,\n): { tracks: TextTrack[]; transcripts: TranscriptResource[]; annotations: AVAnnotation[] } => {\n const tracks: TextTrack[] = [];\n const transcripts: TranscriptResource[] = [];\n const annotations: AVAnnotation[] = [];\n let index = 0;\n for (const page of pages) {\n const pageId = readId(page);\n for (const item of annotationPageItems(page)) {\n const annotation = asObject(item);\n if (!annotation) continue;\n const motivations = annotationMotivations(annotation);\n const normalizedAnnotation = annotationFrom(annotation, canvasId, pageId, languages, index);\n if (normalizedAnnotation) annotations.push(normalizedAnnotation);\n for (const body of bodyItems(annotation.body ?? annotation.resource)) {\n const bodyId = readId(body);\n if (bodyId && (motivations.includes('supplementing') || motivations.includes('transcribing') || motivations.length === 0)) {\n const supplement = classifySupplement(body, annotation, canvasId, languages, index, ui);\n if (supplement.track) tracks.push(supplement.track);\n if (supplement.transcript) transcripts.push(supplement.transcript);\n }\n }\n const inline = textualBodies(annotation.body ?? annotation.resource);\n if (inline.length > 0 && (motivations.includes('supplementing') || motivations.includes('transcribing'))) {\n const cues: TranscriptCue[] = inline.flatMap((body, bodyIndex) => {\n const text = typeof body.value === 'string' ? body.value : label(body.chars, languages);\n if (!text) return [];\n const cue: TranscriptCue = {\n id: `${readId(annotation) ?? `${canvasId}/annotation/${index}`}/cue/${bodyIndex}`,\n text,\n type: 'cue',\n };\n const time = parseTemporalFragment(annotation.target ?? annotation.on);\n if (time) {\n cue.start = time.start;\n if (time.end !== undefined) cue.end = time.end;\n }\n return [cue];\n });\n if (cues.length > 0) {\n const transcriptId = `${pageId ?? canvasId}/inline-transcript`;\n const existing = transcripts.find((transcript) => transcript.id === transcriptId);\n if (existing?.cues) existing.cues.push(...cues);\n else {\n transcripts.push({\n id: transcriptId,\n label: label(page.label, languages, ui.transcript),\n machineGenerated: false,\n cues,\n });\n }\n }\n }\n index += 1;\n }\n }\n return { tracks, transcripts, annotations };\n};\n\nconst paintingAnnotations = (canvas: JsonObject, version: 2 | 3): JsonObject[] => {\n if (version === 2) {\n return asArray(canvas.images).flatMap((item) => {\n const object = asObject(item);\n return object ? [object] : [];\n });\n }\n return asArray(canvas.items).flatMap((page) => {\n const object = asObject(page);\n return object ? annotationPageItems(object).flatMap((item) => (asObject(item) ? [asObject(item) as JsonObject] : [])) : [];\n });\n};\n\nconst inlineSupplementPages = (canvas: JsonObject, version: 2 | 3): JsonObject[] => {\n const raw = version === 2 ? canvas.otherContent : canvas.annotations;\n return asArray(raw).flatMap((item) => {\n const object = asObject(item);\n return object && (Array.isArray(object.items) || Array.isArray(object.resources)) ? [object] : [];\n });\n};\n\nconst externalSupplementReferences = (canvas: JsonObject, version: 2 | 3): string[] => {\n const raw = version === 2 ? canvas.otherContent : canvas.annotations;\n return asArray(raw).flatMap((item) => {\n const object = asObject(item);\n if (object && (Array.isArray(object.items) || Array.isArray(object.resources))) return [];\n const id = readId(item);\n return id ? [id] : [];\n });\n};\n\nconst posterFrom = (canvas: JsonObject): string | undefined => {\n const placeholder = asObject(canvas.placeholderCanvas);\n return firstContentId(placeholder);\n};\n\nconst canvasFrom = (\n canvas: JsonObject,\n index: number,\n version: 2 | 3,\n languages: string[],\n ui: AVStrings,\n): AVCanvas => {\n const id = readId(canvas) ?? `urn:mango:canvas:${index}`;\n const sources = paintingAnnotations(canvas, version).flatMap((annotation, annotationIndex) =>\n bodyItems(annotation.body ?? annotation.resource).flatMap((body, bodyIndex) => {\n const source = sourceFromBody(body, canvas, annotation.target ?? annotation.on, languages, annotationIndex + bodyIndex, ui, annotation.timeMode);\n return source ? [source] : [];\n }),\n );\n const supplementing = collectSupplementing(inlineSupplementPages(canvas, version), id, languages, ui);\n const result: AVCanvas = {\n id,\n index,\n label: label(canvas.label, languages, formatString(ui.sectionNumber, { number: index + 1 })),\n behavior: strings(canvas.behavior ?? canvas.viewingHint),\n sources,\n tracks: supplementing.tracks,\n transcripts: [...supplementing.transcripts, ...renderingTranscripts(canvas.rendering, languages, ui)],\n annotations: supplementing.annotations,\n rendering: downloads(canvas.rendering, languages, ui),\n metadata: metadata(canvas.metadata, languages, ui),\n authServices: services(canvas.service, languages),\n };\n const summary = label(canvas.summary ?? canvas.description, languages);\n if (summary) result.summary = summary;\n const duration = number(canvas.duration);\n const width = number(canvas.width);\n const height = number(canvas.height);\n if (duration !== undefined) result.duration = duration;\n if (width !== undefined) result.width = width;\n if (height !== undefined) result.height = height;\n const poster = posterFrom(canvas);\n if (poster) result.poster = poster;\n const accompanying = readId(canvas.accompanyingCanvas);\n if (accompanying) result.accompanyingCanvas = accompanying;\n const homepage = readId(asArray(canvas.homepage ?? canvas.related)[0]);\n if (homepage) result.homepage = homepage;\n return result;\n};\n\nconst resolveRangeTarget = (value: unknown): { canvasId?: string; time?: { start: number; end?: number } } => {\n const id = readId(value) ?? readId(asObject(value)?.source);\n if (!id) return {};\n const result: { canvasId?: string; time?: { start: number; end?: number } } = { canvasId: withoutFragment(id) };\n const time = parseTemporalFragment(id);\n if (time) result.time = time;\n return result;\n};\n\nconst chaptersFrom = (manifest: JsonObject, version: 2 | 3, languages: string[], ui: AVStrings): Chapter[] => {\n const rawStructures = asArray(manifest.structures).flatMap((item) => (asObject(item) ? [asObject(item) as JsonObject] : []));\n const byId = new Map(rawStructures.map((range) => [readId(range), range]));\n const seen = new Set<JsonObject>();\n\n const parseRange = (range: JsonObject, depth = 0): Chapter | undefined => {\n if (depth > 50 || seen.has(range)) return undefined;\n seen.add(range);\n const rangeBehavior = strings(range.behavior ?? range.viewingHint);\n if (rangeBehavior.includes('no-nav') || rangeBehavior.includes('thumbnail-nav')) return undefined;\n const id = readId(range) ?? `urn:mango:range:${seen.size}`;\n const members = version === 3\n ? asArray(range.items)\n : asArray(range.members ?? range.ranges ?? range.canvases);\n const children: Chapter[] = [];\n let target: ReturnType<typeof resolveRangeTarget> = {};\n for (const member of members) {\n const object = asObject(member);\n const memberId = readId(member);\n const memberType = readType(object)?.toLowerCase();\n const referencedRange = memberId ? byId.get(memberId) : undefined;\n if (referencedRange || memberType?.includes('range') || (object && (object.items || object.ranges || object.members))) {\n const child = parseRange(referencedRange ?? (object as JsonObject), depth + 1);\n if (child) children.push(child);\n } else if (!target.canvasId && memberId) {\n target = resolveRangeTarget(member);\n }\n }\n const result: Chapter = {\n id,\n label: label(range.label, languages, formatString(ui.chapterNumber, { number: seen.size })),\n behavior: rangeBehavior,\n children,\n };\n if (target.canvasId) result.canvasId = target.canvasId;\n if (target.time) result.time = target.time;\n const summary = label(range.summary ?? range.description, languages);\n if (summary) result.summary = summary;\n const homepage = readId(asArray(range.homepage ?? range.related)[0]);\n if (homepage) result.homepage = homepage;\n return result;\n };\n\n return rawStructures.flatMap((range) => {\n const chapter = parseRange(range);\n return chapter ? [chapter] : [];\n });\n};\n\nconst startFrom = (manifest: JsonObject, version: 2 | 3): AVManifest['start'] => {\n const value = version === 2\n ? asObject(asArray(manifest.sequences)[0])?.startCanvas ?? manifest.startCanvas\n : manifest.start;\n const id = readId(value) ?? readId(asObject(value)?.source);\n if (!id) return undefined;\n const result: NonNullable<AVManifest['start']> = { canvasId: withoutFragment(id) };\n const time = parseTemporalFragment(value) ?? parseTemporalFragment(id);\n if (time) result.time = time.start;\n return result;\n};\n\nconst manifestCanvases = (manifest: JsonObject, version: 2 | 3): JsonObject[] => {\n const raw = version === 3\n ? manifest.items\n : asObject(asArray(manifest.sequences)[0])?.canvases;\n return asArray(raw).flatMap((item) => (asObject(item) ? [asObject(item) as JsonObject] : []));\n};\n\nconst detectVersion = (manifest: JsonObject): 2 | 3 => {\n const context = JSON.stringify(manifest['@context'] ?? '');\n if (context.includes('/presentation/2/')) return 2;\n if (Array.isArray(manifest.sequences) || readType(manifest)?.startsWith('sc:')) return 2;\n return 3;\n};\n\nexport const normalizeManifest = async (\n input: JsonObject | string,\n options: NormalizeOptions = {},\n): Promise<AVManifest> => {\n const ui = resolveStrings(options.strings);\n const fetcher = options.fetch ?? globalThis.fetch;\n let source: JsonObject;\n if (typeof input === 'string') {\n if (input.trim().startsWith('{')) {\n source = JSON.parse(input) as JsonObject;\n } else {\n if (!fetcher) throw new Error('No fetch implementation is available to load the IIIF manifest.');\n const response = await fetcher(input, options.requestInit);\n if (!response.ok) throw new Error(formatString(ui.unableToLoadManifest, {\n status: response.status,\n statusText: response.statusText,\n }));\n source = await response.json() as JsonObject;\n }\n } else {\n source = input;\n }\n const type = readType(source)?.toLowerCase();\n if (type && !type.includes('manifest')) throw new Error(formatString(ui.expectedManifest, {\n type: readType(source) ?? '',\n }));\n const version = detectVersion(source);\n const languages = options.preferredLanguages ?? ['en', 'none'];\n const canvases = manifestCanvases(source, version).map((canvas, index) => canvasFrom(canvas, index, version, languages, ui));\n if (canvases.length === 0) throw new Error(ui.manifestWithoutCanvases);\n\n if (options.loadExternalAnnotations !== false && fetcher) {\n const rawCanvases = manifestCanvases(source, version);\n await Promise.all(rawCanvases.map(async (canvas, index) => {\n const target = canvases[index];\n if (!target) return;\n const references = externalSupplementReferences(canvas, version);\n const loaded = await Promise.all(references.map(async (url) => {\n try {\n const response = await fetcher(url, options.requestInit);\n if (!response.ok) return undefined;\n return asObject(await response.json());\n } catch {\n return undefined;\n }\n }));\n const parsed = collectSupplementing(loaded.filter((page): page is JsonObject => Boolean(page)), target.id, languages, ui);\n target.tracks.push(...parsed.tracks);\n target.transcripts.push(...parsed.transcripts);\n target.annotations.push(...parsed.annotations);\n }));\n }\n\n const id = readId(source) ?? 'urn:mango:manifest';\n const result: AVManifest = {\n id,\n type: 'Manifest',\n version,\n label: label(source.label, languages, ui.untitledManifest),\n behavior: strings(source.behavior ?? source.viewingHint),\n canvases,\n chapters: chaptersFrom(source, version, languages, ui),\n metadata: metadata(source.metadata, languages, ui),\n rendering: downloads(source.rendering, languages, ui),\n };\n const summary = label(source.summary ?? source.description, languages);\n if (summary) result.summary = summary;\n const start = startFrom(source, version);\n if (start) result.start = start;\n if (typeof source.rights === 'string') result.rights = source.rights;\n const requiredStatement = metadata([source.requiredStatement ?? source.attribution], languages, ui)[0];\n if (requiredStatement) result.requiredStatement = requiredStatement;\n const homepage = readId(asArray(source.homepage ?? source.related)[0]);\n if (homepage) result.homepage = homepage;\n const logo = readId(asArray(source.logo ?? source.provider)[0]);\n if (logo) result.logo = logo;\n return result;\n};\n","import { normalizeManifest } from './iiif/normalize';\nimport type {\n AVCanvas,\n AVAnnotation,\n AVAnnotationDraft,\n AVManifest,\n AVPlayerConfig,\n AVPlayerEventMap,\n AVPlayerState,\n JsonObject,\n MediaSource,\n} from './types';\nimport { defaultConfig } from './types';\nimport { mergeConfig, withoutFragment } from './utils';\n\ntype ResolvedConfig = AVPlayerConfig & typeof defaultConfig;\n\ninterface SavedPosition {\n time: number;\n savedAt: number;\n}\n\nconst positionPrefix = '@mango-iiif/av:position:';\n\nexport class AVPlayerController extends EventTarget {\n #config: ResolvedConfig;\n #state: AVPlayerState = {\n status: 'idle',\n canvasIndex: 0,\n sourceIndex: 0,\n currentTime: 0,\n duration: 0,\n volume: 1,\n muted: false,\n playbackRate: 1,\n autoAdvance: false,\n repeat: false,\n };\n #media: HTMLMediaElement | undefined;\n #lastTime = 0;\n #timelineScale = 1;\n #pendingTime: number | undefined;\n #boundListeners = new Map<string, EventListener>();\n #crossoriginExplicit: boolean;\n\n constructor(config: AVPlayerConfig = {}) {\n super();\n this.#crossoriginExplicit = Object.hasOwn(config, 'crossorigin');\n this.#config = mergeConfig(defaultConfig, config) as ResolvedConfig;\n this.#state.autoAdvance = this.#config.autoAdvance;\n this.#state.repeat = this.#config.repeat;\n }\n\n get config(): Readonly<ResolvedConfig> {\n return this.#config;\n }\n\n get state(): Readonly<AVPlayerState> {\n return this.#state;\n }\n\n get manifest(): AVManifest | undefined {\n return this.#state.manifest;\n }\n\n get canvas(): AVCanvas | undefined {\n return this.#state.manifest?.canvases[this.#state.canvasIndex];\n }\n\n get source(): MediaSource | undefined {\n return this.canvas?.sources[this.#state.sourceIndex];\n }\n\n get media(): HTMLMediaElement | undefined {\n return this.#media;\n }\n\n /** Whether the host explicitly selected the media element CORS policy. */\n get crossoriginExplicit(): boolean {\n return this.#crossoriginExplicit;\n }\n\n on<K extends keyof AVPlayerEventMap>(\n type: K,\n listener: (event: CustomEvent<AVPlayerEventMap[K]>) => void,\n ): () => void {\n const eventListener = listener as EventListener;\n this.addEventListener(type, eventListener);\n return () => this.removeEventListener(type, eventListener);\n }\n\n configure(config: AVPlayerConfig): void {\n if (Object.hasOwn(config, 'crossorigin')) this.#crossoriginExplicit = true;\n this.#config = mergeConfig(\n this.#config as unknown as Record<string, unknown>,\n config as unknown as Record<string, unknown>,\n ) as unknown as ResolvedConfig;\n if (config.autoAdvance !== undefined) this.#state.autoAdvance = config.autoAdvance;\n if (config.repeat !== undefined) this.#state.repeat = config.repeat;\n this.#emit('av-configchange', { config: this.#config });\n this.#emitState();\n }\n\n async load(input: JsonObject | string): Promise<AVManifest> {\n this.#state.status = 'loading';\n delete this.#state.error;\n this.#emit('av-loadstart', { source: input });\n this.#emitState();\n try {\n const normalizeOptions: Parameters<typeof normalizeManifest>[1] = {\n preferredLanguages: this.#config.preferredLanguages,\n strings: this.#config.strings,\n };\n if (this.#config.fetch) normalizeOptions.fetch = this.#config.fetch;\n if (this.#config.requestInit) normalizeOptions.requestInit = this.#config.requestInit;\n const manifest = await normalizeManifest(input, normalizeOptions);\n this.#state.manifest = manifest;\n const requestedCanvas = this.#config.startCanvasId ?? manifest.start?.canvasId;\n const canvasIndex = requestedCanvas\n ? Math.max(0, manifest.canvases.findIndex((canvas) => canvas.id === withoutFragment(requestedCanvas)))\n : 0;\n this.#state.canvasIndex = canvasIndex;\n this.#state.sourceIndex = 0;\n this.#timelineScale = 1;\n this.#state.currentTime = 0;\n this.#state.duration = this.canvas?.duration ?? 0;\n this.#state.autoAdvance = this.#config.autoAdvance || manifest.behavior.includes('auto-advance');\n this.#state.repeat = this.#config.repeat || manifest.behavior.includes('repeat');\n this.#state.status = 'ready';\n const initialTime = this.#config.startTime ?? manifest.start?.time ?? this.source?.canvasTarget?.start;\n if (initialTime !== undefined) this.#pendingTime = initialTime;\n this.#emit('av-ready', { manifest });\n const canvas = this.canvas;\n if (canvas) this.#emit('av-canvaschange', { canvas, canvasIndex });\n this.#emitState();\n return manifest;\n } catch (cause) {\n const error = cause instanceof Error ? cause : new Error(String(cause));\n this.#state.status = 'error';\n this.#state.error = error;\n this.#emit('av-error', { error });\n this.#emitState();\n throw error;\n }\n }\n\n attachMedia(media: HTMLMediaElement): void {\n if (this.#media === media) return;\n this.detachMedia();\n this.#media = media;\n const listeners: Record<string, EventListener> = {\n loadedmetadata: () => {\n const segment = this.source?.segment;\n const target = this.source?.canvasTarget;\n if (this.source?.timeMode === 'scale' && target?.end !== undefined && Number.isFinite(media.duration)) {\n const sourceDuration = segment?.end !== undefined ? segment.end - segment.start : media.duration;\n const targetDuration = target.end - target.start;\n if (sourceDuration > 0 && targetDuration > 0) {\n this.#timelineScale = sourceDuration / targetDuration;\n media.playbackRate = this.#timelineScale;\n }\n }\n const pending = this.#pendingTime ?? target?.start;\n if (pending !== undefined) {\n media.currentTime = this.#toMediaTime(pending);\n this.#pendingTime = undefined;\n }\n this.#state.duration = this.canvas?.duration ?? target?.end ?? (Number.isFinite(media.duration) ? this.#toCanvasTime(media.duration) : 0);\n this.#emitState();\n },\n play: () => {\n this.#state.status = 'playing';\n this.#emit('av-play', { canvasId: this.canvas?.id ?? '', time: this.#toCanvasTime(media.currentTime) });\n this.#emitState();\n },\n pause: () => {\n if (!media.ended) this.#state.status = 'paused';\n this.#savePosition();\n this.#emit('av-pause', { canvasId: this.canvas?.id ?? '', time: this.#toCanvasTime(media.currentTime) });\n this.#emitState();\n },\n timeupdate: () => {\n const time = this.#toCanvasTime(media.currentTime);\n const duration = this.canvas?.duration ?? this.source?.canvasTarget?.end ?? (Number.isFinite(media.duration) ? this.#toCanvasTime(media.duration) : 0);\n this.#state.currentTime = time;\n this.#state.duration = duration;\n this.#emit('av-timeupdate', { canvasId: this.canvas?.id ?? '', time, duration });\n const end = this.source?.canvasTarget?.end ?? (this.source?.segment?.end !== undefined ? this.#toCanvasTime(this.source.segment.end) : undefined);\n if (end !== undefined && time >= end) {\n if (this.source?.timeMode === 'loop') {\n media.currentTime = this.source.segment?.start ?? 0;\n } else {\n media.pause();\n void this.#advanceAfterEnd();\n }\n }\n this.#lastTime = time;\n this.#emitState();\n },\n seeking: () => {\n const time = this.#toCanvasTime(media.currentTime);\n this.#state.currentTime = time;\n this.#emit('av-seek', { canvasId: this.canvas?.id ?? '', from: this.#lastTime, to: time });\n this.#emitState();\n },\n volumechange: () => {\n this.#state.volume = media.volume;\n this.#state.muted = media.muted;\n this.#emitState();\n },\n ratechange: () => {\n this.#state.playbackRate = media.playbackRate;\n this.#emitState();\n },\n ended: () => {\n this.#state.status = 'ended';\n this.#emit('av-ended', { canvasId: this.canvas?.id ?? '' });\n this.#clearPosition();\n this.#emitState();\n void this.#advanceAfterEnd();\n },\n error: () => {\n const error = new Error(media.error?.message ?? 'The media resource could not be played.');\n this.#state.status = 'error';\n this.#state.error = error;\n this.#emit('av-error', { error });\n this.#emitState();\n },\n };\n for (const [type, listener] of Object.entries(listeners)) {\n media.addEventListener(type, listener);\n this.#boundListeners.set(type, listener);\n }\n }\n\n detachMedia(): void {\n if (!this.#media) return;\n for (const [type, listener] of this.#boundListeners) this.#media.removeEventListener(type, listener);\n this.#boundListeners.clear();\n this.#media = undefined;\n }\n\n async play(): Promise<void> {\n await this.#media?.play();\n }\n\n pause(): void {\n this.#media?.pause();\n }\n\n stop(): void {\n this.pause();\n this.seekTo(this.source?.canvasTarget?.start ?? 0);\n }\n\n seekTo(time: number): void {\n const source = this.source;\n const minimum = source?.canvasTarget?.start ?? 0;\n const maximum = source?.canvasTarget?.end ?? this.#state.duration;\n const target = maximum > 0 ? Math.min(Math.max(time, minimum), maximum) : Math.max(time, minimum);\n if (this.#media && this.#media.readyState > 0) this.#media.currentTime = this.#toMediaTime(target);\n else this.#pendingTime = target;\n this.#state.currentTime = target;\n this.#emitState();\n }\n\n seekBy(delta: number): void {\n this.seekTo(this.#state.currentTime + delta);\n }\n\n selectCanvas(indexOrId: number | string, options: { time?: number; autoplay?: boolean } = {}): AVCanvas | undefined {\n const canvases = this.#state.manifest?.canvases ?? [];\n const index = typeof indexOrId === 'number'\n ? indexOrId\n : canvases.findIndex((canvas) => canvas.id === withoutFragment(indexOrId));\n if (index < 0 || index >= canvases.length) return undefined;\n const wasPlaying = options.autoplay ?? this.#state.status === 'playing';\n const canvas = canvases[index];\n const time = options.time ?? canvas?.sources[0]?.canvasTarget?.start ?? 0;\n if (index === this.#state.canvasIndex) {\n this.seekTo(time);\n if (wasPlaying) queueMicrotask(() => void this.play());\n return canvas;\n }\n this.#state.canvasIndex = index;\n this.#state.sourceIndex = 0;\n this.#timelineScale = 1;\n this.#state.currentTime = time;\n this.#state.duration = canvas?.duration ?? 0;\n this.#pendingTime = this.#state.currentTime;\n if (canvas) this.#emit('av-canvaschange', { canvas, canvasIndex: index });\n this.#emitState();\n if (wasPlaying) queueMicrotask(() => void this.play());\n return canvas;\n }\n\n next(options: { autoplay?: boolean } = {}): AVCanvas | undefined {\n const count = this.#state.manifest?.canvases.length ?? 0;\n if (this.#state.canvasIndex + 1 < count) return this.selectCanvas(this.#state.canvasIndex + 1, options);\n if (this.#state.repeat && count > 0) return this.selectCanvas(0, options);\n return undefined;\n }\n\n previous(options: { autoplay?: boolean } = {}): AVCanvas | undefined {\n if (this.#state.canvasIndex > 0) return this.selectCanvas(this.#state.canvasIndex - 1, options);\n return undefined;\n }\n\n selectSource(index: number): MediaSource | undefined {\n const sources = this.canvas?.sources ?? [];\n const source = sources[index];\n if (!source) return undefined;\n const wasPlaying = this.#state.status === 'playing';\n const currentTime = this.#state.currentTime;\n this.#state.sourceIndex = index;\n this.#timelineScale = 1;\n this.#pendingTime = currentTime;\n this.#emit('av-sourcechange', { source, sourceIndex: index });\n this.#emitState();\n if (wasPlaying) queueMicrotask(() => void this.play());\n return source;\n }\n\n async createAnnotation(draft: AVAnnotationDraft): Promise<AVAnnotation> {\n const canvas = this.canvas;\n if (!canvas) throw new Error('A Canvas must be active before creating an annotation.');\n const created = this.#config.annotationAdapter?.create\n ? await this.#config.annotationAdapter.create(canvas, draft)\n : this.#annotationFromDraft(canvas, draft);\n canvas.annotations.push(created);\n this.#emit('av-annotationschange', { canvasId: canvas.id, annotations: [...canvas.annotations] });\n this.#emitState();\n return created;\n }\n\n async updateAnnotation(id: string, update: Partial<AVAnnotationDraft>): Promise<AVAnnotation> {\n const canvas = this.canvas;\n if (!canvas) throw new Error('A Canvas must be active before updating an annotation.');\n const index = canvas.annotations.findIndex((annotation) => annotation.id === id);\n const current = canvas.annotations[index];\n if (!current) throw new Error(`Annotation ${id} was not found on the active Canvas.`);\n const candidate: AVAnnotation = {\n ...current,\n ...update,\n motivation: update.motivation ?? current.motivation,\n purpose: update.purpose ?? current.purpose,\n tags: update.tags ?? current.tags,\n };\n const saved = this.#config.annotationAdapter?.update\n ? await this.#config.annotationAdapter.update(canvas, candidate)\n : candidate;\n canvas.annotations[index] = saved;\n this.#emit('av-annotationschange', { canvasId: canvas.id, annotations: [...canvas.annotations] });\n this.#emitState();\n return saved;\n }\n\n async removeAnnotation(id: string): Promise<void> {\n const canvas = this.canvas;\n if (!canvas) throw new Error('A Canvas must be active before removing an annotation.');\n const index = canvas.annotations.findIndex((annotation) => annotation.id === id);\n const current = canvas.annotations[index];\n if (!current) throw new Error(`Annotation ${id} was not found on the active Canvas.`);\n if (this.#config.annotationAdapter?.remove) await this.#config.annotationAdapter.remove(canvas, current);\n canvas.annotations.splice(index, 1);\n this.#emit('av-annotationschange', { canvasId: canvas.id, annotations: [...canvas.annotations] });\n this.#emitState();\n }\n\n setAutoAdvance(enabled: boolean): void {\n this.#state.autoAdvance = enabled;\n this.#emitState();\n }\n\n setRepeat(enabled: boolean): void {\n this.#state.repeat = enabled;\n this.#emitState();\n }\n\n getSavedPosition(): number | undefined {\n if (!this.#config.resume.enabled || !this.canvas || typeof localStorage === 'undefined') return undefined;\n const raw = localStorage.getItem(`${positionPrefix}${this.#state.manifest?.id}:${this.canvas.id}`);\n if (!raw) return undefined;\n try {\n const saved = JSON.parse(raw) as SavedPosition;\n const ttl = (this.#config.resume.ttlDays ?? 30) * 86_400_000;\n if (Date.now() - saved.savedAt > ttl) {\n this.#clearPosition();\n return undefined;\n }\n return saved.time;\n } catch {\n return undefined;\n }\n }\n\n destroy(): void {\n this.#savePosition();\n this.detachMedia();\n }\n\n async resolvedSourceUrl(): Promise<string | undefined> {\n const source = this.source;\n if (!source) return undefined;\n if (!this.#config.resolveRequest) return source.src;\n const context: { manifest?: AVManifest; canvas?: AVCanvas } = {};\n if (this.manifest) context.manifest = this.manifest;\n if (this.canvas) context.canvas = this.canvas;\n return await this.#config.resolveRequest(source.src, context);\n }\n\n async #advanceAfterEnd(): Promise<void> {\n if (!this.#state.autoAdvance) return;\n const next = this.next({ autoplay: true });\n if (!next) this.#state.status = 'ended';\n }\n\n #savePosition(): void {\n if (!this.#config.resume.enabled || !this.canvas || typeof localStorage === 'undefined') return;\n const time = this.#state.currentTime;\n if (time <= 0 || (this.#state.duration > 0 && time >= this.#state.duration - 2)) return;\n const key = `${positionPrefix}${this.#state.manifest?.id}:${this.canvas.id}`;\n localStorage.setItem(key, JSON.stringify({ time, savedAt: Date.now() } satisfies SavedPosition));\n const keys = Object.keys(localStorage).filter((item) => item.startsWith(positionPrefix));\n const maxItems = this.#config.resume.maxItems ?? 200;\n if (keys.length > maxItems) {\n const oldest = keys\n .map((item) => ({ item, value: JSON.parse(localStorage.getItem(item) ?? '{}') as Partial<SavedPosition> }))\n .sort((a, b) => (a.value.savedAt ?? 0) - (b.value.savedAt ?? 0))[0];\n if (oldest) localStorage.removeItem(oldest.item);\n }\n }\n\n #clearPosition(): void {\n if (!this.canvas || typeof localStorage === 'undefined') return;\n localStorage.removeItem(`${positionPrefix}${this.#state.manifest?.id}:${this.canvas.id}`);\n }\n\n #emit<K extends keyof AVPlayerEventMap>(type: K, detail: AVPlayerEventMap[K]): void {\n this.dispatchEvent(new CustomEvent(type, { detail, bubbles: false, composed: false }));\n }\n\n #emitState(): void {\n this.#emit('av-statechange', { ...this.#state });\n }\n\n #annotationFromDraft(canvas: AVCanvas, draft: AVAnnotationDraft): AVAnnotation {\n const annotation: AVAnnotation = {\n id: `${canvas.id}/annotation/${crypto.randomUUID?.() ?? Date.now()}`,\n canvasId: canvas.id,\n motivation: draft.motivation ?? ['commenting'],\n purpose: draft.purpose ?? ['commenting'],\n text: draft.text,\n tags: draft.tags ?? [],\n };\n if (draft.label) annotation.label = draft.label;\n if (draft.time) annotation.time = draft.time;\n return annotation;\n }\n\n #toCanvasTime(mediaTime: number): number {\n const sourceStart = this.source?.segment?.start ?? 0;\n const targetStart = this.source?.canvasTarget?.start ?? 0;\n const scale = this.source?.timeMode === 'scale' ? this.#timelineScale : 1;\n return targetStart + ((mediaTime - sourceStart) / scale);\n }\n\n #toMediaTime(canvasTime: number): number {\n const sourceStart = this.source?.segment?.start ?? 0;\n const targetStart = this.source?.canvasTarget?.start ?? 0;\n const scale = this.source?.timeMode === 'scale' ? this.#timelineScale : 1;\n return sourceStart + ((canvasTime - targetStart) * scale);\n }\n}\n"],"mappings":"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","names":["strings","canvas"]}
|
|
@@ -1,24 +1,26 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AudioArtVisualizer,
|
|
3
|
+
applyMediaSource,
|
|
3
4
|
audioArtContentHtml,
|
|
4
5
|
audioArtTranscriptHtml,
|
|
5
6
|
ensureMediaChrome,
|
|
7
|
+
resolveAudioMediaPolicy,
|
|
6
8
|
resolveAudioVisualizerMode,
|
|
7
9
|
syncAudioArtTranscript
|
|
8
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-ELGGWWDS.js";
|
|
9
11
|
import {
|
|
10
12
|
playFromInteraction
|
|
11
13
|
} from "./chunk-CDLYT3KB.js";
|
|
12
14
|
import {
|
|
13
15
|
loadTranscript
|
|
14
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-CIAQZ2EB.js";
|
|
15
17
|
import {
|
|
16
18
|
AVPlayerController,
|
|
17
19
|
escapeHtml,
|
|
18
20
|
formatString,
|
|
19
21
|
formatTime,
|
|
20
22
|
resolveStrings
|
|
21
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-4NOWGMI5.js";
|
|
22
24
|
|
|
23
25
|
// src/components/mango-av-media.ts
|
|
24
26
|
var HTMLElementBase = globalThis.HTMLElement ?? class {
|
|
@@ -41,7 +43,8 @@ var eventTypes = [
|
|
|
41
43
|
"av-ended",
|
|
42
44
|
"av-annotationschange",
|
|
43
45
|
"av-configchange",
|
|
44
|
-
"av-statechange"
|
|
46
|
+
"av-statechange",
|
|
47
|
+
"av-visualizerfallback"
|
|
45
48
|
];
|
|
46
49
|
var styles = `
|
|
47
50
|
:host {
|
|
@@ -171,6 +174,7 @@ var MangoAVMediaElement = class extends HTMLElementBase {
|
|
|
171
174
|
#loadingToken = 0;
|
|
172
175
|
#resolvedSourceUrl;
|
|
173
176
|
#sourceToken = 0;
|
|
177
|
+
#fallbackSourceUrl;
|
|
174
178
|
#visualizer = new AudioArtVisualizer();
|
|
175
179
|
constructor() {
|
|
176
180
|
super();
|
|
@@ -180,7 +184,7 @@ var MangoAVMediaElement = class extends HTMLElementBase {
|
|
|
180
184
|
this.player.addEventListener(type, ((event) => {
|
|
181
185
|
if (type === "av-ready") {
|
|
182
186
|
if (this.player.source?.isHls) void ensureHlsElement();
|
|
183
|
-
this.#
|
|
187
|
+
this.#resetSourceLoad();
|
|
184
188
|
this.#resumeTime = this.player.getSavedPosition();
|
|
185
189
|
this.#activePanel = this.player.config.activePanel;
|
|
186
190
|
this.#render();
|
|
@@ -188,15 +192,19 @@ var MangoAVMediaElement = class extends HTMLElementBase {
|
|
|
188
192
|
void this.#loadActiveTranscript();
|
|
189
193
|
} else if (type === "av-canvaschange" || type === "av-sourcechange") {
|
|
190
194
|
if (this.player.source?.isHls) void ensureHlsElement();
|
|
191
|
-
this.#
|
|
195
|
+
this.#resetSourceLoad();
|
|
192
196
|
this.#transcriptCues = [];
|
|
193
197
|
this.#transcriptIndex = 0;
|
|
194
198
|
this.#render();
|
|
195
199
|
void this.#resolveSource();
|
|
196
200
|
void this.#loadActiveTranscript();
|
|
197
201
|
} else if (type === "av-configchange") {
|
|
202
|
+
this.#resetSourceLoad();
|
|
198
203
|
this.#activePanel = this.player.config.activePanel;
|
|
199
|
-
void ensureMediaChrome(this.player.config.preferredLanguages[0]).then(() =>
|
|
204
|
+
void ensureMediaChrome(this.player.config.preferredLanguages[0]).then(() => {
|
|
205
|
+
this.#render();
|
|
206
|
+
void this.#resolveSource();
|
|
207
|
+
});
|
|
200
208
|
} else if (type === "av-error") {
|
|
201
209
|
this.#render();
|
|
202
210
|
} else if (type === "av-annotationschange") {
|
|
@@ -299,12 +307,7 @@ var MangoAVMediaElement = class extends HTMLElementBase {
|
|
|
299
307
|
</div>`;
|
|
300
308
|
this.#bindInteractions();
|
|
301
309
|
const media = this.#root.querySelector("video, audio, hls-video");
|
|
302
|
-
if (media)
|
|
303
|
-
this.player.attachMedia(media);
|
|
304
|
-
const art = this.#root.querySelector(".audio-art.visualizer");
|
|
305
|
-
const visualizerMode = resolveAudioVisualizerMode(this.player.config.audioArt.visualizer);
|
|
306
|
-
if (art && media instanceof HTMLAudioElement && visualizerMode) this.#visualizer.connect(media, art, visualizerMode);
|
|
307
|
-
}
|
|
310
|
+
if (media && this.#resolvedSourceUrl) this.#activateMedia(media, this.#resolvedSourceUrl);
|
|
308
311
|
this.#syncTimedContent();
|
|
309
312
|
}
|
|
310
313
|
#renderReady(manifest, canvas, kind) {
|
|
@@ -330,7 +333,7 @@ var MangoAVMediaElement = class extends HTMLElementBase {
|
|
|
330
333
|
<section class="player-column" aria-label="${escapeHtml(ui.mediaPlayer)}">
|
|
331
334
|
<slot name="before-player"></slot>
|
|
332
335
|
<media-controller ${kind === "audio" ? "audio" : ""} ${this.#mediaChromeLanguage()}>
|
|
333
|
-
${kind === "audio" ? `<div class="audio-art ${visualizerMode ? `visualizer visualizer--${visualizerMode}` : ""}">${audioArtContentHtml(canvas.label, this.#transcriptCues, Boolean(this.player.config.audioArt.transcript), visualizerMode)}</div>` : ""}
|
|
336
|
+
${kind === "audio" ? `<div class="audio-art ${visualizerMode ? `visualizer visualizer--${visualizerMode}` : ""}">${audioArtContentHtml(canvas.label, this.player.config.audioArt.title ?? "", this.#transcriptCues, Boolean(this.player.config.audioArt.transcript), visualizerMode)}</div>` : ""}
|
|
334
337
|
${source ? this.#mediaHtml(canvas, source.kind) : `<div class="audio-art"><span>${escapeHtml(ui.noPlayableMedia)}</span></div>`}
|
|
335
338
|
<slot name="player-overlay"></slot>
|
|
336
339
|
<slot name="controls">
|
|
@@ -373,10 +376,8 @@ var MangoAVMediaElement = class extends HTMLElementBase {
|
|
|
373
376
|
const source = this.player.source;
|
|
374
377
|
if (!source) return "";
|
|
375
378
|
const tag = source.isHls ? "hls-video" : kind;
|
|
376
|
-
const sourceUrl = this.#resolvedSourceUrl ?? (this.player.config.resolveRequest ? "" : source.src);
|
|
377
379
|
const attributes = [
|
|
378
380
|
'slot="media"',
|
|
379
|
-
sourceUrl ? `src="${escapeHtml(sourceUrl)}"` : "",
|
|
380
381
|
`preload="${this.player.config.preload}"`,
|
|
381
382
|
this.player.config.crossorigin ? `crossorigin="${this.player.config.crossorigin}"` : "",
|
|
382
383
|
kind === "video" && canvas.poster ? `poster="${escapeHtml(canvas.poster)}"` : "",
|
|
@@ -537,19 +538,74 @@ var MangoAVMediaElement = class extends HTMLElementBase {
|
|
|
537
538
|
}
|
|
538
539
|
}
|
|
539
540
|
async #resolveSource() {
|
|
540
|
-
if (!this.player.config.resolveRequest) return;
|
|
541
541
|
const token = ++this.#sourceToken;
|
|
542
542
|
try {
|
|
543
543
|
const sourceUrl = await this.player.resolvedSourceUrl();
|
|
544
544
|
if (token !== this.#sourceToken || !sourceUrl) return;
|
|
545
545
|
this.#resolvedSourceUrl = sourceUrl;
|
|
546
546
|
const media = this.#root.querySelector("video, audio, hls-video");
|
|
547
|
-
if (media) media
|
|
547
|
+
if (media) this.#activateMedia(media, sourceUrl);
|
|
548
548
|
} catch (cause) {
|
|
549
549
|
const error = cause instanceof Error ? cause : new Error(String(cause));
|
|
550
550
|
this.dispatchEvent(new CustomEvent("av-error", { detail: { error }, bubbles: true, composed: true }));
|
|
551
551
|
}
|
|
552
552
|
}
|
|
553
|
+
#activateMedia(media, sourceUrl) {
|
|
554
|
+
const mode = resolveAudioVisualizerMode(this.player.config.audioArt.visualizer);
|
|
555
|
+
const policy = resolveAudioMediaPolicy(
|
|
556
|
+
sourceUrl,
|
|
557
|
+
this.player.config.crossorigin,
|
|
558
|
+
this.player.crossoriginExplicit,
|
|
559
|
+
media instanceof HTMLAudioElement ? mode : void 0,
|
|
560
|
+
this.#fallbackSourceUrl === sourceUrl
|
|
561
|
+
);
|
|
562
|
+
if (media instanceof HTMLAudioElement && policy.implicitCors) {
|
|
563
|
+
media.addEventListener("error", (event) => {
|
|
564
|
+
if (this.#fallbackSourceUrl === sourceUrl) return;
|
|
565
|
+
event.stopImmediatePropagation();
|
|
566
|
+
this.#fallbackToOrdinaryAudio(media, sourceUrl);
|
|
567
|
+
}, { once: true });
|
|
568
|
+
}
|
|
569
|
+
if (media instanceof HTMLAudioElement && mode && policy.visualize) {
|
|
570
|
+
const connect = () => {
|
|
571
|
+
const art = this.#root.querySelector(".audio-art.visualizer");
|
|
572
|
+
if (art && media.isConnected) this.#visualizer.connect(media, art, mode);
|
|
573
|
+
};
|
|
574
|
+
media.addEventListener("loadedmetadata", connect, { once: true });
|
|
575
|
+
if (media.readyState >= HTMLMediaElement.HAVE_METADATA) queueMicrotask(connect);
|
|
576
|
+
}
|
|
577
|
+
this.player.attachMedia(media);
|
|
578
|
+
applyMediaSource(media, sourceUrl, policy.crossOrigin);
|
|
579
|
+
}
|
|
580
|
+
#fallbackToOrdinaryAudio(failed, sourceUrl) {
|
|
581
|
+
this.#fallbackSourceUrl = sourceUrl;
|
|
582
|
+
this.#visualizer.disconnect();
|
|
583
|
+
const requestedTime = this.player.state.currentTime;
|
|
584
|
+
const shouldPlay = this.player.state.status === "playing" || !failed.paused;
|
|
585
|
+
const replacement = failed.cloneNode(true);
|
|
586
|
+
replacement.removeAttribute("src");
|
|
587
|
+
replacement.removeAttribute("crossorigin");
|
|
588
|
+
replacement.volume = failed.volume;
|
|
589
|
+
replacement.muted = failed.muted;
|
|
590
|
+
replacement.playbackRate = failed.playbackRate;
|
|
591
|
+
const hadFocus = this.#root.activeElement === failed;
|
|
592
|
+
failed.replaceWith(replacement);
|
|
593
|
+
this.player.attachMedia(replacement);
|
|
594
|
+
this.player.seekTo(requestedTime);
|
|
595
|
+
if (hadFocus) replacement.focus();
|
|
596
|
+
this.#root.querySelector(".audio-art")?.classList.remove("visualizer");
|
|
597
|
+
applyMediaSource(replacement, sourceUrl);
|
|
598
|
+
if (shouldPlay) replacement.addEventListener("loadedmetadata", () => void replacement.play().catch(() => void 0), { once: true });
|
|
599
|
+
this.player.dispatchEvent(new CustomEvent("av-visualizerfallback", {
|
|
600
|
+
detail: { canvasId: this.player.canvas?.id ?? "", sourceUrl, reason: "cors" }
|
|
601
|
+
}));
|
|
602
|
+
}
|
|
603
|
+
#resetSourceLoad() {
|
|
604
|
+
this.#sourceToken += 1;
|
|
605
|
+
this.#resolvedSourceUrl = void 0;
|
|
606
|
+
this.#fallbackSourceUrl = void 0;
|
|
607
|
+
this.#visualizer.disconnect();
|
|
608
|
+
}
|
|
553
609
|
#syncTimedContent(time = this.player.state.currentTime, instant = false) {
|
|
554
610
|
syncAudioArtTranscript(this.#root, time, instant);
|
|
555
611
|
const rows = this.#root.querySelectorAll("[data-start][data-end]");
|
|
@@ -570,7 +626,7 @@ var MangoAVMediaElement = class extends HTMLElementBase {
|
|
|
570
626
|
const canvas = this.player.canvas;
|
|
571
627
|
if (!art || !canvas || this.player.source?.kind !== "audio") return;
|
|
572
628
|
const text = art.querySelector(".audio-art-text");
|
|
573
|
-
if (text) text.innerHTML = audioArtTranscriptHtml(canvas.label, this.#transcriptCues, Boolean(this.player.config.audioArt.transcript));
|
|
629
|
+
if (text) text.innerHTML = audioArtTranscriptHtml(canvas.label, this.player.config.audioArt.title ?? "", this.#transcriptCues, Boolean(this.player.config.audioArt.transcript));
|
|
574
630
|
syncAudioArtTranscript(art, this.player.state.currentTime);
|
|
575
631
|
}
|
|
576
632
|
};
|
|
@@ -584,4 +640,4 @@ export {
|
|
|
584
640
|
MangoAVMediaElement,
|
|
585
641
|
defineMangoAVMedia
|
|
586
642
|
};
|
|
587
|
-
//# sourceMappingURL=chunk-
|
|
643
|
+
//# sourceMappingURL=chunk-4V6FME6B.js.map
|