@banou/media-player 0.2.6 → 0.4.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 (76) hide show
  1. package/README.md +0 -10
  2. package/build/components/chrome.d.ts +4 -0
  3. package/build/components/control-bar.d.ts +5 -0
  4. package/build/components/overlay.d.ts +1 -0
  5. package/build/components/progress-bar.d.ts +1 -0
  6. package/build/components/settings.d.ts +2 -0
  7. package/build/components/sound.d.ts +4 -0
  8. package/build/components/tooltip-display.d.ts +20 -0
  9. package/build/components/volume-slider.d.ts +6 -0
  10. package/build/index.d.ts +23 -48
  11. package/build/index.js +2593 -2230
  12. package/build/main.d.ts +1 -1
  13. package/build/state-machines/data-source.d.ts +27 -0
  14. package/build/state-machines/index.d.ts +33185 -0
  15. package/build/state-machines/media-properties.d.ts +45 -0
  16. package/build/state-machines/media-source.d.ts +34 -0
  17. package/build/state-machines/media.d.ts +8344 -0
  18. package/build/state-machines/subtitles.d.ts +53 -0
  19. package/build/state-machines/thumbnails.d.ts +24 -0
  20. package/build/state-machines/utils.d.ts +26 -0
  21. package/build/utils/actor-utils.d.ts +2 -0
  22. package/build/utils/colors.d.ts +8 -0
  23. package/build/utils/context.d.ts +14 -0
  24. package/build/utils/fonts.d.ts +28 -0
  25. package/build/{utils.d.ts → utils/index.d.ts} +4 -12
  26. package/build/utils/languages.d.ts +260 -0
  27. package/build/{mp4box.d.ts → utils/mp4box.d.ts} +61 -61
  28. package/build/utils/time.d.ts +2 -0
  29. package/build/utils/use-local-storage.d.ts +3 -0
  30. package/build/{use-scrub.d.ts → utils/use-scrub.d.ts} +11 -10
  31. package/build/utils/volume-utils.d.ts +17 -0
  32. package/build/utils/window-height.d.ts +2 -0
  33. package/package.json +15 -12
  34. package/src/assets/picture-in-picture.svg +5 -0
  35. package/src/components/chrome.tsx +89 -0
  36. package/src/components/control-bar.tsx +330 -0
  37. package/src/components/overlay.tsx +28 -0
  38. package/src/components/progress-bar.tsx +252 -0
  39. package/src/components/settings.tsx +269 -0
  40. package/src/components/sound.tsx +101 -0
  41. package/src/components/tooltip-display.tsx +83 -0
  42. package/src/components/volume-slider.tsx +156 -0
  43. package/src/index.tsx +145 -434
  44. package/src/main.tsx +66 -39
  45. package/src/state-machines/data-source.ts +83 -0
  46. package/src/state-machines/index.ts +5 -0
  47. package/src/state-machines/media-properties.ts +78 -0
  48. package/src/state-machines/media-source.ts +129 -0
  49. package/src/state-machines/media.ts +245 -0
  50. package/src/state-machines/subtitles.ts +247 -0
  51. package/src/state-machines/thumbnails.ts +123 -0
  52. package/src/state-machines/utils.ts +94 -0
  53. package/src/utils/actor-utils.ts +19 -0
  54. package/src/utils/colors.ts +9 -0
  55. package/src/utils/context.ts +23 -0
  56. package/src/utils/fonts.ts +156 -0
  57. package/src/{utils.ts → utils/index.ts} +2 -26
  58. package/src/utils/time.ts +16 -0
  59. package/src/utils/use-local-storage.ts +30 -0
  60. package/src/{use-scrub.ts → utils/use-scrub.ts} +2 -1
  61. package/src/utils/volume-utils.ts +39 -0
  62. package/src/utils/window-height.ts +19 -0
  63. package/src/vite-env.d.ts +1 -1
  64. package/tsconfig.json +4 -2
  65. package/tsconfig.node.json +9 -9
  66. package/build/chrome/bottom.d.ts +0 -20
  67. package/build/chrome/index.d.ts +0 -27
  68. package/build/chrome/overlay.d.ts +0 -9
  69. package/build/languages.d.ts +0 -260
  70. package/build/use-local-storage.d.ts +0 -6
  71. package/src/chrome/bottom.tsx +0 -651
  72. package/src/chrome/index.tsx +0 -199
  73. package/src/chrome/overlay.tsx +0 -104
  74. package/src/use-local-storage.ts +0 -32
  75. /package/src/{languages.ts → utils/languages.ts} +0 -0
  76. /package/src/{mp4box.ts → utils/mp4box.ts} +0 -0
@@ -0,0 +1,94 @@
1
+ import type { AnyActorSystem } from 'xstate/dist/declarations/src/system'
2
+ import type { AnyEventObject, CallbackActorLogic, CallbackActorRef, EventObject, NonReducibleUnknown } from 'xstate'
3
+
4
+ import PQueue from 'p-queue'
5
+ import { fromCallback } from 'xstate'
6
+
7
+ type Receiver<TEvent extends EventObject> = (listener: {
8
+ bivarianceHack(event: TEvent): void
9
+ }['bivarianceHack']) => void
10
+
11
+ export type CallbackLogicFunction<TEvent extends EventObject = AnyEventObject, TSentEvent extends EventObject = AnyEventObject, TInput = NonReducibleUnknown, TEmitted extends EventObject = EventObject> = ({ input, system, self, sendBack, receive, emit }: {
12
+ input: TInput
13
+ system: AnyActorSystem
14
+ self: CallbackActorRef<TEvent>
15
+ sendBack: (event: TSentEvent) => void
16
+ receive: Receiver<TEvent>
17
+ emit: (emitted: TEmitted) => void
18
+ }) => Promise<(() => void) | void>
19
+
20
+ type FromAsyncCallback = <TEvent extends EventObject, TInput = NonReducibleUnknown, TEmitted extends EventObject = EventObject>(callback: CallbackLogicFunction<TEvent, AnyEventObject, TInput, TEmitted>) => CallbackActorLogic<TEvent, TInput, TEmitted>
21
+
22
+ export const fromAsyncCallback =
23
+ ((callback: (...args: any[]) => Promise<() => any>) =>
24
+ fromCallback((...args: any[]) => {
25
+ const callbackPromise = callback(...args)
26
+ return () => {
27
+ callbackPromise
28
+ .then(callbackResult => callbackResult?.())
29
+ }
30
+ })) as FromAsyncCallback
31
+
32
+ export const getTimeRanges = (sourceBuffer: SourceBuffer) =>
33
+ Array(sourceBuffer.buffered.length)
34
+ .fill(undefined)
35
+ .map((_, index) => ({
36
+ index,
37
+ start: sourceBuffer.buffered.start(index),
38
+ end: sourceBuffer.buffered.end(index)
39
+ }))
40
+
41
+ const setupListeners = (sourceBuffer: SourceBuffer, resolve: (value: Event) => void, reject: (reason: Event) => void) => {
42
+ const updateEndListener = (ev: Event) => {
43
+ resolve(ev)
44
+ unregisterListeners()
45
+ }
46
+ const abortListener = (ev: Event) => {
47
+ resolve(ev)
48
+ unregisterListeners()
49
+ }
50
+ const errorListener = (ev: Event) => {
51
+ console.error(ev)
52
+ reject(ev)
53
+ unregisterListeners()
54
+ }
55
+ const unregisterListeners = () => {
56
+ sourceBuffer.removeEventListener('updateend', updateEndListener)
57
+ sourceBuffer.removeEventListener('abort', abortListener)
58
+ sourceBuffer.removeEventListener('error', errorListener)
59
+ }
60
+ sourceBuffer.addEventListener('updateend', updateEndListener, { once: true })
61
+ sourceBuffer.addEventListener('abort', abortListener, { once: true })
62
+ sourceBuffer.addEventListener('error', errorListener, { once: true })
63
+ }
64
+
65
+ export const updateSourceBuffer = (sourceBuffer: SourceBuffer) => {
66
+ const queue = new PQueue({ concurrency: 1 })
67
+
68
+ const appendBuffer = (buffer: ArrayBuffer) =>
69
+ queue.add(() =>
70
+ new Promise<Event>((resolve, reject) => {
71
+ setupListeners(sourceBuffer, resolve, reject)
72
+ sourceBuffer.appendBuffer(buffer)
73
+ })
74
+ )
75
+
76
+ const unbufferRange = async (start: number, end: number) =>
77
+ queue.add(() =>
78
+ new Promise((resolve, reject) => {
79
+ setupListeners(sourceBuffer, resolve, reject)
80
+ sourceBuffer.remove(start, end)
81
+ })
82
+ )
83
+
84
+ const updateTimestampOffset = (timestampOffset: number) =>
85
+ queue.add(() => {
86
+ sourceBuffer.timestampOffset = timestampOffset
87
+ })
88
+
89
+ return {
90
+ appendBuffer,
91
+ unbufferRange,
92
+ updateTimestampOffset
93
+ }
94
+ }
@@ -0,0 +1,19 @@
1
+ import { Actor, AnyActorLogic } from "xstate"
2
+
3
+ export const togglePlay = (
4
+ mediaActor: Actor<AnyActorLogic>,
5
+ isPaused: boolean,
6
+ duration: number | undefined,
7
+ currentTime: number
8
+ ) => {
9
+ if (!mediaActor) throw new Error('Media actor not found')
10
+ if (!duration) throw new Error('Duration not found')
11
+ if (duration === currentTime) {
12
+ mediaActor.send({ type: 'SET_TIME', value: 0 })
13
+ mediaActor.send({ type: 'PLAY' })
14
+ } else if (isPaused) {
15
+ mediaActor.send({ type: 'PLAY' })
16
+ } else {
17
+ mediaActor.send({ type: 'PAUSE' })
18
+ }
19
+ }
@@ -0,0 +1,9 @@
1
+ const colors = {
2
+ primary: '#EAEBEE',
3
+ secondary: '#D0D0D9',
4
+ hover: 'rgba(255, 255, 255, 0.13)',
5
+ borderPrimary: '#384F70',
6
+ backgroundTooltip: '#222222',
7
+ }
8
+
9
+ export default colors
@@ -0,0 +1,23 @@
1
+ import { createContext } from 'react'
2
+
3
+ export type DownloadedRange =
4
+ // | {
5
+ // startTimestamp: number
6
+ // endTimestamp: number
7
+ // }
8
+ | {
9
+ startByteOffset: number
10
+ endByteOffset: number
11
+ }
12
+
13
+ export type MediaPlayerContextType = {
14
+ videoElement?: HTMLVideoElement
15
+ title?: string
16
+ subtitle?: string
17
+ size?: number
18
+ downloadedRanges?: DownloadedRange[]
19
+ hideUI: boolean
20
+ update: (context: Omit<MediaPlayerContextType, 'update'>) => void
21
+ }
22
+
23
+ export const MediaPlayerContext = createContext<MediaPlayerContextType>({} as MediaPlayerContextType)
@@ -0,0 +1,156 @@
1
+ export const fonts = {
2
+ headings: {
3
+ large: `
4
+ font-weight: 600;
5
+ font-size: 2.8rem;
6
+ line-height: 3.4rem;
7
+ @media (min-width: 960px) {
8
+ font-size: 3.4rem;
9
+ line-height: 4.1rem;
10
+ }
11
+ `,
12
+ medium: `
13
+ font-weight: 600;
14
+ font-size: 2.4rem;
15
+ line-height: 2.9rem;
16
+ @media (min-width: 960px) {
17
+ font-size: 2.8rem;
18
+ line-height: 3.4rem;
19
+ }
20
+ `,
21
+ small: `
22
+ font-weight: 500;
23
+ font-size: 1.8rem;
24
+ line-height: 1.9rem;
25
+ @media (min-width: 960px) {
26
+ font-size: 1.8rem;
27
+ line-height: 2.2rem;
28
+ }
29
+ `,
30
+ extraSmall: `
31
+ font-weight: 500;
32
+ font-size: 1.4rem;
33
+ line-height: 1.7rem;
34
+ @media (min-width: 960px) {
35
+ font-size: 1.6rem;
36
+ line-height: 1.9rem;
37
+ }
38
+ `
39
+ },
40
+ bLarge: {
41
+ bold: `
42
+ font-weight: 600;
43
+ font-size: 1.4rem;
44
+ line-height: 2rem;
45
+ @media (min-width: 960px) {
46
+ font-size: 1.6rem;
47
+ line-height: 2.2rem;
48
+ }
49
+ `,
50
+ medium: `
51
+ font-weight: 500;
52
+ font-size: 1.4rem;
53
+ line-height: 2rem;
54
+ @media (min-width: 960px) {
55
+ font-size: 1.6rem;
56
+ line-height: 2.2rem;
57
+ }
58
+ `,
59
+ regular: `
60
+ font-weight: 400;
61
+ font-size: 1.4rem;
62
+ line-height: 2rem;
63
+ @media (min-width: 960px) {
64
+ font-size: 1.6rem;
65
+ line-height: 2.2rem;
66
+ }
67
+ `,
68
+ },
69
+ bMedium: {
70
+ bold: `
71
+ font-weight: 600;
72
+ font-size: 1.2rem;
73
+ line-height: 1.7rem;
74
+ @media (min-width: 960px) {
75
+ font-size: 1.4rem;
76
+ line-height: 2rem;
77
+ }
78
+ `,
79
+ medium: `
80
+ font-weight: 500;
81
+ font-size: 1.2rem;
82
+ line-height: 1.7rem;
83
+ @media (min-width: 960px) {
84
+ font-size: 1.4rem;
85
+ line-height: 2rem;
86
+ }
87
+ `,
88
+ regular: `
89
+ font-weight: 400;
90
+ font-size: 1.2rem;
91
+ line-height: 1.7rem;
92
+ @media (min-width: 960px) {
93
+ font-size: 1.4rem;
94
+ line-height: 2rem;
95
+ }
96
+ `,
97
+ },
98
+ bSmall: {
99
+ bold: `
100
+ font-weight: 600;
101
+ font-size: 1rem;
102
+ line-height: 1.4rem;
103
+ @media (min-width: 960px) {
104
+ font-size: 1.2rem;
105
+ line-height: 1.7rem;
106
+ }
107
+ `,
108
+ medium: `
109
+ font-weight: 500;
110
+ font-size: 1rem;
111
+ line-height: 1.4rem;
112
+ @media (min-width: 960px) {
113
+ font-size: 1.2rem;
114
+ line-height: 1.7rem;
115
+ }
116
+ `,
117
+ regular: `
118
+ font-weight: 400;
119
+ font-size: 1rem;
120
+ line-height: 1.4rem;
121
+ @media (min-width: 960px) {
122
+ font-size: 1.2rem;
123
+ line-height: 1.7rem;
124
+ }
125
+ `,
126
+ },
127
+ bExtraSmall: {
128
+ bold: `
129
+ font-weight: 600;
130
+ font-size: 0.8rem;
131
+ line-height: 1.1rem;
132
+ @media (min-width: 960px) {
133
+ font-size: 1rem;
134
+ line-height: 1.4rem;
135
+ }
136
+ `,
137
+ medium: `
138
+ font-weight: 500;
139
+ font-size: 0.8rem;
140
+ line-height: 1.1rem;
141
+ @media (min-width: 960px) {
142
+ font-size: 1rem;
143
+ line-height: 1.4rem;
144
+ }
145
+ `,
146
+ regular: `
147
+ font-weight: 400;
148
+ font-size: 0.8rem;
149
+ line-height: 1.1rem;
150
+ @media (min-width: 960px) {
151
+ font-size: 1rem;
152
+ line-height: 1.4rem;
153
+ }
154
+ `,
155
+ },
156
+ }
@@ -1,11 +1,3 @@
1
- export type Chunk = {
2
- offset: number
3
- buffer: Uint8Array
4
- pts: number
5
- duration: number
6
- pos: number
7
- buffered: boolean
8
- }
9
1
 
10
2
  export function debounceImmediateAndLatest<T extends (...args: any[]) => any>(
11
3
  wait: number,
@@ -40,7 +32,7 @@ export function debounceImmediateAndLatest<T extends (...args: any[]) => any>(
40
32
  return debouncedFunction as T;
41
33
  }
42
34
 
43
- export const queuedDebounceWithLastCall = <T2 extends any[], T extends (...args: T2) => any>(time: number, func: T) => {
35
+ export const queuedThrottleWithLastCall = <T2 extends any[], T extends (...args: T2) => any>(time: number, func: T) => {
44
36
  let runningFunction: Promise<ReturnType<T>> | undefined
45
37
  let lastCall: Promise<ReturnType<T>> | undefined
46
38
  let lastCallArguments: T2 | undefined
@@ -117,22 +109,6 @@ export const queuedDebounceWithLastCall = <T2 extends any[], T extends (...args:
117
109
  }
118
110
  }
119
111
 
120
- const getTimeRanges = (sourceBuffer: SourceBuffer) =>
121
- Array(sourceBuffer.buffered.length)
122
- .fill(undefined)
123
- .map((_, index) => ({
124
- index,
125
- start: sourceBuffer.buffered.start(index),
126
- end: sourceBuffer.buffered.end(index)
127
- }))
128
-
129
- const getTimeRange =
130
- (sourceBuffer: SourceBuffer) =>
131
- (time: number) =>
132
- getTimeRanges(sourceBuffer)
133
- .find(({ start, end }) => time >= start && time <= end)
134
-
135
-
136
112
  // todo: reimplement this into a ReadableByteStream https://web.dev/streams/ once Safari gets support
137
113
  export const toStreamChunkSize = (SIZE: number) => (stream: ReadableStream) =>
138
114
  new ReadableStream<Uint8Array>({
@@ -176,7 +152,7 @@ export const toStreamChunkSize = (SIZE: number) => (stream: ReadableStream) =>
176
152
  if (done) controller.close()
177
153
  },
178
154
  cancel() {
179
- this.reader!.cancel()
155
+ this.reader?.cancel()
180
156
  this.leftOverData = undefined
181
157
  }
182
158
  } as UnderlyingDefaultSource<Uint8Array> & {
@@ -0,0 +1,16 @@
1
+ export const formatTime = (time: number | undefined): string => {
2
+ if (time === undefined) return '0:00'
3
+
4
+ const hours = Math.floor(time / 3600)
5
+ const minutes = Math.floor((time % 3600) / 60)
6
+ const seconds = Math.floor(time % 60)
7
+ // If there are hours, include them in the format
8
+ if (hours > 0) {
9
+ return `${hours}:${minutes < 10 ? '0' : ''}${minutes}:${seconds < 10 ? '0' : ''}${seconds}`
10
+ }
11
+ return `${minutes}:${seconds < 10 ? '0' : ''}${seconds}`
12
+ }
13
+
14
+ export const formatMediaTime = (currentTime: number, duration: number | undefined): string => {
15
+ return `${formatTime(currentTime)} / ${formatTime(duration)}`
16
+ }
@@ -0,0 +1,30 @@
1
+ import { useEffect, useState } from 'react'
2
+
3
+ export const useLocalStorage = <T,>(name: string, defaultValue?: T) => {
4
+ const [storageValue, setStorageValue] = useState(() => localStorage.getItem(name) ?? defaultValue)
5
+
6
+ const updateStorage = (newValue: string) => {
7
+ localStorage.setItem(name, newValue)
8
+ setStorageValue(newValue)
9
+ window.dispatchEvent(new Event('storage'))
10
+ }
11
+
12
+ useEffect(() => {
13
+ const syncLocalStorage = () => {
14
+ const item = localStorage.getItem(name)
15
+ setStorageValue(item ?? defaultValue)
16
+ }
17
+
18
+ window.addEventListener('storage', syncLocalStorage)
19
+ return () => {
20
+ window.removeEventListener('storage', syncLocalStorage)
21
+ }
22
+ }, [name])
23
+
24
+ return [storageValue, updateStorage] as const
25
+ }
26
+
27
+ export default useLocalStorage
28
+
29
+ export type mediaMutedType = 'true' | 'false' | undefined
30
+
@@ -34,6 +34,7 @@ export default ({ ref, defaultValue }: { ref: RefObject<HTMLElement>, defaultVal
34
34
  return {
35
35
  value,
36
36
  scrubbing,
37
- scrub
37
+ scrub,
38
+ setValue
38
39
  }
39
40
  }
@@ -0,0 +1,39 @@
1
+ // Constants for logarithmic scaling
2
+ const MIN_VOLUME = 0.0001 // Avoid zero which would give -Infinity when taking log
3
+ const MAX_VOLUME = 1.0
4
+
5
+ // Defines how "curved" the logarithmic response is
6
+ // Higher values = more dramatic volume change at the low end
7
+ export const VOLUME_EXPONENT = 2.0
8
+
9
+ /**
10
+ * Converts a linear slider value (0-1) to logarithmic volume scale
11
+ * Uses formula: volume = minVolume * (maxVolume/minVolume)^position
12
+ *
13
+ * @param linearValue Linear slider position (0-1)
14
+ * @returns Logarithmic volume value (0-1)
15
+ */
16
+ export const linearToLogVolume = (linearValue: number): number => {
17
+ // Ensure value is within range
18
+ const normalizedLinear = Math.max(MIN_VOLUME, Math.min(MAX_VOLUME, linearValue))
19
+
20
+ // Calculate using the formula: volume = minVolume * (maxVolume/minVolume)^position
21
+ // We can also use a simpler formula: Math.pow(normalizedLinear, VOLUME_EXPONENT)
22
+ // Which gives a good perceptual curve with proper scaling
23
+ return Math.pow(normalizedLinear, VOLUME_EXPONENT)
24
+ }
25
+
26
+ /**
27
+ * Converts a logarithmic volume (0-1) back to linear slider position (0-1)
28
+ * Inverse of the logarithmic formula
29
+ *
30
+ * @param logVolume Logarithmic volume (0-1)
31
+ * @returns Linear slider position (0-1)
32
+ */
33
+ export const logToLinearVolume = (logVolume: number): number => {
34
+ // Ensure value is within range
35
+ const normalizedLog = Math.max(MIN_VOLUME, Math.min(MAX_VOLUME, logVolume))
36
+
37
+ // Inverse of our simplified formula
38
+ return Math.pow(normalizedLog, MAX_VOLUME/VOLUME_EXPONENT)
39
+ }
@@ -0,0 +1,19 @@
1
+ import { useEffect, useState } from 'react'
2
+
3
+ const useWindowSize = () => {
4
+ const [windowHeight, setWindowHeight] = useState(window.innerHeight)
5
+ const [windowWidth, setWindowWidth] = useState(window.innerWidth)
6
+ useEffect(() => {
7
+ const handleResize = () => {
8
+ setWindowHeight(window.innerHeight)
9
+ setWindowWidth(window.innerWidth)
10
+ }
11
+
12
+ window.addEventListener('resize', handleResize)
13
+
14
+ return () => { window.removeEventListener('resize', handleResize) }
15
+ }, [])
16
+ return [windowHeight, windowWidth]
17
+ }
18
+
19
+ export default useWindowSize
package/src/vite-env.d.ts CHANGED
@@ -1 +1 @@
1
- /// <reference types="vite/client" />
1
+ /// <reference types="vite/client" />
package/tsconfig.json CHANGED
@@ -18,9 +18,11 @@
18
18
  "emitDeclarationOnly": true,
19
19
  "jsx": "react-jsx",
20
20
  "paths": {
21
- "mp4box": ["./src/mp4box.ts"]
22
- }
21
+ "mp4box": ["./src/utils/mp4box.ts"]
22
+ },
23
+ "types": []
23
24
  },
24
25
  "include": ["src"],
26
+ "exclude": ["node_modules"],
25
27
  "references": [{ "path": "./tsconfig.node.json" }]
26
28
  }
@@ -1,9 +1,9 @@
1
- {
2
- "compilerOptions": {
3
- "composite": true,
4
- "module": "ESNext",
5
- "moduleResolution": "Node",
6
- "allowSyntheticDefaultImports": true
7
- },
8
- "include": ["vite.config.ts"]
9
- }
1
+ {
2
+ "compilerOptions": {
3
+ "composite": true,
4
+ "module": "ESNext",
5
+ "moduleResolution": "Node",
6
+ "allowSyntheticDefaultImports": true
7
+ },
8
+ "include": ["vite.config.ts"]
9
+ }
@@ -1,20 +0,0 @@
1
- import type { Dispatch, HTMLAttributes, SetStateAction } from 'react';
2
- import type { ChromeOptions } from '.';
3
- import type { FKNVideoControl, Subtitle, TransmuxError } from '..';
4
- export type BottomOptions = {
5
- duration?: number;
6
- currentTime?: number;
7
- togglePlay: () => void;
8
- isSubtitleMenuHidden: boolean;
9
- setIsSubtitleMenuHidden: Dispatch<SetStateAction<boolean>>;
10
- isErrorMenuHidden: boolean;
11
- setIsErrorMenuHidden: Dispatch<SetStateAction<boolean>>;
12
- setCurrentSubtitleTrack: Dispatch<SetStateAction<number | undefined>>;
13
- isFullscreen: boolean;
14
- toggleFullscreen: () => void;
15
- subtitleTrack: Subtitle | undefined;
16
- errors: TransmuxError[];
17
- customControls?: FKNVideoControl[];
18
- } & Pick<ChromeOptions, 'seek' | 'setVolume' | 'loadedTime' | 'isPlaying' | 'tracks' | 'pictureInPicture'> & HTMLAttributes<HTMLDivElement>;
19
- declare const _default: ({ duration, currentTime, togglePlay, seek, setVolume, isSubtitleMenuHidden, setIsSubtitleMenuHidden, isErrorMenuHidden, setIsErrorMenuHidden, setCurrentSubtitleTrack, loadedTime, isPlaying, tracks, isFullscreen, toggleFullscreen, subtitleTrack, pictureInPicture, errors, customControls, ...rest }: BottomOptions) => import("react/jsx-runtime").JSX.Element;
20
- export default _default;
@@ -1,27 +0,0 @@
1
- import type { HTMLAttributes, MutableRefObject, ReactNode } from 'react';
2
- import type { Attachment, FKNVideoControl, Subtitle, TransmuxError } from '..';
3
- export type ChromeOptions = {
4
- publicPath: string;
5
- customOverlay?: ReactNode;
6
- isPlaying?: boolean;
7
- loading?: boolean;
8
- duration?: number;
9
- loadedTime?: [number, number];
10
- currentTime?: number;
11
- pictureInPicture: () => void;
12
- fullscreen: () => void;
13
- play: () => void;
14
- seek: (time: number) => void;
15
- getVolume: () => number | undefined;
16
- setVolume: (volume: number) => void;
17
- attachments: Attachment[] | undefined;
18
- tracks: Subtitle[];
19
- video: MutableRefObject<HTMLVideoElement | undefined>;
20
- errors: TransmuxError[];
21
- customControls?: FKNVideoControl[];
22
- libassWorkerUrl: string;
23
- wasmUrl: string;
24
- needsInitialInteraction?: boolean;
25
- } & HTMLAttributes<HTMLDivElement>;
26
- declare const _default: ({ customOverlay, publicPath, isPlaying, loading, duration, loadedTime, currentTime, pictureInPicture, fullscreen, play, seek, getVolume, setVolume, attachments, tracks, video, errors, customControls, libassWorkerUrl, wasmUrl, needsInitialInteraction, ...rest }: ChromeOptions) => import("react/jsx-runtime").JSX.Element;
27
- export default _default;
@@ -1,9 +0,0 @@
1
- import type { ClassAttributes } from 'react';
2
- export type OverlayOptions = {
3
- loading?: boolean;
4
- togglePlay: (ev: any) => void;
5
- setCanvasRef: ClassAttributes<HTMLCanvasElement>['ref'];
6
- needsInitialInteraction?: boolean;
7
- };
8
- declare const _default: ({ loading, needsInitialInteraction, togglePlay, setCanvasRef }: OverlayOptions) => import("react/jsx-runtime").JSX.Element;
9
- export default _default;