@banou/media-player 0.6.0 → 0.6.2

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 (37) hide show
  1. package/README.md +6 -6
  2. package/package.json +51 -51
  3. package/src/assets/picture-in-picture.svg +5 -5
  4. package/src/components/chrome.tsx +95 -95
  5. package/src/components/control-bar.tsx +333 -333
  6. package/src/components/overlay.tsx +91 -91
  7. package/src/components/playback-slider.tsx +174 -174
  8. package/src/components/progress-bar.tsx +251 -251
  9. package/src/components/settings.tsx +321 -321
  10. package/src/components/sound.tsx +100 -100
  11. package/src/components/tooltip-display.tsx +83 -83
  12. package/src/components/volume-slider.tsx +156 -156
  13. package/src/index.tsx +195 -195
  14. package/src/main.tsx +169 -169
  15. package/src/state-machines/data-source.ts +84 -84
  16. package/src/state-machines/index.ts +5 -5
  17. package/src/state-machines/media-properties.ts +82 -82
  18. package/src/state-machines/media-source.ts +129 -129
  19. package/src/state-machines/media.ts +255 -255
  20. package/src/state-machines/subtitles.ts +285 -285
  21. package/src/state-machines/thumbnails.ts +123 -123
  22. package/src/state-machines/utils.ts +94 -94
  23. package/src/utils/actor-utils.ts +19 -19
  24. package/src/utils/colors.ts +8 -8
  25. package/src/utils/context.ts +23 -23
  26. package/src/utils/fonts.ts +159 -159
  27. package/src/utils/index.ts +229 -229
  28. package/src/utils/languages.ts +262 -262
  29. package/src/utils/mp4box.ts +74 -74
  30. package/src/utils/time.ts +15 -15
  31. package/src/utils/use-local-storage.ts +30 -30
  32. package/src/utils/use-scrub.ts +40 -40
  33. package/src/utils/volume-utils.ts +39 -39
  34. package/src/utils/window-height.ts +19 -19
  35. package/src/vite-env.d.ts +1 -1
  36. package/tsconfig.json +28 -28
  37. package/tsconfig.node.json +9 -9
@@ -1,229 +1,229 @@
1
-
2
- export function debounceImmediateAndLatest<T extends (...args: any[]) => any>(
3
- wait: number,
4
- func: T
5
- ): T {
6
- let timeoutId: ReturnType<typeof setTimeout> | null = null;
7
- let lastArgs: any[] | null = null;
8
-
9
- const debouncedFunction = function(...args: any[]) {
10
- // @ts-expect-error
11
- const context = this;
12
-
13
- if (timeoutId === null) {
14
- // Call immediately on the first call
15
- func.apply(context, args);
16
- } else {
17
- // Store the latest arguments for the last call
18
- lastArgs = args;
19
- }
20
-
21
- clearTimeout(timeoutId as ReturnType<typeof setTimeout>);
22
-
23
- timeoutId = setTimeout(() => {
24
- if (lastArgs) {
25
- func.apply(context, lastArgs);
26
- lastArgs = null;
27
- }
28
- timeoutId = null;
29
- }, wait);
30
- };
31
-
32
- return debouncedFunction as T;
33
- }
34
-
35
- export const queuedThrottleWithLastCall = <T2 extends any[], T extends (...args: T2) => any>(time: number, func: T) => {
36
- let runningFunction: Promise<ReturnType<T>> | undefined
37
- let lastCall: Promise<ReturnType<T>> | undefined
38
- let lastCallArguments: T2 | undefined
39
-
40
- const checkForLastCall = (
41
- timeStart: number,
42
- resolve: (value: ReturnType<T> | PromiseLike<ReturnType<T>>) => void,
43
- reject: (reason?: any) => void
44
- ) =>
45
- (result: ReturnType<T>) => {
46
- const currentTime = performance.now()
47
- setTimeout(() => {
48
- if (!lastCallArguments) {
49
- runningFunction = undefined
50
- lastCall = undefined
51
- return
52
- }
53
- const funcResult = (async () => (func(...lastCallArguments)))()
54
- lastCallArguments = undefined
55
- funcResult
56
- .then(resolve)
57
- .catch((err) => {
58
- console.error(err)
59
- reject(err)
60
- })
61
-
62
- let _resolve: (value: ReturnType<T> | PromiseLike<ReturnType<T>>) => void
63
- let _reject: (reason?: any) => void
64
- lastCall = new Promise((resolve, reject) => {
65
- _resolve = resolve
66
- _reject = reject
67
- })
68
-
69
- runningFunction =
70
- funcResult
71
- // @ts-ignore
72
- .then(checkForLastCall(currentTime, _resolve, _reject))
73
- // @ts-ignore
74
- .catch(err => {
75
- console.error(err)
76
- return checkForLastCall(timeStart, _resolve, _reject)(err)
77
- })
78
- }, time - (currentTime - timeStart))
79
- return result
80
- }
81
-
82
- return (...args: Parameters<T>) => {
83
- lastCallArguments = args
84
- if (!runningFunction) {
85
- const timeStart = performance.now()
86
- const funcResult = (async () => (func(...args)))()
87
- lastCallArguments = undefined
88
- let _resolve: (value: ReturnType<T> | PromiseLike<ReturnType<T>>) => void
89
- let _reject: (reason?: any) => void
90
- lastCall = new Promise((resolve, reject) => {
91
- _resolve = resolve
92
- _reject = reject
93
- })
94
-
95
- runningFunction =
96
- funcResult
97
- // @ts-ignore
98
- .then(checkForLastCall(timeStart, _resolve, _reject))
99
- // @ts-ignore
100
- .catch(err => {
101
- console.error(err)
102
- return checkForLastCall(timeStart, _resolve, _reject)(err)
103
- })
104
-
105
- return funcResult
106
- } else {
107
- return lastCall
108
- }
109
- }
110
- }
111
-
112
- // todo: reimplement this into a ReadableByteStream https://web.dev/streams/ once Safari gets support
113
- export const toStreamChunkSize = (SIZE: number) => (stream: ReadableStream) =>
114
- new ReadableStream<Uint8Array>({
115
- reader: undefined,
116
- leftOverData: undefined,
117
- start() {
118
- this.reader = stream.getReader()
119
- },
120
- async pull(controller) {
121
- const { leftOverData }: { leftOverData: Uint8Array | undefined } = this
122
-
123
- const accumulate = async ({ buffer = new Uint8Array(SIZE), currentSize = 0 } = {}): Promise<{ buffer?: Uint8Array, currentSize?: number, done: boolean }> => {
124
- const { value: newBuffer, done } = await this.reader!.read()
125
- if (currentSize === 0 && leftOverData) {
126
- buffer.set(leftOverData)
127
- currentSize += leftOverData.byteLength
128
- this.leftOverData = undefined
129
- }
130
-
131
- if (done) {
132
- const finalResult = { buffer: buffer.slice(0, currentSize), currentSize, done }
133
- this.reader = undefined
134
- this.leftOverData = undefined
135
- return finalResult
136
- }
137
-
138
- let newSize
139
- const slicedBuffer = newBuffer.slice(0, SIZE - currentSize)
140
- newSize = currentSize + slicedBuffer.byteLength
141
- buffer.set(slicedBuffer, currentSize)
142
-
143
- if (newSize === SIZE) {
144
- this.leftOverData = newBuffer.slice(SIZE - currentSize)
145
- return { buffer, currentSize: newSize, done: false }
146
- }
147
-
148
- return accumulate({ buffer, currentSize: newSize })
149
- }
150
- const { buffer, done } = await accumulate()
151
- if (buffer?.byteLength) controller.enqueue(buffer)
152
- if (done) controller.close()
153
- },
154
- cancel() {
155
- this.reader?.cancel()
156
- this.leftOverData = undefined
157
- }
158
- } as UnderlyingDefaultSource<Uint8Array> & {
159
- reader: ReadableStreamDefaultReader<Uint8Array> | undefined
160
- leftOverData: Uint8Array | undefined
161
- })
162
-
163
- export const toBufferedStream = (SIZE: number) => (stream: ReadableStream) =>
164
- new ReadableStream<Uint8Array>({
165
- buffers: [],
166
- currentPullPromise: undefined,
167
- reader: undefined,
168
- leftOverData: undefined,
169
- start() {
170
- this.reader = stream.getReader()
171
- },
172
- async pull(controller) {
173
- const pull = async () => {
174
- if (this.buffers.length >= SIZE) return
175
- this.currentPullPromise = this.reader!.read()
176
- const { value: newBuffer, done } = await this.currentPullPromise
177
- this.currentPullPromise = undefined
178
- if (done) {
179
- try {
180
- for (const buffer of this.buffers) controller.enqueue(buffer)
181
- controller.close()
182
- } catch (err) {
183
- // console.error(err)
184
- }
185
- return
186
- }
187
- this.buffers.push(newBuffer)
188
- return newBuffer
189
- }
190
-
191
- const tryToBuffer = async (): Promise<void> => {
192
- if (this.buffers.length >= SIZE) return
193
-
194
- if (this.buffers.length === 0) {
195
- const buffer = await pull()
196
- if (!buffer) return
197
- return tryToBuffer()
198
- } else {
199
- pull().then((buffer) => {
200
- if (!buffer) return
201
- tryToBuffer()
202
- })
203
- }
204
- }
205
-
206
- await tryToBuffer()
207
- try {
208
- controller.enqueue(this.buffers.shift())
209
- tryToBuffer()
210
- } catch(err) {
211
- if (!(
212
- err instanceof TypeError && (
213
- err.message === 'ReadableStreamDefaultController.enqueue: Cannot enqueue into a stream that has already been requested to close.' ||
214
- err.message === `Failed to execute 'enqueue' on 'ReadableStreamDefaultController': Cannot enqueue a chunk into a readable stream that is closed or has been requested to be closed`
215
- )
216
- )) {
217
- throw err
218
- }
219
- }
220
- },
221
- cancel() {
222
- this.reader!.cancel()
223
- }
224
- } as UnderlyingDefaultSource<Uint8Array> & {
225
- reader: ReadableStreamDefaultReader<Uint8Array> | undefined
226
- leftOverData: Uint8Array | undefined
227
- buffers: Uint8Array[]
228
- currentPullPromise: Promise<ReadableStreamReadResult<Uint8Array>> | undefined
229
- })
1
+
2
+ export function debounceImmediateAndLatest<T extends (...args: any[]) => any>(
3
+ wait: number,
4
+ func: T
5
+ ): T {
6
+ let timeoutId: ReturnType<typeof setTimeout> | null = null;
7
+ let lastArgs: any[] | null = null;
8
+
9
+ const debouncedFunction = function(...args: any[]) {
10
+ // @ts-expect-error
11
+ const context = this;
12
+
13
+ if (timeoutId === null) {
14
+ // Call immediately on the first call
15
+ func.apply(context, args);
16
+ } else {
17
+ // Store the latest arguments for the last call
18
+ lastArgs = args;
19
+ }
20
+
21
+ clearTimeout(timeoutId as ReturnType<typeof setTimeout>);
22
+
23
+ timeoutId = setTimeout(() => {
24
+ if (lastArgs) {
25
+ func.apply(context, lastArgs);
26
+ lastArgs = null;
27
+ }
28
+ timeoutId = null;
29
+ }, wait);
30
+ };
31
+
32
+ return debouncedFunction as T;
33
+ }
34
+
35
+ export const queuedThrottleWithLastCall = <T2 extends any[], T extends (...args: T2) => any>(time: number, func: T) => {
36
+ let runningFunction: Promise<ReturnType<T>> | undefined
37
+ let lastCall: Promise<ReturnType<T>> | undefined
38
+ let lastCallArguments: T2 | undefined
39
+
40
+ const checkForLastCall = (
41
+ timeStart: number,
42
+ resolve: (value: ReturnType<T> | PromiseLike<ReturnType<T>>) => void,
43
+ reject: (reason?: any) => void
44
+ ) =>
45
+ (result: ReturnType<T>) => {
46
+ const currentTime = performance.now()
47
+ setTimeout(() => {
48
+ if (!lastCallArguments) {
49
+ runningFunction = undefined
50
+ lastCall = undefined
51
+ return
52
+ }
53
+ const funcResult = (async () => (func(...lastCallArguments)))()
54
+ lastCallArguments = undefined
55
+ funcResult
56
+ .then(resolve)
57
+ .catch((err) => {
58
+ console.error(err)
59
+ reject(err)
60
+ })
61
+
62
+ let _resolve: (value: ReturnType<T> | PromiseLike<ReturnType<T>>) => void
63
+ let _reject: (reason?: any) => void
64
+ lastCall = new Promise((resolve, reject) => {
65
+ _resolve = resolve
66
+ _reject = reject
67
+ })
68
+
69
+ runningFunction =
70
+ funcResult
71
+ // @ts-ignore
72
+ .then(checkForLastCall(currentTime, _resolve, _reject))
73
+ // @ts-ignore
74
+ .catch(err => {
75
+ console.error(err)
76
+ return checkForLastCall(timeStart, _resolve, _reject)(err)
77
+ })
78
+ }, time - (currentTime - timeStart))
79
+ return result
80
+ }
81
+
82
+ return (...args: Parameters<T>) => {
83
+ lastCallArguments = args
84
+ if (!runningFunction) {
85
+ const timeStart = performance.now()
86
+ const funcResult = (async () => (func(...args)))()
87
+ lastCallArguments = undefined
88
+ let _resolve: (value: ReturnType<T> | PromiseLike<ReturnType<T>>) => void
89
+ let _reject: (reason?: any) => void
90
+ lastCall = new Promise((resolve, reject) => {
91
+ _resolve = resolve
92
+ _reject = reject
93
+ })
94
+
95
+ runningFunction =
96
+ funcResult
97
+ // @ts-ignore
98
+ .then(checkForLastCall(timeStart, _resolve, _reject))
99
+ // @ts-ignore
100
+ .catch(err => {
101
+ console.error(err)
102
+ return checkForLastCall(timeStart, _resolve, _reject)(err)
103
+ })
104
+
105
+ return funcResult
106
+ } else {
107
+ return lastCall
108
+ }
109
+ }
110
+ }
111
+
112
+ // todo: reimplement this into a ReadableByteStream https://web.dev/streams/ once Safari gets support
113
+ export const toStreamChunkSize = (SIZE: number) => (stream: ReadableStream) =>
114
+ new ReadableStream<Uint8Array>({
115
+ reader: undefined,
116
+ leftOverData: undefined,
117
+ start() {
118
+ this.reader = stream.getReader()
119
+ },
120
+ async pull(controller) {
121
+ const { leftOverData }: { leftOverData: Uint8Array | undefined } = this
122
+
123
+ const accumulate = async ({ buffer = new Uint8Array(SIZE), currentSize = 0 } = {}): Promise<{ buffer?: Uint8Array, currentSize?: number, done: boolean }> => {
124
+ const { value: newBuffer, done } = await this.reader!.read()
125
+ if (currentSize === 0 && leftOverData) {
126
+ buffer.set(leftOverData)
127
+ currentSize += leftOverData.byteLength
128
+ this.leftOverData = undefined
129
+ }
130
+
131
+ if (done) {
132
+ const finalResult = { buffer: buffer.slice(0, currentSize), currentSize, done }
133
+ this.reader = undefined
134
+ this.leftOverData = undefined
135
+ return finalResult
136
+ }
137
+
138
+ let newSize
139
+ const slicedBuffer = newBuffer.slice(0, SIZE - currentSize)
140
+ newSize = currentSize + slicedBuffer.byteLength
141
+ buffer.set(slicedBuffer, currentSize)
142
+
143
+ if (newSize === SIZE) {
144
+ this.leftOverData = newBuffer.slice(SIZE - currentSize)
145
+ return { buffer, currentSize: newSize, done: false }
146
+ }
147
+
148
+ return accumulate({ buffer, currentSize: newSize })
149
+ }
150
+ const { buffer, done } = await accumulate()
151
+ if (buffer?.byteLength) controller.enqueue(buffer)
152
+ if (done) controller.close()
153
+ },
154
+ cancel() {
155
+ this.reader?.cancel()
156
+ this.leftOverData = undefined
157
+ }
158
+ } as UnderlyingDefaultSource<Uint8Array> & {
159
+ reader: ReadableStreamDefaultReader<Uint8Array> | undefined
160
+ leftOverData: Uint8Array | undefined
161
+ })
162
+
163
+ export const toBufferedStream = (SIZE: number) => (stream: ReadableStream) =>
164
+ new ReadableStream<Uint8Array>({
165
+ buffers: [],
166
+ currentPullPromise: undefined,
167
+ reader: undefined,
168
+ leftOverData: undefined,
169
+ start() {
170
+ this.reader = stream.getReader()
171
+ },
172
+ async pull(controller) {
173
+ const pull = async () => {
174
+ if (this.buffers.length >= SIZE) return
175
+ this.currentPullPromise = this.reader!.read()
176
+ const { value: newBuffer, done } = await this.currentPullPromise
177
+ this.currentPullPromise = undefined
178
+ if (done) {
179
+ try {
180
+ for (const buffer of this.buffers) controller.enqueue(buffer)
181
+ controller.close()
182
+ } catch (err) {
183
+ // console.error(err)
184
+ }
185
+ return
186
+ }
187
+ this.buffers.push(newBuffer)
188
+ return newBuffer
189
+ }
190
+
191
+ const tryToBuffer = async (): Promise<void> => {
192
+ if (this.buffers.length >= SIZE) return
193
+
194
+ if (this.buffers.length === 0) {
195
+ const buffer = await pull()
196
+ if (!buffer) return
197
+ return tryToBuffer()
198
+ } else {
199
+ pull().then((buffer) => {
200
+ if (!buffer) return
201
+ tryToBuffer()
202
+ })
203
+ }
204
+ }
205
+
206
+ await tryToBuffer()
207
+ try {
208
+ controller.enqueue(this.buffers.shift())
209
+ tryToBuffer()
210
+ } catch(err) {
211
+ if (!(
212
+ err instanceof TypeError && (
213
+ err.message === 'ReadableStreamDefaultController.enqueue: Cannot enqueue into a stream that has already been requested to close.' ||
214
+ err.message === `Failed to execute 'enqueue' on 'ReadableStreamDefaultController': Cannot enqueue a chunk into a readable stream that is closed or has been requested to be closed`
215
+ )
216
+ )) {
217
+ throw err
218
+ }
219
+ }
220
+ },
221
+ cancel() {
222
+ this.reader!.cancel()
223
+ }
224
+ } as UnderlyingDefaultSource<Uint8Array> & {
225
+ reader: ReadableStreamDefaultReader<Uint8Array> | undefined
226
+ leftOverData: Uint8Array | undefined
227
+ buffers: Uint8Array[]
228
+ currentPullPromise: Promise<ReadableStreamReadResult<Uint8Array>> | undefined
229
+ })