expo-video 2.1.9 → 2.2.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 +12 -0
- package/android/build.gradle +2 -2
- package/android/src/main/java/expo/modules/video/VideoModule.kt +21 -1
- package/android/src/main/java/expo/modules/video/VideoView.kt +7 -4
- package/android/src/main/java/expo/modules/video/player/FirstFrameEventGenerator.kt +3 -2
- package/android/src/main/java/expo/modules/video/player/PlayerEvent.kt +20 -2
- package/android/src/main/java/expo/modules/video/player/VideoPlayer.kt +16 -1
- package/android/src/main/java/expo/modules/video/player/VideoPlayerAudioTracks.kt +125 -0
- package/android/src/main/java/expo/modules/video/records/Tracks.kt +21 -0
- package/android/src/main/java/expo/modules/video/records/VideoEventPayloads.kt +12 -1
- package/build/VideoPlayer.types.d.ts +30 -0
- package/build/VideoPlayer.types.d.ts.map +1 -1
- package/build/VideoPlayer.types.js.map +1 -1
- package/build/VideoPlayer.web.d.ts +3 -1
- package/build/VideoPlayer.web.d.ts.map +1 -1
- package/build/VideoPlayer.web.js +2 -0
- package/build/VideoPlayer.web.js.map +1 -1
- package/build/VideoPlayerEvents.types.d.ts +34 -1
- package/build/VideoPlayerEvents.types.d.ts.map +1 -1
- package/build/VideoPlayerEvents.types.js.map +1 -1
- package/build/VideoView.types.d.ts +1 -1
- package/build/VideoView.types.d.ts.map +1 -1
- package/build/VideoView.types.js.map +1 -1
- package/build/index.d.ts +1 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.js.map +1 -1
- package/expo-module.config.json +7 -1
- package/ios/Records/Tracks.swift +13 -0
- package/ios/Records/VideoEventPayloads.swift +11 -0
- package/ios/VideoModule.swift +11 -0
- package/ios/VideoPlayer.swift +20 -1
- package/ios/VideoPlayerAudioTracks.swift +72 -0
- package/ios/VideoPlayerObserver.swift +15 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0-sources.jar +0 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0-sources.jar.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0-sources.jar.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0-sources.jar.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0-sources.jar.sha512 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0.aar +0 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0.aar.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0.aar.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0.aar.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0.aar.sha512 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0.module +147 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0.module.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0.module.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0.module.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0.module.sha512 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0.pom +88 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0.pom.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0.pom.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0.pom.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0.pom.sha512 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/maven-metadata.xml +13 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/maven-metadata.xml.md5 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/maven-metadata.xml.sha1 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/maven-metadata.xml.sha256 +1 -0
- package/local-maven-repo/host/exp/exponent/expo.modules.video/maven-metadata.xml.sha512 +1 -0
- package/package.json +2 -2
- package/src/VideoPlayer.types.ts +35 -0
- package/src/VideoPlayer.web.tsx +3 -0
- package/src/VideoPlayerEvents.types.ts +40 -0
- package/src/VideoView.types.ts +2 -1
- package/src/index.ts +1 -0
package/build/VideoPlayer.web.js
CHANGED
|
@@ -53,6 +53,8 @@ export default class VideoPlayerWeb extends globalThis.expo.SharedObject {
|
|
|
53
53
|
bufferOptions = {}; // Not supported on web. Dummy to match the interface.
|
|
54
54
|
subtitleTrack = null; // Embedded subtitles are not supported by the html web player. Dummy to match the interface.
|
|
55
55
|
availableSubtitleTracks = []; // Embedded subtitles are not supported by the html web player. Dummy to match the interface.
|
|
56
|
+
audioTrack = null; // Not supported on web. Dummy to match the interface.
|
|
57
|
+
availableAudioTracks = []; // Not supported on web. Dummy to match the interface.
|
|
56
58
|
videoTrack = null; // Not supported on web. Dummy to match the interface.
|
|
57
59
|
availableVideoTracks = []; // Not supported on web. Dummy to match the interface.
|
|
58
60
|
set muted(value) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VideoPlayer.web.js","sourceRoot":"","sources":["../src/VideoPlayer.web.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useMemo } from 'react';\n\nimport type {\n BufferOptions,\n PlayerError,\n VideoPlayerStatus,\n VideoSource,\n VideoPlayer,\n SubtitleTrack,\n AudioMixingMode,\n VideoTrack,\n} from './VideoPlayer.types';\nimport type { VideoPlayerEvents } from './VideoPlayerEvents.types';\nimport { VideoThumbnail } from './VideoThumbnail';\nimport resolveAssetSource from './resolveAssetSource';\n\nexport function useVideoPlayer(\n source: VideoSource,\n setup?: (player: VideoPlayer) => void\n): VideoPlayer {\n const parsedSource = typeof source === 'string' ? { uri: source } : source;\n\n return useMemo(() => {\n const player = new VideoPlayerWeb(parsedSource);\n setup?.(player);\n return player;\n }, [JSON.stringify(source)]);\n}\n\nexport function getSourceUri(source: VideoSource): string | null {\n if (typeof source === 'string') {\n return source;\n }\n if (typeof source === 'number') {\n return resolveAssetSource(source)?.uri ?? null;\n }\n if (typeof source?.assetId === 'number' && !source?.uri) {\n return resolveAssetSource(source.assetId)?.uri ?? null;\n }\n\n return source?.uri ?? null;\n}\n\nexport function createVideoPlayer(source: VideoSource): VideoPlayer {\n const parsedSource = typeof source === 'string' ? { uri: source } : source;\n\n return new VideoPlayerWeb(parsedSource);\n}\n\nexport default class VideoPlayerWeb\n extends globalThis.expo.SharedObject<VideoPlayerEvents>\n implements VideoPlayer\n{\n constructor(source: VideoSource) {\n super();\n this.src = source;\n }\n\n src: VideoSource = null;\n previousSrc: VideoSource = null;\n _mountedVideos: Set<HTMLVideoElement> = new Set();\n _audioNodes: Set<MediaElementAudioSourceNode> = new Set();\n playing: boolean = false;\n _muted: boolean = false;\n _volume: number = 1;\n _loop: boolean = false;\n _playbackRate: number = 1.0;\n _preservesPitch: boolean = true;\n _status: VideoPlayerStatus = 'idle';\n _error: PlayerError | null = null;\n _timeUpdateLoop: number | null = null;\n _timeUpdateEventInterval: number = 0;\n audioMixingMode: AudioMixingMode = 'auto'; // Not supported on web. Dummy to match the interface.\n allowsExternalPlayback: boolean = false; // Not supported on web. Dummy to match the interface.\n staysActiveInBackground: boolean = false; // Not supported on web. Dummy to match the interface.\n showNowPlayingNotification: boolean = false; // Not supported on web. Dummy to match the interface.\n currentLiveTimestamp: number | null = null; // Not supported on web. Dummy to match the interface.\n currentOffsetFromLive: number | null = null; // Not supported on web. Dummy to match the interface.\n targetOffsetFromLive: number = 0; // Not supported on web. Dummy to match the interface.\n bufferOptions: BufferOptions = {} as BufferOptions; // Not supported on web. Dummy to match the interface.\n subtitleTrack: SubtitleTrack | null = null; // Embedded subtitles are not supported by the html web player. Dummy to match the interface.\n availableSubtitleTracks: SubtitleTrack[] = []; // Embedded subtitles are not supported by the html web player. Dummy to match the interface.\n videoTrack: VideoTrack | null = null; // Not supported on web. Dummy to match the interface.\n availableVideoTracks: VideoTrack[] = []; // Not supported on web. Dummy to match the interface.\n\n set muted(value: boolean) {\n this._mountedVideos.forEach((video) => {\n video.muted = value;\n });\n this._muted = value;\n }\n\n get muted(): boolean {\n return this._muted;\n }\n\n set playbackRate(value: number) {\n this._mountedVideos.forEach((video) => {\n video.playbackRate = value;\n });\n this._playbackRate = value;\n }\n\n get playbackRate(): number {\n return this._playbackRate;\n }\n\n get isLive(): boolean {\n return [...this._mountedVideos][0]?.duration === Infinity;\n }\n\n set volume(value: number) {\n this._mountedVideos.forEach((video) => {\n video.volume = value;\n });\n this._volume = value;\n }\n\n get volume(): number {\n return this._volume;\n }\n\n set loop(value: boolean) {\n this._mountedVideos.forEach((video) => {\n video.loop = value;\n });\n this._loop = value;\n }\n\n get loop(): boolean {\n return this._loop;\n }\n\n get currentTime(): number {\n // All videos should be synchronized, so we return the position of the first video.\n return [...this._mountedVideos][0]?.currentTime ?? 0;\n }\n\n set currentTime(value: number) {\n this._mountedVideos.forEach((video) => {\n video.currentTime = value;\n });\n }\n\n get duration(): number {\n // All videos should have the same duration, so we return the duration of the first video.\n return [...this._mountedVideos][0]?.duration ?? 0;\n }\n\n get preservesPitch(): boolean {\n return this._preservesPitch;\n }\n\n set preservesPitch(value: boolean) {\n this._mountedVideos.forEach((video) => {\n video.preservesPitch = value;\n });\n this._preservesPitch = value;\n }\n\n get timeUpdateEventInterval(): number {\n return this._timeUpdateEventInterval;\n }\n set timeUpdateEventInterval(value: number) {\n this._timeUpdateEventInterval = value;\n if (this._timeUpdateLoop) {\n clearInterval(this._timeUpdateLoop);\n }\n if (value > 0) {\n // Emit the first event immediately like on other platforms\n this.emit('timeUpdate', {\n currentTime: this.currentTime,\n currentLiveTimestamp: null,\n currentOffsetFromLive: null,\n bufferedPosition: this.bufferedPosition,\n });\n\n this._timeUpdateLoop = setInterval(() => {\n this.emit('timeUpdate', {\n currentTime: this.currentTime,\n currentLiveTimestamp: null,\n currentOffsetFromLive: null,\n bufferedPosition: this.bufferedPosition,\n });\n }, value * 1000);\n }\n }\n\n get status(): VideoPlayerStatus {\n return this._status;\n }\n\n get bufferedPosition(): number {\n if (this._mountedVideos.size === 0 || this.status === 'error') {\n return -1;\n }\n const buffered = [...this._mountedVideos][0]?.buffered;\n for (let i = 0; i < buffered.length; i++) {\n if (buffered.start(i) <= this.currentTime && buffered.end(i) >= this.currentTime) {\n return buffered.end(i);\n }\n }\n return 0;\n }\n\n private set status(value: VideoPlayerStatus) {\n if (this._status === value) return;\n\n if (value === 'error' && this._error) {\n this.emit('statusChange', {\n status: value,\n oldStatus: this._status,\n error: this._error,\n });\n } else {\n this.emit('statusChange', {\n status: value,\n oldStatus: this._status,\n });\n this._error = null;\n }\n this._status = value;\n }\n\n mountVideoView(video: HTMLVideoElement) {\n // The video will be the first video, it should inherit the properties set in the setup() function\n if (this._mountedVideos.size === 0) {\n video.preservesPitch = this._preservesPitch;\n video.loop = this._loop;\n video.volume = this._volume;\n video.muted = this._muted;\n video.playbackRate = this._playbackRate;\n }\n this._mountedVideos.add(video);\n this._addListeners(video);\n this._synchronizeWithFirstVideo(video);\n }\n\n unmountVideoView(video: HTMLVideoElement) {\n this._mountedVideos.delete(video);\n }\n\n mountAudioNode(\n audioContext: AudioContext,\n zeroGainNode: GainNode,\n audioSourceNode: MediaElementAudioSourceNode\n ): void {\n if (!audioContext || !zeroGainNode) return;\n\n this._audioNodes.add(audioSourceNode);\n // First mounted video should be connected to the audio context. All other videos have to be muted.\n if (this._audioNodes.size === 1) {\n audioSourceNode.connect(audioContext.destination);\n } else {\n audioSourceNode.connect(zeroGainNode);\n }\n }\n\n unmountAudioNode(\n video: HTMLVideoElement,\n audioContext: AudioContext,\n audioSourceNode: MediaElementAudioSourceNode\n ) {\n const mountedVideos = [...this._mountedVideos];\n const videoPlayingAudio = mountedVideos[0];\n this._audioNodes.delete(audioSourceNode);\n audioSourceNode.disconnect();\n\n // If video playing audio has been removed, select a new video to be the audio player by disconnecting it from the mute node.\n if (videoPlayingAudio === video && this._audioNodes.size > 0 && audioContext) {\n const newMainAudioSource = [...this._audioNodes][0];\n newMainAudioSource.disconnect();\n newMainAudioSource.connect(audioContext.destination);\n }\n }\n\n play(): void {\n this._mountedVideos.forEach((video) => {\n video.play();\n });\n }\n\n pause(): void {\n this._mountedVideos.forEach((video) => {\n video.pause();\n });\n }\n\n replace(source: VideoSource): void {\n this._mountedVideos.forEach((video) => {\n const uri = getSourceUri(source);\n video.pause();\n if (uri) {\n video.setAttribute('src', uri);\n video.load();\n video.play();\n } else {\n video.removeAttribute('src');\n video.load();\n }\n });\n // TODO @behenate: this won't work when we add support for playlists\n this.previousSrc = this.src;\n this.src = source;\n this.playing = true;\n }\n\n // The HTML5 player already offloads loading of the asset onto a different thread so we can keep the same\n // implementation until `replace` is deprecated and removed.\n async replaceAsync(source: VideoSource): Promise<void> {\n return this.replace(source);\n }\n\n seekBy(seconds: number): void {\n this._mountedVideos.forEach((video) => {\n video.currentTime += seconds;\n });\n }\n\n replay(): void {\n this._mountedVideos.forEach((video) => {\n video.currentTime = 0;\n video.play();\n });\n this.playing = true;\n }\n\n generateThumbnailsAsync(times: number | number[]): Promise<VideoThumbnail[]> {\n throw new Error('Generating video thumbnails is not supported on Web yet');\n }\n\n _synchronizeWithFirstVideo(video: HTMLVideoElement): void {\n const firstVideo = [...this._mountedVideos][0];\n if (!firstVideo) return;\n\n if (firstVideo.paused) {\n video.pause();\n } else {\n video.play();\n }\n video.currentTime = firstVideo.currentTime;\n video.volume = firstVideo.volume;\n video.muted = firstVideo.muted;\n video.playbackRate = firstVideo.playbackRate;\n }\n\n /**\n * If there are multiple mounted videos, all of them will emit an event, as they are synchronised.\n * We want to avoid this, so we only emit the event if it came from the first video.\n */\n _emitOnce<EventName extends keyof VideoPlayerEvents>(\n eventSource: HTMLVideoElement,\n eventName: EventName,\n ...args: Parameters<VideoPlayerEvents[EventName]>\n ): void {\n const mountedVideos = [...this._mountedVideos];\n if (mountedVideos[0] === eventSource) {\n this.emit(eventName, ...args);\n }\n }\n\n _addListeners(video: HTMLVideoElement): void {\n video.onplay = () => {\n this._emitOnce(video, 'playingChange', {\n isPlaying: true,\n oldIsPlaying: this.playing,\n });\n this.playing = true;\n this._mountedVideos.forEach((mountedVideo) => {\n mountedVideo.play();\n });\n };\n\n video.onpause = () => {\n this._emitOnce(video, 'playingChange', {\n isPlaying: false,\n oldIsPlaying: this.playing,\n });\n this.playing = false;\n this._mountedVideos.forEach((mountedVideo) => {\n mountedVideo.pause();\n });\n };\n\n video.onvolumechange = () => {\n this._emitOnce(video, 'volumeChange', { volume: video.volume, oldVolume: this.volume });\n this._emitOnce(video, 'mutedChange', { muted: video.muted, oldMuted: this.muted });\n this.volume = video.volume;\n this.muted = video.muted;\n };\n\n video.onseeking = () => {\n this._mountedVideos.forEach((mountedVideo) => {\n if (mountedVideo === video || mountedVideo.currentTime === video.currentTime) return;\n mountedVideo.currentTime = video.currentTime;\n });\n };\n\n video.onseeked = () => {\n this._mountedVideos.forEach((mountedVideo) => {\n if (mountedVideo === video || mountedVideo.currentTime === video.currentTime) return;\n mountedVideo.currentTime = video.currentTime;\n });\n };\n\n video.onratechange = () => {\n this._emitOnce(video, 'playbackRateChange', {\n playbackRate: video.playbackRate,\n oldPlaybackRate: this.playbackRate,\n });\n this._mountedVideos.forEach((mountedVideo) => {\n if (mountedVideo.playbackRate === video.playbackRate) return;\n this._playbackRate = video.playbackRate;\n mountedVideo.playbackRate = video.playbackRate;\n });\n this._playbackRate = video.playbackRate;\n };\n\n video.onerror = () => {\n this._error = {\n message: video.error?.message ?? 'Unknown player error',\n };\n this.status = 'error';\n };\n\n video.oncanplay = () => {\n const allCanPlay = [...this._mountedVideos].reduce((previousValue, video) => {\n return previousValue && video.readyState >= 3;\n }, true);\n if (!allCanPlay) return;\n\n this.status = 'readyToPlay';\n };\n\n video.onwaiting = () => {\n if (this._status === 'loading') return;\n this.status = 'loading';\n };\n\n video.onended = () => {\n this._emitOnce(video, 'playToEnd');\n };\n\n video.onloadstart = () => {\n this._emitOnce(video, 'sourceChange', { source: this.src, oldSource: this.previousSrc });\n };\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"VideoPlayer.web.js","sourceRoot":"","sources":["../src/VideoPlayer.web.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAehC,OAAO,kBAAkB,MAAM,sBAAsB,CAAC;AAEtD,MAAM,UAAU,cAAc,CAC5B,MAAmB,EACnB,KAAqC;IAErC,MAAM,YAAY,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;IAE3E,OAAO,OAAO,CAAC,GAAG,EAAE;QAClB,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC,YAAY,CAAC,CAAC;QAChD,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC;QAChB,OAAO,MAAM,CAAC;IAChB,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,MAAmB;IAC9C,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAO,kBAAkB,CAAC,MAAM,CAAC,EAAE,GAAG,IAAI,IAAI,CAAC;IACjD,CAAC;IACD,IAAI,OAAO,MAAM,EAAE,OAAO,KAAK,QAAQ,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC;QACxD,OAAO,kBAAkB,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,GAAG,IAAI,IAAI,CAAC;IACzD,CAAC;IAED,OAAO,MAAM,EAAE,GAAG,IAAI,IAAI,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,MAAmB;IACnD,MAAM,YAAY,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;IAE3E,OAAO,IAAI,cAAc,CAAC,YAAY,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,CAAC,OAAO,OAAO,cACnB,SAAQ,UAAU,CAAC,IAAI,CAAC,YAA+B;IAGvD,YAAY,MAAmB;QAC7B,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,GAAG,GAAG,MAAM,CAAC;IACpB,CAAC;IAED,GAAG,GAAgB,IAAI,CAAC;IACxB,WAAW,GAAgB,IAAI,CAAC;IAChC,cAAc,GAA0B,IAAI,GAAG,EAAE,CAAC;IAClD,WAAW,GAAqC,IAAI,GAAG,EAAE,CAAC;IAC1D,OAAO,GAAY,KAAK,CAAC;IACzB,MAAM,GAAY,KAAK,CAAC;IACxB,OAAO,GAAW,CAAC,CAAC;IACpB,KAAK,GAAY,KAAK,CAAC;IACvB,aAAa,GAAW,GAAG,CAAC;IAC5B,eAAe,GAAY,IAAI,CAAC;IAChC,OAAO,GAAsB,MAAM,CAAC;IACpC,MAAM,GAAuB,IAAI,CAAC;IAClC,eAAe,GAAkB,IAAI,CAAC;IACtC,wBAAwB,GAAW,CAAC,CAAC;IACrC,eAAe,GAAoB,MAAM,CAAC,CAAC,sDAAsD;IACjG,sBAAsB,GAAY,KAAK,CAAC,CAAC,sDAAsD;IAC/F,uBAAuB,GAAY,KAAK,CAAC,CAAC,sDAAsD;IAChG,0BAA0B,GAAY,KAAK,CAAC,CAAC,sDAAsD;IACnG,oBAAoB,GAAkB,IAAI,CAAC,CAAC,sDAAsD;IAClG,qBAAqB,GAAkB,IAAI,CAAC,CAAC,sDAAsD;IACnG,oBAAoB,GAAW,CAAC,CAAC,CAAC,sDAAsD;IACxF,aAAa,GAAkB,EAAmB,CAAC,CAAC,sDAAsD;IAC1G,aAAa,GAAyB,IAAI,CAAC,CAAC,6FAA6F;IACzI,uBAAuB,GAAoB,EAAE,CAAC,CAAC,6FAA6F;IAC5I,UAAU,GAAsB,IAAI,CAAC,CAAC,sDAAsD;IAC5F,oBAAoB,GAAiB,EAAE,CAAC,CAAC,sDAAsD;IAC/F,UAAU,GAAsB,IAAI,CAAC,CAAC,sDAAsD;IAC5F,oBAAoB,GAAiB,EAAE,CAAC,CAAC,sDAAsD;IAE/F,IAAI,KAAK,CAAC,KAAc;QACtB,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YACpC,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC;QACtB,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;IACtB,CAAC;IAED,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED,IAAI,YAAY,CAAC,KAAa;QAC5B,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YACpC,KAAK,CAAC,YAAY,GAAG,KAAK,CAAC;QAC7B,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;IAC7B,CAAC;IAED,IAAI,YAAY;QACd,OAAO,IAAI,CAAC,aAAa,CAAC;IAC5B,CAAC;IAED,IAAI,MAAM;QACR,OAAO,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,KAAK,QAAQ,CAAC;IAC5D,CAAC;IAED,IAAI,MAAM,CAAC,KAAa;QACtB,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YACpC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC;QACvB,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;IACvB,CAAC;IAED,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,IAAI,IAAI,CAAC,KAAc;QACrB,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YACpC,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC;QACrB,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED,IAAI,WAAW;QACb,mFAAmF;QACnF,OAAO,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,IAAI,CAAC,CAAC;IACvD,CAAC;IAED,IAAI,WAAW,CAAC,KAAa;QAC3B,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YACpC,KAAK,CAAC,WAAW,GAAG,KAAK,CAAC;QAC5B,CAAC,CAAC,CAAC;IACL,CAAC;IAED,IAAI,QAAQ;QACV,0FAA0F;QAC1F,OAAO,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,IAAI,CAAC,CAAC;IACpD,CAAC;IAED,IAAI,cAAc;QAChB,OAAO,IAAI,CAAC,eAAe,CAAC;IAC9B,CAAC;IAED,IAAI,cAAc,CAAC,KAAc;QAC/B,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YACpC,KAAK,CAAC,cAAc,GAAG,KAAK,CAAC;QAC/B,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;IAC/B,CAAC;IAED,IAAI,uBAAuB;QACzB,OAAO,IAAI,CAAC,wBAAwB,CAAC;IACvC,CAAC;IACD,IAAI,uBAAuB,CAAC,KAAa;QACvC,IAAI,CAAC,wBAAwB,GAAG,KAAK,CAAC;QACtC,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACzB,aAAa,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QACtC,CAAC;QACD,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACd,2DAA2D;YAC3D,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;gBACtB,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,oBAAoB,EAAE,IAAI;gBAC1B,qBAAqB,EAAE,IAAI;gBAC3B,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;aACxC,CAAC,CAAC;YAEH,IAAI,CAAC,eAAe,GAAG,WAAW,CAAC,GAAG,EAAE;gBACtC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;oBACtB,WAAW,EAAE,IAAI,CAAC,WAAW;oBAC7B,oBAAoB,EAAE,IAAI;oBAC1B,qBAAqB,EAAE,IAAI;oBAC3B,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;iBACxC,CAAC,CAAC;YACL,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,CAAC;QACnB,CAAC;IACH,CAAC;IAED,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,IAAI,gBAAgB;QAClB,IAAI,IAAI,CAAC,cAAc,CAAC,IAAI,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;YAC9D,OAAO,CAAC,CAAC,CAAC;QACZ,CAAC;QACD,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC;QACvD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACzC,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,WAAW,IAAI,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjF,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACzB,CAAC;QACH,CAAC;QACD,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAY,MAAM,CAAC,KAAwB;QACzC,IAAI,IAAI,CAAC,OAAO,KAAK,KAAK;YAAE,OAAO;QAEnC,IAAI,KAAK,KAAK,OAAO,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACrC,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE;gBACxB,MAAM,EAAE,KAAK;gBACb,SAAS,EAAE,IAAI,CAAC,OAAO;gBACvB,KAAK,EAAE,IAAI,CAAC,MAAM;aACnB,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE;gBACxB,MAAM,EAAE,KAAK;gBACb,SAAS,EAAE,IAAI,CAAC,OAAO;aACxB,CAAC,CAAC;YACH,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACrB,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;IACvB,CAAC;IAED,cAAc,CAAC,KAAuB;QACpC,kGAAkG;QAClG,IAAI,IAAI,CAAC,cAAc,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YACnC,KAAK,CAAC,cAAc,GAAG,IAAI,CAAC,eAAe,CAAC;YAC5C,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC;YACxB,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC;YAC5B,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC;YAC1B,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC;QAC1C,CAAC;QACD,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC/B,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC1B,IAAI,CAAC,0BAA0B,CAAC,KAAK,CAAC,CAAC;IACzC,CAAC;IAED,gBAAgB,CAAC,KAAuB;QACtC,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;IAED,cAAc,CACZ,YAA0B,EAC1B,YAAsB,EACtB,eAA4C;QAE5C,IAAI,CAAC,YAAY,IAAI,CAAC,YAAY;YAAE,OAAO;QAE3C,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QACtC,mGAAmG;QACnG,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YAChC,eAAe,CAAC,OAAO,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;QACpD,CAAC;aAAM,CAAC;YACN,eAAe,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QACxC,CAAC;IACH,CAAC;IAED,gBAAgB,CACd,KAAuB,EACvB,YAA0B,EAC1B,eAA4C;QAE5C,MAAM,aAAa,GAAG,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC;QAC/C,MAAM,iBAAiB,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;QAC3C,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;QACzC,eAAe,CAAC,UAAU,EAAE,CAAC;QAE7B,6HAA6H;QAC7H,IAAI,iBAAiB,KAAK,KAAK,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,GAAG,CAAC,IAAI,YAAY,EAAE,CAAC;YAC7E,MAAM,kBAAkB,GAAG,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;YACpD,kBAAkB,CAAC,UAAU,EAAE,CAAC;YAChC,kBAAkB,CAAC,OAAO,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;IAED,IAAI;QACF,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YACpC,KAAK,CAAC,IAAI,EAAE,CAAC;QACf,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK;QACH,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YACpC,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,CAAC,CAAC,CAAC;IACL,CAAC;IAED,OAAO,CAAC,MAAmB;QACzB,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YACpC,MAAM,GAAG,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;YACjC,KAAK,CAAC,KAAK,EAAE,CAAC;YACd,IAAI,GAAG,EAAE,CAAC;gBACR,KAAK,CAAC,YAAY,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;gBAC/B,KAAK,CAAC,IAAI,EAAE,CAAC;gBACb,KAAK,CAAC,IAAI,EAAE,CAAC;YACf,CAAC;iBAAM,CAAC;gBACN,KAAK,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;gBAC7B,KAAK,CAAC,IAAI,EAAE,CAAC;YACf,CAAC;QACH,CAAC,CAAC,CAAC;QACH,oEAAoE;QACpE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC;QAC5B,IAAI,CAAC,GAAG,GAAG,MAAM,CAAC;QAClB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;IACtB,CAAC;IAED,yGAAyG;IACzG,4DAA4D;IAC5D,KAAK,CAAC,YAAY,CAAC,MAAmB;QACpC,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9B,CAAC;IAED,MAAM,CAAC,OAAe;QACpB,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YACpC,KAAK,CAAC,WAAW,IAAI,OAAO,CAAC;QAC/B,CAAC,CAAC,CAAC;IACL,CAAC;IAED,MAAM;QACJ,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YACpC,KAAK,CAAC,WAAW,GAAG,CAAC,CAAC;YACtB,KAAK,CAAC,IAAI,EAAE,CAAC;QACf,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;IACtB,CAAC;IAED,uBAAuB,CAAC,KAAwB;QAC9C,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;IAC7E,CAAC;IAED,0BAA0B,CAAC,KAAuB;QAChD,MAAM,UAAU,GAAG,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/C,IAAI,CAAC,UAAU;YAAE,OAAO;QAExB,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;YACtB,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,IAAI,EAAE,CAAC;QACf,CAAC;QACD,KAAK,CAAC,WAAW,GAAG,UAAU,CAAC,WAAW,CAAC;QAC3C,KAAK,CAAC,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC;QACjC,KAAK,CAAC,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC;QAC/B,KAAK,CAAC,YAAY,GAAG,UAAU,CAAC,YAAY,CAAC;IAC/C,CAAC;IAED;;;OAGG;IACH,SAAS,CACP,WAA6B,EAC7B,SAAoB,EACpB,GAAG,IAA8C;QAEjD,MAAM,aAAa,GAAG,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC;QAC/C,IAAI,aAAa,CAAC,CAAC,CAAC,KAAK,WAAW,EAAE,CAAC;YACrC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,IAAI,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IAED,aAAa,CAAC,KAAuB;QACnC,KAAK,CAAC,MAAM,GAAG,GAAG,EAAE;YAClB,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,eAAe,EAAE;gBACrC,SAAS,EAAE,IAAI;gBACf,YAAY,EAAE,IAAI,CAAC,OAAO;aAC3B,CAAC,CAAC;YACH,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YACpB,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,YAAY,EAAE,EAAE;gBAC3C,YAAY,CAAC,IAAI,EAAE,CAAC;YACtB,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;QAEF,KAAK,CAAC,OAAO,GAAG,GAAG,EAAE;YACnB,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,eAAe,EAAE;gBACrC,SAAS,EAAE,KAAK;gBAChB,YAAY,EAAE,IAAI,CAAC,OAAO;aAC3B,CAAC,CAAC;YACH,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;YACrB,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,YAAY,EAAE,EAAE;gBAC3C,YAAY,CAAC,KAAK,EAAE,CAAC;YACvB,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;QAEF,KAAK,CAAC,cAAc,GAAG,GAAG,EAAE;YAC1B,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,cAAc,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YACxF,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,aAAa,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;YACnF,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;YAC3B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;QAC3B,CAAC,CAAC;QAEF,KAAK,CAAC,SAAS,GAAG,GAAG,EAAE;YACrB,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,YAAY,EAAE,EAAE;gBAC3C,IAAI,YAAY,KAAK,KAAK,IAAI,YAAY,CAAC,WAAW,KAAK,KAAK,CAAC,WAAW;oBAAE,OAAO;gBACrF,YAAY,CAAC,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC;YAC/C,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;QAEF,KAAK,CAAC,QAAQ,GAAG,GAAG,EAAE;YACpB,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,YAAY,EAAE,EAAE;gBAC3C,IAAI,YAAY,KAAK,KAAK,IAAI,YAAY,CAAC,WAAW,KAAK,KAAK,CAAC,WAAW;oBAAE,OAAO;gBACrF,YAAY,CAAC,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC;YAC/C,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;QAEF,KAAK,CAAC,YAAY,GAAG,GAAG,EAAE;YACxB,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,oBAAoB,EAAE;gBAC1C,YAAY,EAAE,KAAK,CAAC,YAAY;gBAChC,eAAe,EAAE,IAAI,CAAC,YAAY;aACnC,CAAC,CAAC;YACH,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,YAAY,EAAE,EAAE;gBAC3C,IAAI,YAAY,CAAC,YAAY,KAAK,KAAK,CAAC,YAAY;oBAAE,OAAO;gBAC7D,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC,YAAY,CAAC;gBACxC,YAAY,CAAC,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC;YACjD,CAAC,CAAC,CAAC;YACH,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC,YAAY,CAAC;QAC1C,CAAC,CAAC;QAEF,KAAK,CAAC,OAAO,GAAG,GAAG,EAAE;YACnB,IAAI,CAAC,MAAM,GAAG;gBACZ,OAAO,EAAE,KAAK,CAAC,KAAK,EAAE,OAAO,IAAI,sBAAsB;aACxD,CAAC;YACF,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC;QACxB,CAAC,CAAC;QAEF,KAAK,CAAC,SAAS,GAAG,GAAG,EAAE;YACrB,MAAM,UAAU,GAAG,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,EAAE,KAAK,EAAE,EAAE;gBAC1E,OAAO,aAAa,IAAI,KAAK,CAAC,UAAU,IAAI,CAAC,CAAC;YAChD,CAAC,EAAE,IAAI,CAAC,CAAC;YACT,IAAI,CAAC,UAAU;gBAAE,OAAO;YAExB,IAAI,CAAC,MAAM,GAAG,aAAa,CAAC;QAC9B,CAAC,CAAC;QAEF,KAAK,CAAC,SAAS,GAAG,GAAG,EAAE;YACrB,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS;gBAAE,OAAO;YACvC,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;QAC1B,CAAC,CAAC;QAEF,KAAK,CAAC,OAAO,GAAG,GAAG,EAAE;YACnB,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;QACrC,CAAC,CAAC;QAEF,KAAK,CAAC,WAAW,GAAG,GAAG,EAAE;YACvB,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,cAAc,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;QAC3F,CAAC,CAAC;IACJ,CAAC;CACF","sourcesContent":["import { useMemo } from 'react';\n\nimport type {\n BufferOptions,\n PlayerError,\n VideoPlayerStatus,\n VideoSource,\n VideoPlayer,\n SubtitleTrack,\n AudioMixingMode,\n VideoTrack,\n AudioTrack,\n} from './VideoPlayer.types';\nimport type { VideoPlayerEvents } from './VideoPlayerEvents.types';\nimport { VideoThumbnail } from './VideoThumbnail';\nimport resolveAssetSource from './resolveAssetSource';\n\nexport function useVideoPlayer(\n source: VideoSource,\n setup?: (player: VideoPlayer) => void\n): VideoPlayer {\n const parsedSource = typeof source === 'string' ? { uri: source } : source;\n\n return useMemo(() => {\n const player = new VideoPlayerWeb(parsedSource);\n setup?.(player);\n return player;\n }, [JSON.stringify(source)]);\n}\n\nexport function getSourceUri(source: VideoSource): string | null {\n if (typeof source === 'string') {\n return source;\n }\n if (typeof source === 'number') {\n return resolveAssetSource(source)?.uri ?? null;\n }\n if (typeof source?.assetId === 'number' && !source?.uri) {\n return resolveAssetSource(source.assetId)?.uri ?? null;\n }\n\n return source?.uri ?? null;\n}\n\nexport function createVideoPlayer(source: VideoSource): VideoPlayer {\n const parsedSource = typeof source === 'string' ? { uri: source } : source;\n\n return new VideoPlayerWeb(parsedSource);\n}\n\nexport default class VideoPlayerWeb\n extends globalThis.expo.SharedObject<VideoPlayerEvents>\n implements VideoPlayer\n{\n constructor(source: VideoSource) {\n super();\n this.src = source;\n }\n\n src: VideoSource = null;\n previousSrc: VideoSource = null;\n _mountedVideos: Set<HTMLVideoElement> = new Set();\n _audioNodes: Set<MediaElementAudioSourceNode> = new Set();\n playing: boolean = false;\n _muted: boolean = false;\n _volume: number = 1;\n _loop: boolean = false;\n _playbackRate: number = 1.0;\n _preservesPitch: boolean = true;\n _status: VideoPlayerStatus = 'idle';\n _error: PlayerError | null = null;\n _timeUpdateLoop: number | null = null;\n _timeUpdateEventInterval: number = 0;\n audioMixingMode: AudioMixingMode = 'auto'; // Not supported on web. Dummy to match the interface.\n allowsExternalPlayback: boolean = false; // Not supported on web. Dummy to match the interface.\n staysActiveInBackground: boolean = false; // Not supported on web. Dummy to match the interface.\n showNowPlayingNotification: boolean = false; // Not supported on web. Dummy to match the interface.\n currentLiveTimestamp: number | null = null; // Not supported on web. Dummy to match the interface.\n currentOffsetFromLive: number | null = null; // Not supported on web. Dummy to match the interface.\n targetOffsetFromLive: number = 0; // Not supported on web. Dummy to match the interface.\n bufferOptions: BufferOptions = {} as BufferOptions; // Not supported on web. Dummy to match the interface.\n subtitleTrack: SubtitleTrack | null = null; // Embedded subtitles are not supported by the html web player. Dummy to match the interface.\n availableSubtitleTracks: SubtitleTrack[] = []; // Embedded subtitles are not supported by the html web player. Dummy to match the interface.\n audioTrack: AudioTrack | null = null; // Not supported on web. Dummy to match the interface.\n availableAudioTracks: AudioTrack[] = []; // Not supported on web. Dummy to match the interface.\n videoTrack: VideoTrack | null = null; // Not supported on web. Dummy to match the interface.\n availableVideoTracks: VideoTrack[] = []; // Not supported on web. Dummy to match the interface.\n\n set muted(value: boolean) {\n this._mountedVideos.forEach((video) => {\n video.muted = value;\n });\n this._muted = value;\n }\n\n get muted(): boolean {\n return this._muted;\n }\n\n set playbackRate(value: number) {\n this._mountedVideos.forEach((video) => {\n video.playbackRate = value;\n });\n this._playbackRate = value;\n }\n\n get playbackRate(): number {\n return this._playbackRate;\n }\n\n get isLive(): boolean {\n return [...this._mountedVideos][0]?.duration === Infinity;\n }\n\n set volume(value: number) {\n this._mountedVideos.forEach((video) => {\n video.volume = value;\n });\n this._volume = value;\n }\n\n get volume(): number {\n return this._volume;\n }\n\n set loop(value: boolean) {\n this._mountedVideos.forEach((video) => {\n video.loop = value;\n });\n this._loop = value;\n }\n\n get loop(): boolean {\n return this._loop;\n }\n\n get currentTime(): number {\n // All videos should be synchronized, so we return the position of the first video.\n return [...this._mountedVideos][0]?.currentTime ?? 0;\n }\n\n set currentTime(value: number) {\n this._mountedVideos.forEach((video) => {\n video.currentTime = value;\n });\n }\n\n get duration(): number {\n // All videos should have the same duration, so we return the duration of the first video.\n return [...this._mountedVideos][0]?.duration ?? 0;\n }\n\n get preservesPitch(): boolean {\n return this._preservesPitch;\n }\n\n set preservesPitch(value: boolean) {\n this._mountedVideos.forEach((video) => {\n video.preservesPitch = value;\n });\n this._preservesPitch = value;\n }\n\n get timeUpdateEventInterval(): number {\n return this._timeUpdateEventInterval;\n }\n set timeUpdateEventInterval(value: number) {\n this._timeUpdateEventInterval = value;\n if (this._timeUpdateLoop) {\n clearInterval(this._timeUpdateLoop);\n }\n if (value > 0) {\n // Emit the first event immediately like on other platforms\n this.emit('timeUpdate', {\n currentTime: this.currentTime,\n currentLiveTimestamp: null,\n currentOffsetFromLive: null,\n bufferedPosition: this.bufferedPosition,\n });\n\n this._timeUpdateLoop = setInterval(() => {\n this.emit('timeUpdate', {\n currentTime: this.currentTime,\n currentLiveTimestamp: null,\n currentOffsetFromLive: null,\n bufferedPosition: this.bufferedPosition,\n });\n }, value * 1000);\n }\n }\n\n get status(): VideoPlayerStatus {\n return this._status;\n }\n\n get bufferedPosition(): number {\n if (this._mountedVideos.size === 0 || this.status === 'error') {\n return -1;\n }\n const buffered = [...this._mountedVideos][0]?.buffered;\n for (let i = 0; i < buffered.length; i++) {\n if (buffered.start(i) <= this.currentTime && buffered.end(i) >= this.currentTime) {\n return buffered.end(i);\n }\n }\n return 0;\n }\n\n private set status(value: VideoPlayerStatus) {\n if (this._status === value) return;\n\n if (value === 'error' && this._error) {\n this.emit('statusChange', {\n status: value,\n oldStatus: this._status,\n error: this._error,\n });\n } else {\n this.emit('statusChange', {\n status: value,\n oldStatus: this._status,\n });\n this._error = null;\n }\n this._status = value;\n }\n\n mountVideoView(video: HTMLVideoElement) {\n // The video will be the first video, it should inherit the properties set in the setup() function\n if (this._mountedVideos.size === 0) {\n video.preservesPitch = this._preservesPitch;\n video.loop = this._loop;\n video.volume = this._volume;\n video.muted = this._muted;\n video.playbackRate = this._playbackRate;\n }\n this._mountedVideos.add(video);\n this._addListeners(video);\n this._synchronizeWithFirstVideo(video);\n }\n\n unmountVideoView(video: HTMLVideoElement) {\n this._mountedVideos.delete(video);\n }\n\n mountAudioNode(\n audioContext: AudioContext,\n zeroGainNode: GainNode,\n audioSourceNode: MediaElementAudioSourceNode\n ): void {\n if (!audioContext || !zeroGainNode) return;\n\n this._audioNodes.add(audioSourceNode);\n // First mounted video should be connected to the audio context. All other videos have to be muted.\n if (this._audioNodes.size === 1) {\n audioSourceNode.connect(audioContext.destination);\n } else {\n audioSourceNode.connect(zeroGainNode);\n }\n }\n\n unmountAudioNode(\n video: HTMLVideoElement,\n audioContext: AudioContext,\n audioSourceNode: MediaElementAudioSourceNode\n ) {\n const mountedVideos = [...this._mountedVideos];\n const videoPlayingAudio = mountedVideos[0];\n this._audioNodes.delete(audioSourceNode);\n audioSourceNode.disconnect();\n\n // If video playing audio has been removed, select a new video to be the audio player by disconnecting it from the mute node.\n if (videoPlayingAudio === video && this._audioNodes.size > 0 && audioContext) {\n const newMainAudioSource = [...this._audioNodes][0];\n newMainAudioSource.disconnect();\n newMainAudioSource.connect(audioContext.destination);\n }\n }\n\n play(): void {\n this._mountedVideos.forEach((video) => {\n video.play();\n });\n }\n\n pause(): void {\n this._mountedVideos.forEach((video) => {\n video.pause();\n });\n }\n\n replace(source: VideoSource): void {\n this._mountedVideos.forEach((video) => {\n const uri = getSourceUri(source);\n video.pause();\n if (uri) {\n video.setAttribute('src', uri);\n video.load();\n video.play();\n } else {\n video.removeAttribute('src');\n video.load();\n }\n });\n // TODO @behenate: this won't work when we add support for playlists\n this.previousSrc = this.src;\n this.src = source;\n this.playing = true;\n }\n\n // The HTML5 player already offloads loading of the asset onto a different thread so we can keep the same\n // implementation until `replace` is deprecated and removed.\n async replaceAsync(source: VideoSource): Promise<void> {\n return this.replace(source);\n }\n\n seekBy(seconds: number): void {\n this._mountedVideos.forEach((video) => {\n video.currentTime += seconds;\n });\n }\n\n replay(): void {\n this._mountedVideos.forEach((video) => {\n video.currentTime = 0;\n video.play();\n });\n this.playing = true;\n }\n\n generateThumbnailsAsync(times: number | number[]): Promise<VideoThumbnail[]> {\n throw new Error('Generating video thumbnails is not supported on Web yet');\n }\n\n _synchronizeWithFirstVideo(video: HTMLVideoElement): void {\n const firstVideo = [...this._mountedVideos][0];\n if (!firstVideo) return;\n\n if (firstVideo.paused) {\n video.pause();\n } else {\n video.play();\n }\n video.currentTime = firstVideo.currentTime;\n video.volume = firstVideo.volume;\n video.muted = firstVideo.muted;\n video.playbackRate = firstVideo.playbackRate;\n }\n\n /**\n * If there are multiple mounted videos, all of them will emit an event, as they are synchronised.\n * We want to avoid this, so we only emit the event if it came from the first video.\n */\n _emitOnce<EventName extends keyof VideoPlayerEvents>(\n eventSource: HTMLVideoElement,\n eventName: EventName,\n ...args: Parameters<VideoPlayerEvents[EventName]>\n ): void {\n const mountedVideos = [...this._mountedVideos];\n if (mountedVideos[0] === eventSource) {\n this.emit(eventName, ...args);\n }\n }\n\n _addListeners(video: HTMLVideoElement): void {\n video.onplay = () => {\n this._emitOnce(video, 'playingChange', {\n isPlaying: true,\n oldIsPlaying: this.playing,\n });\n this.playing = true;\n this._mountedVideos.forEach((mountedVideo) => {\n mountedVideo.play();\n });\n };\n\n video.onpause = () => {\n this._emitOnce(video, 'playingChange', {\n isPlaying: false,\n oldIsPlaying: this.playing,\n });\n this.playing = false;\n this._mountedVideos.forEach((mountedVideo) => {\n mountedVideo.pause();\n });\n };\n\n video.onvolumechange = () => {\n this._emitOnce(video, 'volumeChange', { volume: video.volume, oldVolume: this.volume });\n this._emitOnce(video, 'mutedChange', { muted: video.muted, oldMuted: this.muted });\n this.volume = video.volume;\n this.muted = video.muted;\n };\n\n video.onseeking = () => {\n this._mountedVideos.forEach((mountedVideo) => {\n if (mountedVideo === video || mountedVideo.currentTime === video.currentTime) return;\n mountedVideo.currentTime = video.currentTime;\n });\n };\n\n video.onseeked = () => {\n this._mountedVideos.forEach((mountedVideo) => {\n if (mountedVideo === video || mountedVideo.currentTime === video.currentTime) return;\n mountedVideo.currentTime = video.currentTime;\n });\n };\n\n video.onratechange = () => {\n this._emitOnce(video, 'playbackRateChange', {\n playbackRate: video.playbackRate,\n oldPlaybackRate: this.playbackRate,\n });\n this._mountedVideos.forEach((mountedVideo) => {\n if (mountedVideo.playbackRate === video.playbackRate) return;\n this._playbackRate = video.playbackRate;\n mountedVideo.playbackRate = video.playbackRate;\n });\n this._playbackRate = video.playbackRate;\n };\n\n video.onerror = () => {\n this._error = {\n message: video.error?.message ?? 'Unknown player error',\n };\n this.status = 'error';\n };\n\n video.oncanplay = () => {\n const allCanPlay = [...this._mountedVideos].reduce((previousValue, video) => {\n return previousValue && video.readyState >= 3;\n }, true);\n if (!allCanPlay) return;\n\n this.status = 'readyToPlay';\n };\n\n video.onwaiting = () => {\n if (this._status === 'loading') return;\n this.status = 'loading';\n };\n\n video.onended = () => {\n this._emitOnce(video, 'playToEnd');\n };\n\n video.onloadstart = () => {\n this._emitOnce(video, 'sourceChange', { source: this.src, oldSource: this.previousSrc });\n };\n }\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PlayerError, SubtitleTrack, VideoPlayerStatus, VideoSource, VideoTrack } from './VideoPlayer.types';
|
|
1
|
+
import { PlayerError, SubtitleTrack, VideoPlayerStatus, VideoSource, VideoTrack, AudioTrack } from './VideoPlayer.types';
|
|
2
2
|
/**
|
|
3
3
|
* Handlers for events which can be emitted by the player.
|
|
4
4
|
*/
|
|
@@ -43,6 +43,14 @@ export type VideoPlayerEvents = {
|
|
|
43
43
|
* Handler for an event emitted when the current subtitle track changes.
|
|
44
44
|
*/
|
|
45
45
|
subtitleTrackChange(payload: SubtitleTrackChangeEventPayload): void;
|
|
46
|
+
/**
|
|
47
|
+
* Handler for an event emitted when the available audio tracks change.
|
|
48
|
+
*/
|
|
49
|
+
availableAudioTracksChange(payload: AvailableAudioTracksChangeEventPayload): void;
|
|
50
|
+
/**
|
|
51
|
+
* Handler for an event emitted when the current audio track changes.
|
|
52
|
+
*/
|
|
53
|
+
audioTrackChange(payload: AudioTrackChangeEventPayload): void;
|
|
46
54
|
/**
|
|
47
55
|
* Handler for an event emitted when the current video track changes.
|
|
48
56
|
*/
|
|
@@ -225,5 +233,30 @@ export type SourceLoadEventPayload = {
|
|
|
225
233
|
* Subtitle tracks available for the loaded video source.
|
|
226
234
|
*/
|
|
227
235
|
availableSubtitleTracks: SubtitleTrack[];
|
|
236
|
+
/**
|
|
237
|
+
* Audio tracks available for the loaded video source.
|
|
238
|
+
*/
|
|
239
|
+
availableAudioTracks: AudioTrack[];
|
|
240
|
+
};
|
|
241
|
+
type AudioTrackChangeEventPayload = {
|
|
242
|
+
/**
|
|
243
|
+
* New audio track of the player.
|
|
244
|
+
*/
|
|
245
|
+
audioTrack: AudioTrack | null;
|
|
246
|
+
/**
|
|
247
|
+
* Previous audio track of the player.
|
|
248
|
+
*/
|
|
249
|
+
oldAudioTrack?: AudioTrack | null;
|
|
250
|
+
};
|
|
251
|
+
type AvailableAudioTracksChangeEventPayload = {
|
|
252
|
+
/**
|
|
253
|
+
* Array of available audio tracks.
|
|
254
|
+
*/
|
|
255
|
+
availableAudioTracks: AudioTrack[];
|
|
256
|
+
/**
|
|
257
|
+
* Previous array of available audio tracks.
|
|
258
|
+
*/
|
|
259
|
+
oldAvailableAudioTracks?: AudioTrack[];
|
|
228
260
|
};
|
|
261
|
+
export {};
|
|
229
262
|
//# sourceMappingURL=VideoPlayerEvents.types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VideoPlayerEvents.types.d.ts","sourceRoot":"","sources":["../src/VideoPlayerEvents.types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"VideoPlayerEvents.types.d.ts","sourceRoot":"","sources":["../src/VideoPlayerEvents.types.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,aAAa,EACb,iBAAiB,EACjB,WAAW,EACX,UAAU,EACV,UAAU,EACX,MAAM,qBAAqB,CAAC;AAE7B;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B;;OAEG;IACH,YAAY,CAAC,OAAO,EAAE,wBAAwB,GAAG,IAAI,CAAC;IAEtD;;OAEG;IACH,aAAa,CAAC,OAAO,EAAE,yBAAyB,GAAG,IAAI,CAAC;IAExD;;OAEG;IACH,kBAAkB,CAAC,OAAO,EAAE,8BAA8B,GAAG,IAAI,CAAC;IAElE;;OAEG;IACH,YAAY,CAAC,OAAO,EAAE,wBAAwB,GAAG,IAAI,CAAC;IAEtD;;OAEG;IACH,WAAW,CAAC,OAAO,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAEpD;;OAEG;IACH,SAAS,IAAI,IAAI,CAAC;IAElB;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,sBAAsB,GAAG,IAAI,CAAC;IAElD;;OAEG;IACH,YAAY,CAAC,OAAO,EAAE,wBAAwB,GAAG,IAAI,CAAC;IAEtD;;OAEG;IACH,6BAA6B,CAAC,OAAO,EAAE,yCAAyC,GAAG,IAAI,CAAC;IAExF;;OAEG;IACH,mBAAmB,CAAC,OAAO,EAAE,+BAA+B,GAAG,IAAI,CAAC;IAEpE;;OAEG;IACH,0BAA0B,CAAC,OAAO,EAAE,sCAAsC,GAAG,IAAI,CAAC;IAElF;;OAEG;IACH,gBAAgB,CAAC,OAAO,EAAE,4BAA4B,GAAG,IAAI,CAAC;IAE9D;;OAEG;IACH,gBAAgB,CAAC,OAAO,EAAE,4BAA4B,GAAG,IAAI,CAAC;IAE9D;;;OAGG;IACH,UAAU,CAAC,OAAO,EAAE,sBAAsB,GAAG,IAAI,CAAC;CACnD,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,wBAAwB,GAAG;IACrC;;OAEG;IACH,MAAM,EAAE,iBAAiB,CAAC;IAE1B;;OAEG;IACH,SAAS,CAAC,EAAE,iBAAiB,CAAC;IAE9B;;OAEG;IACH,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,yBAAyB,GAAG;IACtC;;OAEG;IACH,SAAS,EAAE,OAAO,CAAC;IAEnB;;OAEG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,8BAA8B,GAAG;IAC3C;;OAEG;IACH,YAAY,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,wBAAwB,GAAG;IACrC;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,uBAAuB,GAAG;IACpC;;OAEG;IACH,KAAK,EAAE,OAAO,CAAC;IAEf;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,wBAAwB,GAAG;IACrC;;OAEG;IACH,MAAM,EAAE,WAAW,CAAC;IAEpB;;OAEG;IACH,SAAS,CAAC,EAAE,WAAW,CAAC;CACzB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;;;;;OAMG;IACH,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IAEpC;;;;;OAKG;IACH,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;IAErC;;;;;OAKG;IACH,gBAAgB,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,+BAA+B,GAAG;IAC5C;;OAEG;IACH,aAAa,EAAE,aAAa,GAAG,IAAI,CAAC;IAEpC;;OAEG;IACH,gBAAgB,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;CACzC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,4BAA4B,GAAG;IACzC;;OAEG;IACH,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IAE9B;;OAEG;IACH,aAAa,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;CACnC,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,yCAAyC,GAAG;IACtD;;OAEG;IACH,uBAAuB,EAAE,aAAa,EAAE,CAAC;IAEzC;;OAEG;IACH,0BAA0B,CAAC,EAAE,aAAa,EAAE,CAAC;CAC9C,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC;;OAEG;IACH,WAAW,EAAE,WAAW,GAAG,IAAI,CAAC;IAEhC;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;;;OAIG;IACH,oBAAoB,EAAE,UAAU,EAAE,CAAC;IAEnC;;OAEG;IACH,uBAAuB,EAAE,aAAa,EAAE,CAAC;IAEzC;;OAEG;IACH,oBAAoB,EAAE,UAAU,EAAE,CAAC;CACpC,CAAC;AAEF,KAAK,4BAA4B,GAAG;IAClC;;OAEG;IACH,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IAE9B;;OAEG;IACH,aAAa,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;CACnC,CAAC;AAEF,KAAK,sCAAsC,GAAG;IAC5C;;OAEG;IACH,oBAAoB,EAAE,UAAU,EAAE,CAAC;IAEnC;;OAEG;IACH,uBAAuB,CAAC,EAAE,UAAU,EAAE,CAAC;CACxC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VideoPlayerEvents.types.js","sourceRoot":"","sources":["../src/VideoPlayerEvents.types.ts"],"names":[],"mappings":"","sourcesContent":["import {\n PlayerError,\n SubtitleTrack,\n VideoPlayerStatus,\n VideoSource,\n VideoTrack,\n} from './VideoPlayer.types';\n\n/**\n * Handlers for events which can be emitted by the player.\n */\nexport type VideoPlayerEvents = {\n /**\n * Handler for an event emitted when the status of the player changes.\n */\n statusChange(payload: StatusChangeEventPayload): void;\n\n /**\n * Handler for an event emitted when the player starts or stops playback.\n */\n playingChange(payload: PlayingChangeEventPayload): void;\n\n /**\n * Handler for an event emitted when the `playbackRate` property of the player changes.\n */\n playbackRateChange(payload: PlaybackRateChangeEventPayload): void;\n\n /**\n * Handler for an event emitted when the `volume` of `muted` property of the player changes.\n */\n volumeChange(payload: VolumeChangeEventPayload): void;\n\n /**\n * Handler for an event emitted when the `muted` property of the player changes\n */\n mutedChange(payload: MutedChangeEventPayload): void;\n\n /**\n * Handler for an event emitted when the player plays to the end of the current source.\n */\n playToEnd(): void;\n\n /**\n * Handler for an event emitted in a given interval specified by the `timeUpdateEventInterval`.\n */\n timeUpdate(payload: TimeUpdateEventPayload): void;\n\n /**\n * Handler for an event emitted when the current media source of the player changes.\n */\n sourceChange(payload: SourceChangeEventPayload): void;\n\n /**\n * Handler for an event emitted when the available subtitle tracks change.\n */\n availableSubtitleTracksChange(payload: AvailableSubtitleTracksChangeEventPayload): void;\n\n /**\n * Handler for an event emitted when the current subtitle track changes.\n */\n subtitleTrackChange(payload: SubtitleTrackChangeEventPayload): void;\n\n /**\n * Handler for an event emitted when the current video track changes.\n */\n videoTrackChange(payload: VideoTrackChangeEventPayload): void;\n\n /**\n * Handler for an event emitted when the player has finished loading metadata for the current video source.\n * This event is emitted when the player has finished metadata for a [`VideoSource`](#videosource), but it doesn't mean that there is enough data buffered to start the playback.\n */\n sourceLoad(payload: SourceLoadEventPayload): void;\n};\n\n/**\n * Data delivered with the [`statusChange`](#videoplayerevents) event.\n */\nexport type StatusChangeEventPayload = {\n /**\n * New status of the player.\n */\n status: VideoPlayerStatus;\n\n /**\n * Previous status of the player.\n */\n oldStatus?: VideoPlayerStatus;\n\n /**\n * Error object containing information about the error that occurred.\n */\n error?: PlayerError;\n};\n\n/**\n * Data delivered with the [`playingChange`](#videoplayerevents) event.\n */\nexport type PlayingChangeEventPayload = {\n /**\n * Boolean value whether the player is currently playing.\n */\n isPlaying: boolean;\n\n /**\n * Previous value of the `isPlaying` property.\n */\n oldIsPlaying?: boolean;\n};\n\n/**\n * Data delivered with the [`playbackRateChange`](#videoplayerevents) event.\n */\nexport type PlaybackRateChangeEventPayload = {\n /**\n * Float value indicating the current playback speed of the player.\n */\n playbackRate: number;\n\n /**\n * Previous value of the `playbackRate` property.\n */\n oldPlaybackRate?: number;\n};\n\n/**\n * Data delivered with the [`volumeChange`](#videoplayerevents) event.\n */\nexport type VolumeChangeEventPayload = {\n /**\n * Float value indicating the current volume of the player.\n */\n volume: number;\n\n /**\n * Previous value of the `volume` property.\n */\n oldVolume?: number;\n};\n\n/**\n * Data delivered with the [`mutedChange`](#videoplayerevents) event.\n */\nexport type MutedChangeEventPayload = {\n /**\n * Boolean value whether the player is currently muted.\n */\n muted: boolean;\n\n /**\n * Previous value of the `isMuted` property.\n */\n oldMuted?: boolean;\n};\n\n/**\n * Data delivered with the [`sourceChange`](#videoplayerevents) event.\n */\nexport type SourceChangeEventPayload = {\n /**\n * New source of the player.\n */\n source: VideoSource;\n\n /**\n * Previous source of the player.\n */\n oldSource?: VideoSource;\n};\n\n/**\n * Data delivered with the [`timeUpdate`](#videoplayerevents) event, contains information about the current playback progress.\n */\nexport type TimeUpdateEventPayload = {\n /**\n * Float value indicating the current playback time in seconds. Same as the [`currentTime`](#currenttime) property.\n */\n currentTime: number;\n\n /**\n * The exact timestamp when the currently displayed video frame was sent from the server,\n * based on the `EXT-X-PROGRAM-DATE-TIME` tag in the livestream metadata.\n * Same as the [`currentLiveTimestamp`](#currentlivetimestamp) property.\n * @platform android\n * @platform ios\n */\n currentLiveTimestamp: number | null;\n\n /**\n * Float value indicating the latency of the live stream in seconds.\n * Same as the [`currentOffsetFromLive`](#currentoffsetfromlive) property.\n * @platform android\n * @platform ios\n */\n currentOffsetFromLive: number | null;\n\n /**\n * Float value indicating how far the player has buffered the video in seconds.\n * Same as the [`bufferedPosition`](#bufferedPosition) property.\n * @platform android\n * @platform ios\n */\n bufferedPosition: number;\n};\n\nexport type SubtitleTrackChangeEventPayload = {\n /**\n * New subtitle track of the player.\n */\n subtitleTrack: SubtitleTrack | null;\n\n /**\n * Previous subtitle track of the player.\n */\n oldSubtitleTrack?: SubtitleTrack | null;\n};\n\n/**\n * Data delivered with the [`videoTrackChange`](#videoplayerevents) event, contains information about the video track which is currently being played.\n */\nexport type VideoTrackChangeEventPayload = {\n /**\n * New video track of the player.\n */\n videoTrack: VideoTrack | null;\n\n /**\n * Previous video track of the player.\n */\n oldVideoTrack?: VideoTrack | null;\n};\n\n/**\n * TODO @behenate: For SDK53 mark as deprecated in favor of SourceLoadEventPayload\n * @hidden\n */\nexport type AvailableSubtitleTracksChangeEventPayload = {\n /**\n * Array of available subtitle tracks.\n */\n availableSubtitleTracks: SubtitleTrack[];\n\n /**\n * Previous array of available subtitle tracks.\n */\n oldAvailableSubtitleTracks?: SubtitleTrack[];\n};\n\n/**\n * Data delivered with the [`sourceLoad`](#videoplayerevents) event, contains information about the video source that has finished loading.\n */\nexport type SourceLoadEventPayload = {\n /**\n * The video source that has been loaded.\n */\n videoSource: VideoSource | null;\n\n /**\n * Duration of the video source in seconds.\n */\n duration: number;\n\n /**\n * Video tracks available for the loaded video source.\n *\n * > On iOS, when using a HLS source, make sure that the uri contains `.m3u8` extension or that the [`contentType`](#contenttype) property of the [`VideoSource`](#videosource) has been set to `'hls'`. Otherwise, the video tracks will not be available.\n */\n availableVideoTracks: VideoTrack[];\n\n /**\n * Subtitle tracks available for the loaded video source.\n */\n availableSubtitleTracks: SubtitleTrack[];\n};\n"]}
|
|
1
|
+
{"version":3,"file":"VideoPlayerEvents.types.js","sourceRoot":"","sources":["../src/VideoPlayerEvents.types.ts"],"names":[],"mappings":"","sourcesContent":["import {\n PlayerError,\n SubtitleTrack,\n VideoPlayerStatus,\n VideoSource,\n VideoTrack,\n AudioTrack,\n} from './VideoPlayer.types';\n\n/**\n * Handlers for events which can be emitted by the player.\n */\nexport type VideoPlayerEvents = {\n /**\n * Handler for an event emitted when the status of the player changes.\n */\n statusChange(payload: StatusChangeEventPayload): void;\n\n /**\n * Handler for an event emitted when the player starts or stops playback.\n */\n playingChange(payload: PlayingChangeEventPayload): void;\n\n /**\n * Handler for an event emitted when the `playbackRate` property of the player changes.\n */\n playbackRateChange(payload: PlaybackRateChangeEventPayload): void;\n\n /**\n * Handler for an event emitted when the `volume` of `muted` property of the player changes.\n */\n volumeChange(payload: VolumeChangeEventPayload): void;\n\n /**\n * Handler for an event emitted when the `muted` property of the player changes\n */\n mutedChange(payload: MutedChangeEventPayload): void;\n\n /**\n * Handler for an event emitted when the player plays to the end of the current source.\n */\n playToEnd(): void;\n\n /**\n * Handler for an event emitted in a given interval specified by the `timeUpdateEventInterval`.\n */\n timeUpdate(payload: TimeUpdateEventPayload): void;\n\n /**\n * Handler for an event emitted when the current media source of the player changes.\n */\n sourceChange(payload: SourceChangeEventPayload): void;\n\n /**\n * Handler for an event emitted when the available subtitle tracks change.\n */\n availableSubtitleTracksChange(payload: AvailableSubtitleTracksChangeEventPayload): void;\n\n /**\n * Handler for an event emitted when the current subtitle track changes.\n */\n subtitleTrackChange(payload: SubtitleTrackChangeEventPayload): void;\n\n /**\n * Handler for an event emitted when the available audio tracks change.\n */\n availableAudioTracksChange(payload: AvailableAudioTracksChangeEventPayload): void;\n\n /**\n * Handler for an event emitted when the current audio track changes.\n */\n audioTrackChange(payload: AudioTrackChangeEventPayload): void;\n\n /**\n * Handler for an event emitted when the current video track changes.\n */\n videoTrackChange(payload: VideoTrackChangeEventPayload): void;\n\n /**\n * Handler for an event emitted when the player has finished loading metadata for the current video source.\n * This event is emitted when the player has finished metadata for a [`VideoSource`](#videosource), but it doesn't mean that there is enough data buffered to start the playback.\n */\n sourceLoad(payload: SourceLoadEventPayload): void;\n};\n\n/**\n * Data delivered with the [`statusChange`](#videoplayerevents) event.\n */\nexport type StatusChangeEventPayload = {\n /**\n * New status of the player.\n */\n status: VideoPlayerStatus;\n\n /**\n * Previous status of the player.\n */\n oldStatus?: VideoPlayerStatus;\n\n /**\n * Error object containing information about the error that occurred.\n */\n error?: PlayerError;\n};\n\n/**\n * Data delivered with the [`playingChange`](#videoplayerevents) event.\n */\nexport type PlayingChangeEventPayload = {\n /**\n * Boolean value whether the player is currently playing.\n */\n isPlaying: boolean;\n\n /**\n * Previous value of the `isPlaying` property.\n */\n oldIsPlaying?: boolean;\n};\n\n/**\n * Data delivered with the [`playbackRateChange`](#videoplayerevents) event.\n */\nexport type PlaybackRateChangeEventPayload = {\n /**\n * Float value indicating the current playback speed of the player.\n */\n playbackRate: number;\n\n /**\n * Previous value of the `playbackRate` property.\n */\n oldPlaybackRate?: number;\n};\n\n/**\n * Data delivered with the [`volumeChange`](#videoplayerevents) event.\n */\nexport type VolumeChangeEventPayload = {\n /**\n * Float value indicating the current volume of the player.\n */\n volume: number;\n\n /**\n * Previous value of the `volume` property.\n */\n oldVolume?: number;\n};\n\n/**\n * Data delivered with the [`mutedChange`](#videoplayerevents) event.\n */\nexport type MutedChangeEventPayload = {\n /**\n * Boolean value whether the player is currently muted.\n */\n muted: boolean;\n\n /**\n * Previous value of the `isMuted` property.\n */\n oldMuted?: boolean;\n};\n\n/**\n * Data delivered with the [`sourceChange`](#videoplayerevents) event.\n */\nexport type SourceChangeEventPayload = {\n /**\n * New source of the player.\n */\n source: VideoSource;\n\n /**\n * Previous source of the player.\n */\n oldSource?: VideoSource;\n};\n\n/**\n * Data delivered with the [`timeUpdate`](#videoplayerevents) event, contains information about the current playback progress.\n */\nexport type TimeUpdateEventPayload = {\n /**\n * Float value indicating the current playback time in seconds. Same as the [`currentTime`](#currenttime) property.\n */\n currentTime: number;\n\n /**\n * The exact timestamp when the currently displayed video frame was sent from the server,\n * based on the `EXT-X-PROGRAM-DATE-TIME` tag in the livestream metadata.\n * Same as the [`currentLiveTimestamp`](#currentlivetimestamp) property.\n * @platform android\n * @platform ios\n */\n currentLiveTimestamp: number | null;\n\n /**\n * Float value indicating the latency of the live stream in seconds.\n * Same as the [`currentOffsetFromLive`](#currentoffsetfromlive) property.\n * @platform android\n * @platform ios\n */\n currentOffsetFromLive: number | null;\n\n /**\n * Float value indicating how far the player has buffered the video in seconds.\n * Same as the [`bufferedPosition`](#bufferedPosition) property.\n * @platform android\n * @platform ios\n */\n bufferedPosition: number;\n};\n\nexport type SubtitleTrackChangeEventPayload = {\n /**\n * New subtitle track of the player.\n */\n subtitleTrack: SubtitleTrack | null;\n\n /**\n * Previous subtitle track of the player.\n */\n oldSubtitleTrack?: SubtitleTrack | null;\n};\n\n/**\n * Data delivered with the [`videoTrackChange`](#videoplayerevents) event, contains information about the video track which is currently being played.\n */\nexport type VideoTrackChangeEventPayload = {\n /**\n * New video track of the player.\n */\n videoTrack: VideoTrack | null;\n\n /**\n * Previous video track of the player.\n */\n oldVideoTrack?: VideoTrack | null;\n};\n\n/**\n * TODO @behenate: For SDK53 mark as deprecated in favor of SourceLoadEventPayload\n * @hidden\n */\nexport type AvailableSubtitleTracksChangeEventPayload = {\n /**\n * Array of available subtitle tracks.\n */\n availableSubtitleTracks: SubtitleTrack[];\n\n /**\n * Previous array of available subtitle tracks.\n */\n oldAvailableSubtitleTracks?: SubtitleTrack[];\n};\n\n/**\n * Data delivered with the [`sourceLoad`](#videoplayerevents) event, contains information about the video source that has finished loading.\n */\nexport type SourceLoadEventPayload = {\n /**\n * The video source that has been loaded.\n */\n videoSource: VideoSource | null;\n\n /**\n * Duration of the video source in seconds.\n */\n duration: number;\n\n /**\n * Video tracks available for the loaded video source.\n *\n * > On iOS, when using a HLS source, make sure that the uri contains `.m3u8` extension or that the [`contentType`](#contenttype) property of the [`VideoSource`](#videosource) has been set to `'hls'`. Otherwise, the video tracks will not be available.\n */\n availableVideoTracks: VideoTrack[];\n\n /**\n * Subtitle tracks available for the loaded video source.\n */\n availableSubtitleTracks: SubtitleTrack[];\n\n /**\n * Audio tracks available for the loaded video source.\n */\n availableAudioTracks: AudioTrack[];\n};\n\ntype AudioTrackChangeEventPayload = {\n /**\n * New audio track of the player.\n */\n audioTrack: AudioTrack | null;\n\n /**\n * Previous audio track of the player.\n */\n oldAudioTrack?: AudioTrack | null;\n};\n\ntype AvailableAudioTracksChangeEventPayload = {\n /**\n * Array of available audio tracks.\n */\n availableAudioTracks: AudioTrack[];\n\n /**\n * Previous array of available audio tracks.\n */\n oldAvailableAudioTracks?: AudioTrack[];\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VideoView.types.d.ts","sourceRoot":"","sources":["../src/VideoView.types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;AAE3D;;;;;;;GAOG;AACH,MAAM,MAAM,WAAW,GAAG,aAAa,GAAG,aAAa,CAAC;AAExD,MAAM,WAAW,cAAe,SAAQ,SAAS;IAC/C;;OAEG;IACH,MAAM,EAAE,WAAW,CAAC;IAEpB;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;;;OAIG;IACH,UAAU,CAAC,EAAE,eAAe,CAAC;IAE7B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;;;;OAKG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAEjC;;;;;OAKG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;IAE1B;;;;OAIG;IACH,eAAe,CAAC,EAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,EAAE,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAE/C;;;;;OAKG;IACH,uBAAuB,CAAC,EAAE,MAAM,IAAI,CAAC;IAErC;;;;;OAKG;IACH,sBAAsB,CAAC,EAAE,MAAM,IAAI,CAAC;IAEpC;;;;;;;OAOG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAEjC;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;;;;;;;;;OAUG;IACH,mCAAmC,CAAC,EAAE,OAAO,CAAC;IAE9C;;;;;OAKG;IACH,wBAAwB,CAAC,EAAE,OAAO,CAAC;IAEnC;;OAEG;IACH,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAC;IAE/B;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAE9B;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAC;IAEhC;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"VideoView.types.d.ts","sourceRoot":"","sources":["../src/VideoView.types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;AAE3D;;;;;;;GAOG;AACH,MAAM,MAAM,WAAW,GAAG,aAAa,GAAG,aAAa,CAAC;AAExD,MAAM,WAAW,cAAe,SAAQ,SAAS;IAC/C;;OAEG;IACH,MAAM,EAAE,WAAW,CAAC;IAEpB;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;;;OAIG;IACH,UAAU,CAAC,EAAE,eAAe,CAAC;IAE7B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;;;;OAKG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAEjC;;;;;OAKG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;IAE1B;;;;OAIG;IACH,eAAe,CAAC,EAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,EAAE,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAE/C;;;;;OAKG;IACH,uBAAuB,CAAC,EAAE,MAAM,IAAI,CAAC;IAErC;;;;;OAKG;IACH,sBAAsB,CAAC,EAAE,MAAM,IAAI,CAAC;IAEpC;;;;;;;OAOG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAEjC;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;;;;;;;;;OAUG;IACH,mCAAmC,CAAC,EAAE,OAAO,CAAC;IAE9C;;;;;OAKG;IACH,wBAAwB,CAAC,EAAE,OAAO,CAAC;IAEnC;;OAEG;IACH,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAC;IAE/B;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAE9B;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAC;IAEhC;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,WAAW,GAAG,iBAAiB,CAAC;CAC/C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VideoView.types.js","sourceRoot":"","sources":["../src/VideoView.types.ts"],"names":[],"mappings":"","sourcesContent":["import { ViewProps } from 'react-native';\n\nimport type { VideoPlayer } from './VideoPlayer.types';\n\n/**\n * Describes how a video should be scaled to fit in a container.\n * - `contain`: The video maintains its aspect ratio and fits inside the container, with possible letterboxing/pillarboxing.\n * - `cover`: The video maintains its aspect ratio and covers the entire container, potentially cropping some portions.\n * - `fill`: The video stretches/squeezes to completely fill the container, potentially causing distortion.\n */\nexport type VideoContentFit = 'contain' | 'cover' | 'fill';\n\n/**\n * Describes the type of the surface used to render the video.\n * - `surfaceView`: Uses the `SurfaceView` to render the video. This value should be used in the majority of cases. Provides significantly lower power consumption, better performance, and more features.\n * - `textureView`: Uses the `TextureView` to render the video. Should be used in cases where the SurfaceView is not supported or causes issues (for example, overlapping video views).\n *\n * You can learn more about surface types in the official [ExoPlayer documentation](https://developer.android.com/media/media3/ui/playerview#surfacetype).\n * @platform android\n */\nexport type SurfaceType = 'textureView' | 'surfaceView';\n\nexport interface VideoViewProps extends ViewProps {\n /**\n * A video player instance. Use [`useVideoPlayer()`](#usevideoplayersource-setup) hook to create one.\n */\n player: VideoPlayer;\n\n /**\n * Determines whether native controls should be displayed or not.\n * @default true\n */\n nativeControls?: boolean;\n\n /**\n * Describes how the video should be scaled to fit in the container.\n * Options are `'contain'`, `'cover'`, and `'fill'`.\n * @default 'contain'\n */\n contentFit?: VideoContentFit;\n\n /**\n * Determines whether fullscreen mode is allowed or not.\n * @default true\n */\n allowsFullscreen?: boolean;\n\n /**\n * Determines whether the timecodes should be displayed or not.\n * @default true\n * @platform ios\n */\n showsTimecodes?: boolean;\n\n /**\n * Determines whether the player allows the user to skip media content.\n * @default false\n * @platform android\n * @platform ios\n */\n requiresLinearPlayback?: boolean;\n\n /**\n * Determines the type of the surface used to render the video.\n * > This prop should not be changed at runtime.\n * @default 'surfaceView'\n * @platform android\n */\n surfaceType?: SurfaceType;\n\n /**\n * Determines the position offset of the video inside the container.\n * @default { dx: 0, dy: 0 }\n * @platform ios\n */\n contentPosition?: { dx?: number; dy?: number };\n\n /**\n * A callback to call after the video player enters Picture in Picture (PiP) mode.\n * @platform android\n * @platform ios\n * @platform web\n */\n onPictureInPictureStart?: () => void;\n\n /**\n * A callback to call after the video player exits Picture in Picture (PiP) mode.\n * @platform android\n * @platform ios\n * @platform web\n */\n onPictureInPictureStop?: () => void;\n\n /**\n * Determines whether the player allows Picture in Picture (PiP) mode.\n * > **Note:** The `supportsPictureInPicture` property of the [config plugin](#configuration-in-app-config)\n * > has to be configured for the PiP to work.\n * @platform android\n * @platform ios\n * @platform web\n */\n allowsPictureInPicture?: boolean;\n\n /**\n * Determines whether a video should be played \"inline\", that is, within the element's playback area.\n * @platform web\n */\n playsInline?: boolean;\n\n /**\n * Determines whether the player should start Picture in Picture (PiP) automatically when the app is in the background.\n * > **Note:** Only one player can be in Picture in Picture (PiP) mode at a time.\n *\n * > **Note:** The `supportsPictureInPicture` property of the [config plugin](#configuration-in-app-config)\n * > has to be configured for the PiP to work.\n *\n * @default false\n * @platform android 12+\n * @platform ios\n */\n startsPictureInPictureAutomatically?: boolean;\n\n /**\n * Specifies whether to perform video frame analysis (Live Text in videos).\n * Check official [Apple documentation](https://developer.apple.com/documentation/avkit/avplayerviewcontroller/allowsvideoframeanalysis) for more details.\n * @default true\n * @platform ios 16.0+\n */\n allowsVideoFrameAnalysis?: boolean;\n\n /**\n * A callback to call after the video player enters fullscreen mode.\n */\n onFullscreenEnter?: () => void;\n\n /**\n * A callback to call after the video player exits fullscreen mode.\n */\n onFullscreenExit?: () => void;\n\n /**\n * A callback to call after the mounted `VideoPlayer` has rendered the first frame into the `VideoView`.\n * This event can be used to hide any cover images that conceal the initial loading of the player.\n * > **Note:** This event may also be called during playback when the current video track changes (for example when the player switches video quality).\n */\n onFirstFrameRender?: () => void;\n\n /**\n * Determines whether the player should use the default ExoPlayer shutter that covers the `VideoView` before the first video frame is rendered.\n * Setting this property to `false` makes the Android behavior the same as iOS.\n *\n * @platform android\n * @default
|
|
1
|
+
{"version":3,"file":"VideoView.types.js","sourceRoot":"","sources":["../src/VideoView.types.ts"],"names":[],"mappings":"","sourcesContent":["import { ViewProps } from 'react-native';\n\nimport type { VideoPlayer } from './VideoPlayer.types';\n\n/**\n * Describes how a video should be scaled to fit in a container.\n * - `contain`: The video maintains its aspect ratio and fits inside the container, with possible letterboxing/pillarboxing.\n * - `cover`: The video maintains its aspect ratio and covers the entire container, potentially cropping some portions.\n * - `fill`: The video stretches/squeezes to completely fill the container, potentially causing distortion.\n */\nexport type VideoContentFit = 'contain' | 'cover' | 'fill';\n\n/**\n * Describes the type of the surface used to render the video.\n * - `surfaceView`: Uses the `SurfaceView` to render the video. This value should be used in the majority of cases. Provides significantly lower power consumption, better performance, and more features.\n * - `textureView`: Uses the `TextureView` to render the video. Should be used in cases where the SurfaceView is not supported or causes issues (for example, overlapping video views).\n *\n * You can learn more about surface types in the official [ExoPlayer documentation](https://developer.android.com/media/media3/ui/playerview#surfacetype).\n * @platform android\n */\nexport type SurfaceType = 'textureView' | 'surfaceView';\n\nexport interface VideoViewProps extends ViewProps {\n /**\n * A video player instance. Use [`useVideoPlayer()`](#usevideoplayersource-setup) hook to create one.\n */\n player: VideoPlayer;\n\n /**\n * Determines whether native controls should be displayed or not.\n * @default true\n */\n nativeControls?: boolean;\n\n /**\n * Describes how the video should be scaled to fit in the container.\n * Options are `'contain'`, `'cover'`, and `'fill'`.\n * @default 'contain'\n */\n contentFit?: VideoContentFit;\n\n /**\n * Determines whether fullscreen mode is allowed or not.\n * @default true\n */\n allowsFullscreen?: boolean;\n\n /**\n * Determines whether the timecodes should be displayed or not.\n * @default true\n * @platform ios\n */\n showsTimecodes?: boolean;\n\n /**\n * Determines whether the player allows the user to skip media content.\n * @default false\n * @platform android\n * @platform ios\n */\n requiresLinearPlayback?: boolean;\n\n /**\n * Determines the type of the surface used to render the video.\n * > This prop should not be changed at runtime.\n * @default 'surfaceView'\n * @platform android\n */\n surfaceType?: SurfaceType;\n\n /**\n * Determines the position offset of the video inside the container.\n * @default { dx: 0, dy: 0 }\n * @platform ios\n */\n contentPosition?: { dx?: number; dy?: number };\n\n /**\n * A callback to call after the video player enters Picture in Picture (PiP) mode.\n * @platform android\n * @platform ios\n * @platform web\n */\n onPictureInPictureStart?: () => void;\n\n /**\n * A callback to call after the video player exits Picture in Picture (PiP) mode.\n * @platform android\n * @platform ios\n * @platform web\n */\n onPictureInPictureStop?: () => void;\n\n /**\n * Determines whether the player allows Picture in Picture (PiP) mode.\n * > **Note:** The `supportsPictureInPicture` property of the [config plugin](#configuration-in-app-config)\n * > has to be configured for the PiP to work.\n * @platform android\n * @platform ios\n * @platform web\n */\n allowsPictureInPicture?: boolean;\n\n /**\n * Determines whether a video should be played \"inline\", that is, within the element's playback area.\n * @platform web\n */\n playsInline?: boolean;\n\n /**\n * Determines whether the player should start Picture in Picture (PiP) automatically when the app is in the background.\n * > **Note:** Only one player can be in Picture in Picture (PiP) mode at a time.\n *\n * > **Note:** The `supportsPictureInPicture` property of the [config plugin](#configuration-in-app-config)\n * > has to be configured for the PiP to work.\n *\n * @default false\n * @platform android 12+\n * @platform ios\n */\n startsPictureInPictureAutomatically?: boolean;\n\n /**\n * Specifies whether to perform video frame analysis (Live Text in videos).\n * Check official [Apple documentation](https://developer.apple.com/documentation/avkit/avplayerviewcontroller/allowsvideoframeanalysis) for more details.\n * @default true\n * @platform ios 16.0+\n */\n allowsVideoFrameAnalysis?: boolean;\n\n /**\n * A callback to call after the video player enters fullscreen mode.\n */\n onFullscreenEnter?: () => void;\n\n /**\n * A callback to call after the video player exits fullscreen mode.\n */\n onFullscreenExit?: () => void;\n\n /**\n * A callback to call after the mounted `VideoPlayer` has rendered the first frame into the `VideoView`.\n * This event can be used to hide any cover images that conceal the initial loading of the player.\n * > **Note:** This event may also be called during playback when the current video track changes (for example when the player switches video quality).\n */\n onFirstFrameRender?: () => void;\n\n /**\n * Determines whether the player should use the default ExoPlayer shutter that covers the `VideoView` before the first video frame is rendered.\n * Setting this property to `false` makes the Android behavior the same as iOS.\n *\n * @platform android\n * @default false\n */\n useExoShutter?: boolean;\n\n /**\n * Determines the [cross origin policy](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Attributes/crossorigin) used by the underlying native view on web.\n * If undefined, does not use CORS at all.\n *\n * @platform web\n * @default undefined\n */\n crossOrigin?: 'anonymous' | 'use-credentials';\n}\n"]}
|
package/build/index.d.ts
CHANGED
|
@@ -4,6 +4,6 @@ export { useVideoPlayer } from './VideoPlayer';
|
|
|
4
4
|
export { VideoContentFit, VideoViewProps, SurfaceType } from './VideoView.types';
|
|
5
5
|
export { VideoThumbnail } from './VideoThumbnail';
|
|
6
6
|
export { createVideoPlayer } from './VideoPlayer';
|
|
7
|
-
export { VideoPlayer, VideoPlayerStatus, VideoSource, PlayerError, VideoMetadata, DRMType, DRMOptions, BufferOptions, AudioMixingMode, VideoThumbnailOptions, VideoSize, SubtitleTrack, VideoTrack, ContentType, } from './VideoPlayer.types';
|
|
7
|
+
export { VideoPlayer, VideoPlayerStatus, VideoSource, PlayerError, VideoMetadata, DRMType, DRMOptions, BufferOptions, AudioMixingMode, VideoThumbnailOptions, VideoSize, SubtitleTrack, AudioTrack, VideoTrack, ContentType, } from './VideoPlayer.types';
|
|
8
8
|
export { VideoPlayerEvents, StatusChangeEventPayload, PlayingChangeEventPayload, PlaybackRateChangeEventPayload, VolumeChangeEventPayload, MutedChangeEventPayload, TimeUpdateEventPayload, SourceChangeEventPayload, SourceLoadEventPayload, } from './VideoPlayerEvents.types';
|
|
9
9
|
//# sourceMappingURL=index.d.ts.map
|
package/build/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,2BAA2B,EAC3B,oBAAoB,EACpB,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,WAAW,EACX,WAAW,EACX,aAAa,EACb,OAAO,EACP,UAAU,EACV,aAAa,EACb,eAAe,EACf,qBAAqB,EACrB,SAAS,EACT,aAAa,EACb,UAAU,EACV,WAAW,GACZ,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,iBAAiB,EACjB,wBAAwB,EACxB,yBAAyB,EACzB,8BAA8B,EAC9B,wBAAwB,EACxB,uBAAuB,EACvB,sBAAsB,EACtB,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,2BAA2B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,2BAA2B,EAC3B,oBAAoB,EACpB,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,WAAW,EACX,WAAW,EACX,aAAa,EACb,OAAO,EACP,UAAU,EACV,aAAa,EACb,eAAe,EACf,qBAAqB,EACrB,SAAS,EACT,aAAa,EACb,UAAU,EACV,UAAU,EACV,WAAW,GACZ,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,iBAAiB,EACjB,wBAAwB,EACxB,yBAAyB,EACzB,8BAA8B,EAC9B,wBAAwB,EACxB,uBAAuB,EACvB,sBAAsB,EACtB,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,2BAA2B,CAAC"}
|
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,2BAA2B,EAC3B,oBAAoB,EACpB,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAG/C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,EACL,WAAW,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,2BAA2B,EAC3B,oBAAoB,EACpB,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAG/C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,EACL,WAAW,GAeZ,MAAM,qBAAqB,CAAC","sourcesContent":["export {\n isPictureInPictureSupported,\n clearVideoCacheAsync,\n setVideoCacheSizeAsync,\n getCurrentVideoCacheSize,\n} from './VideoModule';\nexport { VideoView } from './VideoView';\nexport { useVideoPlayer } from './VideoPlayer';\n\nexport { VideoContentFit, VideoViewProps, SurfaceType } from './VideoView.types';\nexport { VideoThumbnail } from './VideoThumbnail';\n\nexport { createVideoPlayer } from './VideoPlayer';\n\nexport {\n VideoPlayer,\n VideoPlayerStatus,\n VideoSource,\n PlayerError,\n VideoMetadata,\n DRMType,\n DRMOptions,\n BufferOptions,\n AudioMixingMode,\n VideoThumbnailOptions,\n VideoSize,\n SubtitleTrack,\n AudioTrack,\n VideoTrack,\n ContentType,\n} from './VideoPlayer.types';\n\nexport {\n VideoPlayerEvents,\n StatusChangeEventPayload,\n PlayingChangeEventPayload,\n PlaybackRateChangeEventPayload,\n VolumeChangeEventPayload,\n MutedChangeEventPayload,\n TimeUpdateEventPayload,\n SourceChangeEventPayload,\n SourceLoadEventPayload,\n} from './VideoPlayerEvents.types';\n"]}
|
package/expo-module.config.json
CHANGED
|
@@ -4,6 +4,12 @@
|
|
|
4
4
|
"modules": ["VideoModule"]
|
|
5
5
|
},
|
|
6
6
|
"android": {
|
|
7
|
-
"modules": ["expo.modules.video.VideoModule"]
|
|
7
|
+
"modules": ["expo.modules.video.VideoModule"],
|
|
8
|
+
"publication": {
|
|
9
|
+
"groupId": "host.exp.exponent",
|
|
10
|
+
"artifactId": "expo.modules.video",
|
|
11
|
+
"version": "2.2.0",
|
|
12
|
+
"repository": "local-maven-repo"
|
|
13
|
+
}
|
|
8
14
|
}
|
|
9
15
|
}
|
package/ios/Records/Tracks.swift
CHANGED
|
@@ -20,6 +20,19 @@ internal struct SubtitleTrack: Record {
|
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
internal struct AudioTrack: Record {
|
|
24
|
+
@Field var language: String? = nil
|
|
25
|
+
@Field var label: String? = nil
|
|
26
|
+
|
|
27
|
+
static func from(mediaSelectionOption option: AVMediaSelectionOption) -> AudioTrack? {
|
|
28
|
+
guard let identifier = option.locale?.identifier else {
|
|
29
|
+
return nil
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return AudioTrack(language: identifier, label: option.displayName)
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
23
36
|
internal struct VideoTrack: Record, Equatable {
|
|
24
37
|
@Field var id: String? = nil
|
|
25
38
|
@Field var size: VideoSize? = nil
|
|
@@ -43,6 +43,16 @@ internal struct SubtitleTrackChangedEventPayload: Record {
|
|
|
43
43
|
@Field var oldSubtitleTrack: SubtitleTrack? = nil
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
internal struct AudioTracksChangedEventPayload: Record {
|
|
47
|
+
@Field var availableAudioTracks: [AudioTrack] = []
|
|
48
|
+
@Field var oldAvailableAudioTracks: [AudioTrack] = []
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
internal struct AudioTrackChangedEventPayload: Record {
|
|
52
|
+
@Field var audioTrack: AudioTrack? = nil
|
|
53
|
+
@Field var oldAudioTrack: AudioTrack? = nil
|
|
54
|
+
}
|
|
55
|
+
|
|
46
56
|
internal struct TimeUpdate: Record {
|
|
47
57
|
@Field var currentTime: Double = 0
|
|
48
58
|
@Field var currentLiveTimestamp: Double? = nil
|
|
@@ -60,6 +70,7 @@ internal struct VideoSourceLoadedEventPayload: Record {
|
|
|
60
70
|
@Field var duration: Double? = nil
|
|
61
71
|
@Field var availableVideoTracks: [VideoTrack]? = nil
|
|
62
72
|
@Field var availableSubtitleTracks: [SubtitleTrack]? = nil
|
|
73
|
+
@Field var availableAudioTracks: [AudioTrack]? = nil
|
|
63
74
|
}
|
|
64
75
|
|
|
65
76
|
// swiftlint:enable redundant_optional_initialization
|
package/ios/VideoModule.swift
CHANGED
|
@@ -271,6 +271,17 @@ public final class VideoModule: Module {
|
|
|
271
271
|
player.subtitles.selectSubtitleTrack(subtitleTrack: subtitleTrack)
|
|
272
272
|
}
|
|
273
273
|
|
|
274
|
+
Property("availableAudioTracks") { player -> [AudioTrack] in
|
|
275
|
+
return player.audioTracks.availableAudioTracks
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
Property("audioTrack") { player -> AudioTrack? in
|
|
279
|
+
return player.audioTracks.currentAudioTrack
|
|
280
|
+
}
|
|
281
|
+
.set { player, audioTrack in
|
|
282
|
+
player.audioTracks.selectAudioTrack(audioTrack: audioTrack)
|
|
283
|
+
}
|
|
284
|
+
|
|
274
285
|
Function("play") { player in
|
|
275
286
|
player.ref.play()
|
|
276
287
|
}
|
package/ios/VideoPlayer.swift
CHANGED
|
@@ -10,6 +10,7 @@ internal final class VideoPlayer: SharedRef<AVPlayer>, Hashable, VideoPlayerObse
|
|
|
10
10
|
var observer: VideoPlayerObserver?
|
|
11
11
|
lazy var subtitles: VideoPlayerSubtitles = VideoPlayerSubtitles(owner: self)
|
|
12
12
|
private var dangerousPropertiesStore = DangerousPropertiesStore()
|
|
13
|
+
lazy var audioTracks: VideoPlayerAudioTracks = VideoPlayerAudioTracks(owner: self)
|
|
13
14
|
|
|
14
15
|
var loop = false
|
|
15
16
|
var audioMixingMode: AudioMixingMode = .doNotMix {
|
|
@@ -21,6 +22,7 @@ internal final class VideoPlayer: SharedRef<AVPlayer>, Hashable, VideoPlayerObse
|
|
|
21
22
|
}
|
|
22
23
|
private(set) var isPlaying = false
|
|
23
24
|
private(set) var status: PlayerStatus = .idle
|
|
25
|
+
|
|
24
26
|
var playbackRate: Float = 1.0 {
|
|
25
27
|
didSet {
|
|
26
28
|
if oldValue != playbackRate {
|
|
@@ -372,6 +374,15 @@ internal final class VideoPlayer: SharedRef<AVPlayer>, Hashable, VideoPlayerObse
|
|
|
372
374
|
)
|
|
373
375
|
safeEmit(event: "availableSubtitleTracksChange", payload: payload)
|
|
374
376
|
|
|
377
|
+
// Handle audio tracks
|
|
378
|
+
let oldAudioTracks = audioTracks.availableAudioTracks
|
|
379
|
+
self.audioTracks.onNewPlayerItemLoaded(playerItem: playerItem)
|
|
380
|
+
let audioPayload = AudioTracksChangedEventPayload(
|
|
381
|
+
availableAudioTracks: audioTracks.availableAudioTracks,
|
|
382
|
+
oldAvailableAudioTracks: oldAudioTracks
|
|
383
|
+
)
|
|
384
|
+
safeEmit(event: "availableAudioTracksChange", payload: audioPayload)
|
|
385
|
+
|
|
375
386
|
Task {
|
|
376
387
|
let videoPlayerItem: VideoPlayerItem? = playerItem as? VideoPlayerItem
|
|
377
388
|
// Those properties will be already loaded 99.9% of time, so the event delay should be almost 0
|
|
@@ -381,7 +392,8 @@ internal final class VideoPlayer: SharedRef<AVPlayer>, Hashable, VideoPlayerObse
|
|
|
381
392
|
videoSource: videoPlayerItem?.videoSource,
|
|
382
393
|
duration: playerItem?.duration.seconds,
|
|
383
394
|
availableVideoTracks: availableVideoTracks,
|
|
384
|
-
availableSubtitleTracks: subtitles.availableSubtitleTracks
|
|
395
|
+
availableSubtitleTracks: subtitles.availableSubtitleTracks,
|
|
396
|
+
availableAudioTracks: audioTracks.availableAudioTracks
|
|
385
397
|
)
|
|
386
398
|
safeEmit(event: "sourceLoad", payload: videoSourceLoadedPayload)
|
|
387
399
|
}
|
|
@@ -394,6 +406,13 @@ internal final class VideoPlayer: SharedRef<AVPlayer>, Hashable, VideoPlayerObse
|
|
|
394
406
|
safeEmit(event: "subtitleTrackChange", payload: payload)
|
|
395
407
|
}
|
|
396
408
|
|
|
409
|
+
func onAudioTrackSelectionChanged(player: AVPlayer, playerItem: AVPlayerItem?, audioTrack: AudioTrack?) {
|
|
410
|
+
let oldTrack = audioTracks.currentAudioTrack
|
|
411
|
+
audioTracks.onNewAudioTrackSelected(audioTrack: audioTrack)
|
|
412
|
+
let payload = AudioTrackChangedEventPayload(audioTrack: audioTracks.currentAudioTrack, oldAudioTrack: oldTrack)
|
|
413
|
+
safeEmit(event: "audioTrackChange", payload: payload)
|
|
414
|
+
}
|
|
415
|
+
|
|
397
416
|
func onVideoTrackChanged(player: AVPlayer, oldVideoTrack: VideoTrack?, newVideoTrack: VideoTrack?) {
|
|
398
417
|
currentVideoTrack = newVideoTrack
|
|
399
418
|
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import AVFoundation
|
|
3
|
+
|
|
4
|
+
class VideoPlayerAudioTracks {
|
|
5
|
+
weak var owner: VideoPlayer?
|
|
6
|
+
private(set) var availableAudioTracks: [AudioTrack] = []
|
|
7
|
+
private(set) var currentAudioTrack: AudioTrack?
|
|
8
|
+
|
|
9
|
+
init (owner: VideoPlayer) {
|
|
10
|
+
self.owner = owner
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
func onNewAudioTrackSelected(audioTrack: AudioTrack?) {
|
|
14
|
+
currentAudioTrack = audioTrack
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
func onNewPlayerItemLoaded(playerItem: AVPlayerItem?) {
|
|
18
|
+
availableAudioTracks = Self.findAvailableAudioTracks(for: playerItem)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
func selectAudioTrack(audioTrack: AudioTrack?) {
|
|
22
|
+
guard let currentItem = self.owner?.ref.currentItem else {
|
|
23
|
+
return
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if let group = currentItem.asset.mediaSelectionGroup(forMediaCharacteristic: .audible) {
|
|
27
|
+
let option = group.options.first {
|
|
28
|
+
$0.displayName == audioTrack?.label && $0.locale?.identifier == audioTrack?.language
|
|
29
|
+
}
|
|
30
|
+
currentItem.select(option, in: group)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
static func findAvailableAudioTracks(for playerItem: AVPlayerItem?) -> [AudioTrack] {
|
|
35
|
+
var availableAudioTracks: [AudioTrack] = []
|
|
36
|
+
|
|
37
|
+
guard let asset = playerItem?.asset else {
|
|
38
|
+
return availableAudioTracks
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
let mediaSelectionCharacteristics = asset.availableMediaCharacteristicsWithMediaSelectionOptions
|
|
42
|
+
|
|
43
|
+
for characteristic in mediaSelectionCharacteristics {
|
|
44
|
+
guard characteristic == .audible else {
|
|
45
|
+
continue
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if let group = asset.mediaSelectionGroup(forMediaCharacteristic: characteristic) {
|
|
49
|
+
for option in group.options {
|
|
50
|
+
guard let audioTrack = AudioTrack.from(mediaSelectionOption: option) else {
|
|
51
|
+
continue
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
availableAudioTracks.append(audioTrack)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return availableAudioTracks
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
static func findCurrentAudioTrack(for playerItem: AVPlayerItem?) -> AudioTrack? {
|
|
62
|
+
guard
|
|
63
|
+
let currentItem = playerItem,
|
|
64
|
+
let mediaSelectionGroup = currentItem.asset.mediaSelectionGroup(forMediaCharacteristic: .audible),
|
|
65
|
+
let selectedMediaOption = currentItem.currentMediaSelection.selectedMediaOption(in: mediaSelectionGroup)
|
|
66
|
+
else {
|
|
67
|
+
return nil
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return AudioTrack.from(mediaSelectionOption: selectedMediaOption)
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -24,6 +24,7 @@ protocol VideoPlayerObserverDelegate: AnyObject {
|
|
|
24
24
|
func onTimeUpdate(player: AVPlayer, timeUpdate: TimeUpdate)
|
|
25
25
|
func onAudioMixingModeChanged(player: AVPlayer, oldAudioMixingMode: AudioMixingMode, newAudioMixingMode: AudioMixingMode)
|
|
26
26
|
func onSubtitleSelectionChanged(player: AVPlayer, playerItem: AVPlayerItem?, subtitleTrack: SubtitleTrack?)
|
|
27
|
+
func onAudioTrackSelectionChanged(player: AVPlayer, playerItem: AVPlayerItem?, audioTrack: AudioTrack?)
|
|
27
28
|
func onLoadedPlayerItem(player: AVPlayer, playerItem: AVPlayerItem?)
|
|
28
29
|
func onVideoTrackChanged(player: AVPlayer, oldVideoTrack: VideoTrack?, newVideoTrack: VideoTrack?)
|
|
29
30
|
}
|
|
@@ -41,6 +42,7 @@ extension VideoPlayerObserverDelegate {
|
|
|
41
42
|
func onTimeUpdate(player: AVPlayer, timeUpdate: TimeUpdate) {}
|
|
42
43
|
func onAudioMixingModeChanged(player: AVPlayer, oldAudioMixingMode: AudioMixingMode, newAudioMixingMode: AudioMixingMode) {}
|
|
43
44
|
func onSubtitleSelectionChanged(player: AVPlayer, playerItem: AVPlayerItem?, subtitleTrack: SubtitleTrack?) {}
|
|
45
|
+
func onAudioTrackSelectionChanged(player: AVPlayer, playerItem: AVPlayerItem?, audioTrack: AudioTrack?) {}
|
|
44
46
|
func onLoadedPlayerItem(player: AVPlayer, playerItem: AVPlayerItem?) {}
|
|
45
47
|
func onVideoTrackChanged(player: AVPlayer, oldVideoTrack: VideoTrack?, newVideoTrack: VideoTrack?) {}
|
|
46
48
|
}
|
|
@@ -123,6 +125,7 @@ class VideoPlayerObserver {
|
|
|
123
125
|
private var playerItemStatusObserver: NSKeyValueObservation?
|
|
124
126
|
private var playbackLikelyToKeepUpObserver: NSKeyValueObservation?
|
|
125
127
|
private var currentSubtitlesObserver: NSObjectProtocol?
|
|
128
|
+
private var currentAudioTracksObserver: NSObjectProtocol?
|
|
126
129
|
|
|
127
130
|
init(owner: VideoPlayer) {
|
|
128
131
|
self.owner = owner
|
|
@@ -241,6 +244,17 @@ class VideoPlayerObserver {
|
|
|
241
244
|
delegate.value?.onSubtitleSelectionChanged(player: player, playerItem: playerItem, subtitleTrack: subtitleTrack)
|
|
242
245
|
}
|
|
243
246
|
}
|
|
247
|
+
|
|
248
|
+
currentAudioTracksObserver = NotificationCenter.default.addObserver(
|
|
249
|
+
forName: AVPlayerItem.mediaSelectionDidChangeNotification,
|
|
250
|
+
object: playerItem,
|
|
251
|
+
queue: nil
|
|
252
|
+
) { [weak self] _ in
|
|
253
|
+
self?.delegates.forEach { delegate in
|
|
254
|
+
let audioTrack = VideoPlayerAudioTracks.findCurrentAudioTrack(for: playerItem)
|
|
255
|
+
delegate.value?.onAudioTrackSelectionChanged(player: player, playerItem: playerItem, audioTrack: audioTrack)
|
|
256
|
+
}
|
|
257
|
+
}
|
|
244
258
|
}
|
|
245
259
|
|
|
246
260
|
private func invalidateCurrentPlayerItemObservers() {
|
|
@@ -250,6 +264,7 @@ class VideoPlayerObserver {
|
|
|
250
264
|
tracksObserver?.invalidate()
|
|
251
265
|
NotificationCenter.default.removeObserver(playerItemObserver as Any)
|
|
252
266
|
NotificationCenter.default.removeObserver(currentSubtitlesObserver as Any)
|
|
267
|
+
NotificationCenter.default.removeObserver(currentAudioTracksObserver as Any)
|
|
253
268
|
}
|
|
254
269
|
|
|
255
270
|
func startOrUpdateTimeUpdates(forInterval interval: Double) {
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
6e1f79fc8674bec45f35f95a4f8933f3
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
f26b20423aa775f88468456856f576c24bc8149b
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ff54e2221752092ebdece914b77e4504b2864fc94504c8a1887ea67a2afa5ea0
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
c7c374ab88183e831ed5a80a5e7a6f9ef2d29d4157c7b9496e30a9f87b14c4952b1e867b29f8feedbab21badccdf1b751f3a20367d1970a5e814311d96618f0e
|
package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0.aar
ADDED
|
Binary file
|
package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0.aar.md5
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
b87e04623a8bc68b39b0d628a278460d
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
06203802abf1c39df7bef9bddb6cf7dda03e6300
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0022fab08b59c4346e67a4bf573af546f4f0e7eb322aee1115335e035318fa2c
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
a1501f7e947680eba85a049cf0520518bca4feca64832fbdc41383cb2c483f6253ecf8d429ad936966fcce1b0494175035399894dbce9c50f4765bd099edebf1
|