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.
Files changed (64) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/android/build.gradle +2 -2
  3. package/android/src/main/java/expo/modules/video/VideoModule.kt +21 -1
  4. package/android/src/main/java/expo/modules/video/VideoView.kt +7 -4
  5. package/android/src/main/java/expo/modules/video/player/FirstFrameEventGenerator.kt +3 -2
  6. package/android/src/main/java/expo/modules/video/player/PlayerEvent.kt +20 -2
  7. package/android/src/main/java/expo/modules/video/player/VideoPlayer.kt +16 -1
  8. package/android/src/main/java/expo/modules/video/player/VideoPlayerAudioTracks.kt +125 -0
  9. package/android/src/main/java/expo/modules/video/records/Tracks.kt +21 -0
  10. package/android/src/main/java/expo/modules/video/records/VideoEventPayloads.kt +12 -1
  11. package/build/VideoPlayer.types.d.ts +30 -0
  12. package/build/VideoPlayer.types.d.ts.map +1 -1
  13. package/build/VideoPlayer.types.js.map +1 -1
  14. package/build/VideoPlayer.web.d.ts +3 -1
  15. package/build/VideoPlayer.web.d.ts.map +1 -1
  16. package/build/VideoPlayer.web.js +2 -0
  17. package/build/VideoPlayer.web.js.map +1 -1
  18. package/build/VideoPlayerEvents.types.d.ts +34 -1
  19. package/build/VideoPlayerEvents.types.d.ts.map +1 -1
  20. package/build/VideoPlayerEvents.types.js.map +1 -1
  21. package/build/VideoView.types.d.ts +1 -1
  22. package/build/VideoView.types.d.ts.map +1 -1
  23. package/build/VideoView.types.js.map +1 -1
  24. package/build/index.d.ts +1 -1
  25. package/build/index.d.ts.map +1 -1
  26. package/build/index.js.map +1 -1
  27. package/expo-module.config.json +7 -1
  28. package/ios/Records/Tracks.swift +13 -0
  29. package/ios/Records/VideoEventPayloads.swift +11 -0
  30. package/ios/VideoModule.swift +11 -0
  31. package/ios/VideoPlayer.swift +20 -1
  32. package/ios/VideoPlayerAudioTracks.swift +72 -0
  33. package/ios/VideoPlayerObserver.swift +15 -0
  34. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0-sources.jar +0 -0
  35. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0-sources.jar.md5 +1 -0
  36. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0-sources.jar.sha1 +1 -0
  37. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0-sources.jar.sha256 +1 -0
  38. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0-sources.jar.sha512 +1 -0
  39. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0.aar +0 -0
  40. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0.aar.md5 +1 -0
  41. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0.aar.sha1 +1 -0
  42. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0.aar.sha256 +1 -0
  43. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0.aar.sha512 +1 -0
  44. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0.module +147 -0
  45. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0.module.md5 +1 -0
  46. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0.module.sha1 +1 -0
  47. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0.module.sha256 +1 -0
  48. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0.module.sha512 +1 -0
  49. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0.pom +88 -0
  50. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0.pom.md5 +1 -0
  51. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0.pom.sha1 +1 -0
  52. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0.pom.sha256 +1 -0
  53. package/local-maven-repo/host/exp/exponent/expo.modules.video/2.2.0/expo.modules.video-2.2.0.pom.sha512 +1 -0
  54. package/local-maven-repo/host/exp/exponent/expo.modules.video/maven-metadata.xml +13 -0
  55. package/local-maven-repo/host/exp/exponent/expo.modules.video/maven-metadata.xml.md5 +1 -0
  56. package/local-maven-repo/host/exp/exponent/expo.modules.video/maven-metadata.xml.sha1 +1 -0
  57. package/local-maven-repo/host/exp/exponent/expo.modules.video/maven-metadata.xml.sha256 +1 -0
  58. package/local-maven-repo/host/exp/exponent/expo.modules.video/maven-metadata.xml.sha512 +1 -0
  59. package/package.json +2 -2
  60. package/src/VideoPlayer.types.ts +35 -0
  61. package/src/VideoPlayer.web.tsx +3 -0
  62. package/src/VideoPlayerEvents.types.ts +40 -0
  63. package/src/VideoView.types.ts +2 -1
  64. package/src/index.ts +1 -0
@@ -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":"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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 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":"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"}
@@ -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"]}
@@ -132,7 +132,7 @@ export interface VideoViewProps extends ViewProps {
132
132
  * Setting this property to `false` makes the Android behavior the same as iOS.
133
133
  *
134
134
  * @platform android
135
- * @default true
135
+ * @default false
136
136
  */
137
137
  useExoShutter?: boolean;
138
138
  /**
@@ -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;IACxB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,WAAW,GAAG,iBAAiB,CAAC;CAC/C"}
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 true\n */\n useExoShutter?: boolean;\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"]}
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
@@ -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"}
@@ -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,GAcZ,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 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"]}
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"]}
@@ -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
  }
@@ -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
@@ -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
  }
@@ -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) {
@@ -0,0 +1 @@
1
+ ff54e2221752092ebdece914b77e4504b2864fc94504c8a1887ea67a2afa5ea0
@@ -0,0 +1 @@
1
+ c7c374ab88183e831ed5a80a5e7a6f9ef2d29d4157c7b9496e30a9f87b14c4952b1e867b29f8feedbab21badccdf1b751f3a20367d1970a5e814311d96618f0e
@@ -0,0 +1 @@
1
+ 06203802abf1c39df7bef9bddb6cf7dda03e6300
@@ -0,0 +1 @@
1
+ 0022fab08b59c4346e67a4bf573af546f4f0e7eb322aee1115335e035318fa2c
@@ -0,0 +1 @@
1
+ a1501f7e947680eba85a049cf0520518bca4feca64832fbdc41383cb2c483f6253ecf8d429ad936966fcce1b0494175035399894dbce9c50f4765bd099edebf1