@banou/media-player 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -0
- package/build/chrome/bottom.d.ts +20 -0
- package/build/chrome/index.d.ts +26 -0
- package/build/chrome/overlay.d.ts +9 -0
- package/build/index.d.ts +48 -0
- package/build/index.js +2725 -0
- package/build/languages.d.ts +260 -0
- package/build/main.d.ts +1 -0
- package/build/mp4box.d.ts +61 -0
- package/build/use-local-storage.d.ts +6 -0
- package/build/use-scrub.d.ts +10 -0
- package/build/utils.d.ts +13 -0
- package/package.json +49 -0
- package/src/chrome/bottom.tsx +651 -0
- package/src/chrome/index.tsx +197 -0
- package/src/chrome/overlay.tsx +104 -0
- package/src/index.tsx +597 -0
- package/src/languages.ts +262 -0
- package/src/main.tsx +187 -0
- package/src/mp4box.ts +74 -0
- package/src/use-local-storage.ts +32 -0
- package/src/use-scrub.ts +39 -0
- package/src/utils.ts +385 -0
- package/src/vite-env.d.ts +1 -0
- package/tsconfig.json +26 -0
- package/tsconfig.node.json +9 -0
package/src/utils.ts
ADDED
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
export type Chunk = {
|
|
2
|
+
offset: number
|
|
3
|
+
buffer: Uint8Array
|
|
4
|
+
pts: number
|
|
5
|
+
duration: number
|
|
6
|
+
pos: number
|
|
7
|
+
buffered: boolean
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const queuedDebounceWithLastCall = <T2 extends any[], T extends (...args: T2) => any>(time: number, func: T) => {
|
|
11
|
+
let runningFunction: Promise<ReturnType<T>> | undefined
|
|
12
|
+
let lastCall: Promise<ReturnType<T>> | undefined
|
|
13
|
+
let lastCallArguments: T2 | undefined
|
|
14
|
+
|
|
15
|
+
const checkForLastCall = (
|
|
16
|
+
timeStart: number,
|
|
17
|
+
resolve: (value: ReturnType<T> | PromiseLike<ReturnType<T>>) => void,
|
|
18
|
+
reject: (reason?: any) => void
|
|
19
|
+
) =>
|
|
20
|
+
(result: ReturnType<T>) => {
|
|
21
|
+
const currentTime = performance.now()
|
|
22
|
+
setTimeout(() => {
|
|
23
|
+
if (!lastCallArguments) {
|
|
24
|
+
runningFunction = undefined
|
|
25
|
+
lastCall = undefined
|
|
26
|
+
return
|
|
27
|
+
}
|
|
28
|
+
const funcResult = (async () => (func(...lastCallArguments)))()
|
|
29
|
+
lastCallArguments = undefined
|
|
30
|
+
funcResult
|
|
31
|
+
.then(resolve)
|
|
32
|
+
.catch((err) => {
|
|
33
|
+
console.error(err)
|
|
34
|
+
reject(err)
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
let _resolve: (value: ReturnType<T> | PromiseLike<ReturnType<T>>) => void
|
|
38
|
+
let _reject: (reason?: any) => void
|
|
39
|
+
lastCall = new Promise((resolve, reject) => {
|
|
40
|
+
_resolve = resolve
|
|
41
|
+
_reject = reject
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
runningFunction =
|
|
45
|
+
funcResult
|
|
46
|
+
// @ts-ignore
|
|
47
|
+
.then(checkForLastCall(currentTime, _resolve, _reject))
|
|
48
|
+
// @ts-ignore
|
|
49
|
+
.catch(err => {
|
|
50
|
+
console.error(err)
|
|
51
|
+
return checkForLastCall(timeStart, _resolve, _reject)(err)
|
|
52
|
+
})
|
|
53
|
+
}, time - (currentTime - timeStart))
|
|
54
|
+
return result
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return (...args: Parameters<T>) => {
|
|
58
|
+
lastCallArguments = args
|
|
59
|
+
if (!runningFunction) {
|
|
60
|
+
const timeStart = performance.now()
|
|
61
|
+
const funcResult = (async () => (func(...args)))()
|
|
62
|
+
lastCallArguments = undefined
|
|
63
|
+
let _resolve: (value: ReturnType<T> | PromiseLike<ReturnType<T>>) => void
|
|
64
|
+
let _reject: (reason?: any) => void
|
|
65
|
+
lastCall = new Promise((resolve, reject) => {
|
|
66
|
+
_resolve = resolve
|
|
67
|
+
_reject = reject
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
runningFunction =
|
|
71
|
+
funcResult
|
|
72
|
+
// @ts-ignore
|
|
73
|
+
.then(checkForLastCall(timeStart, _resolve, _reject))
|
|
74
|
+
// @ts-ignore
|
|
75
|
+
.catch(err => {
|
|
76
|
+
console.error(err)
|
|
77
|
+
return checkForLastCall(timeStart, _resolve, _reject)(err)
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
return funcResult
|
|
81
|
+
} else {
|
|
82
|
+
return lastCall
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// todo: reimplement this into a ReadableByteStream https://web.dev/streams/ once FF gets support
|
|
88
|
+
// todo: remove firefox workaround once https://bugzilla.mozilla.org/show_bug.cgi?id=1808868 ships
|
|
89
|
+
export const bufferStream = ({ stream, size: SIZE }: { stream: ReadableStream, size: number }) =>
|
|
90
|
+
new ReadableStream<Uint8Array>({
|
|
91
|
+
start() {
|
|
92
|
+
// @ts-expect-error
|
|
93
|
+
this.reader = stream.getReader()
|
|
94
|
+
},
|
|
95
|
+
async pull(controller) {
|
|
96
|
+
try {
|
|
97
|
+
// @ts-expect-error
|
|
98
|
+
const { leftOverData }: { leftOverData: Uint8Array | undefined } = this
|
|
99
|
+
|
|
100
|
+
const accumulate = async ({ buffer = new Uint8Array(SIZE), currentSize = 0 } = {}): Promise<{ buffer?: Uint8Array, currentSize?: number, done: boolean }> => {
|
|
101
|
+
// @ts-expect-error
|
|
102
|
+
const { value: newBuffer, done } = await this.reader.read()
|
|
103
|
+
|
|
104
|
+
if (currentSize === 0 && leftOverData) {
|
|
105
|
+
// console.log('currentSize', currentSize)
|
|
106
|
+
// console.log('buffer', buffer)
|
|
107
|
+
// console.log('leftOverData', leftOverData)
|
|
108
|
+
buffer.set(leftOverData)
|
|
109
|
+
currentSize += leftOverData.byteLength
|
|
110
|
+
// @ts-expect-error
|
|
111
|
+
this.leftOverData = undefined
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (done) {
|
|
115
|
+
return { buffer: buffer.slice(0, currentSize), currentSize, done }
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
let newSize
|
|
119
|
+
const slicedBuffer = newBuffer.slice(0, SIZE - currentSize)
|
|
120
|
+
newSize = currentSize + slicedBuffer.byteLength
|
|
121
|
+
buffer.set(slicedBuffer, currentSize)
|
|
122
|
+
|
|
123
|
+
if (newSize === SIZE) {
|
|
124
|
+
// @ts-expect-error
|
|
125
|
+
this.leftOverData = newBuffer.slice(SIZE - currentSize)
|
|
126
|
+
return { buffer, currentSize: newSize, done: false }
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return accumulate({ buffer, currentSize: newSize })
|
|
130
|
+
}
|
|
131
|
+
const { buffer, done } = await accumulate()
|
|
132
|
+
if (buffer?.byteLength) controller.enqueue(buffer)
|
|
133
|
+
if (done) controller.close()
|
|
134
|
+
} catch (err) {
|
|
135
|
+
console.error(err)
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
cancel() {
|
|
139
|
+
// @ts-expect-error
|
|
140
|
+
this.reader.cancel()
|
|
141
|
+
}
|
|
142
|
+
})
|
|
143
|
+
|
|
144
|
+
const getTimeRanges = (sourceBuffer: SourceBuffer) =>
|
|
145
|
+
Array(sourceBuffer.buffered.length)
|
|
146
|
+
.fill(undefined)
|
|
147
|
+
.map((_, index) => ({
|
|
148
|
+
index,
|
|
149
|
+
start: sourceBuffer.buffered.start(index),
|
|
150
|
+
end: sourceBuffer.buffered.end(index)
|
|
151
|
+
}))
|
|
152
|
+
|
|
153
|
+
const getTimeRange =
|
|
154
|
+
(sourceBuffer: SourceBuffer) =>
|
|
155
|
+
(time: number) =>
|
|
156
|
+
getTimeRanges(sourceBuffer)
|
|
157
|
+
.find(({ start, end }) => time >= start && time <= end)
|
|
158
|
+
|
|
159
|
+
// const setupListeners = (sourceBuffer: SourceBuffer, resolve: (value: Event) => void, reject: (reason: Event) => void) => {
|
|
160
|
+
// const updateEndListener = (ev: Event) => {
|
|
161
|
+
// resolve(ev)
|
|
162
|
+
// unregisterListeners()
|
|
163
|
+
// }
|
|
164
|
+
// const abortListener = (ev: Event) => {
|
|
165
|
+
// resolve(ev)
|
|
166
|
+
// unregisterListeners()
|
|
167
|
+
// }
|
|
168
|
+
// const errorListener = (ev: Event) => {
|
|
169
|
+
// reject(ev),
|
|
170
|
+
// unregisterListeners()
|
|
171
|
+
// }
|
|
172
|
+
// const unregisterListeners = () => {
|
|
173
|
+
// sourceBuffer.removeEventListener('updateend', updateEndListener)
|
|
174
|
+
// sourceBuffer.removeEventListener('abort', abortListener)
|
|
175
|
+
// sourceBuffer.removeEventListener('error', errorListener)
|
|
176
|
+
// }
|
|
177
|
+
// sourceBuffer.addEventListener('updateend', updateEndListener, { once: true })
|
|
178
|
+
// sourceBuffer.addEventListener('abort', abortListener, { once: true })
|
|
179
|
+
// sourceBuffer.addEventListener('error', errorListener, { once: true })
|
|
180
|
+
// }
|
|
181
|
+
|
|
182
|
+
// const appendBuffer = (queue: PQueue, sourceBuffer: SourceBuffer, buffer: ArrayBuffer) =>
|
|
183
|
+
// queue.add(() =>
|
|
184
|
+
// new Promise<Event>((resolve, reject) => {
|
|
185
|
+
// setupListeners(sourceBuffer, resolve, reject)
|
|
186
|
+
// sourceBuffer.appendBuffer(buffer)
|
|
187
|
+
// })
|
|
188
|
+
// )
|
|
189
|
+
|
|
190
|
+
// const bufferChunk = async (queue: PQueue, sourceBuffer: SourceBuffer, chunk: Chunk) => {
|
|
191
|
+
// await appendBuffer(queue, sourceBuffer, chunk.buffer.buffer)
|
|
192
|
+
// chunk.buffered = true
|
|
193
|
+
// }
|
|
194
|
+
|
|
195
|
+
// const unbufferChunk = async (queue: PQueue, sourceBuffer: SourceBuffer, chunks: Chunk[], chunk: Chunk) =>
|
|
196
|
+
// queue.add(() =>
|
|
197
|
+
// new Promise((resolve, reject) => {
|
|
198
|
+
// setupListeners(sourceBuffer, resolve, reject)
|
|
199
|
+
|
|
200
|
+
// const chunkIndex = chunks.indexOf(chunk)
|
|
201
|
+
// if (chunkIndex === -1) return reject('No chunk found')
|
|
202
|
+
// sourceBuffer.remove(chunk.pts, chunk.pts + chunk.duration)
|
|
203
|
+
// chunk.buffered = false
|
|
204
|
+
// })
|
|
205
|
+
// )
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
// const listenForOperationResult =
|
|
218
|
+
// (sourceBuffer: SourceBuffer) =>
|
|
219
|
+
// (resolve: (value: Event) => void, reject: (reason: Event) => void) => {
|
|
220
|
+
// const updateEndListener = (ev: Event) => {
|
|
221
|
+
// resolve(ev)
|
|
222
|
+
// unregisterListeners()
|
|
223
|
+
// }
|
|
224
|
+
// const abortListener = (ev: Event) => {
|
|
225
|
+
// resolve(ev)
|
|
226
|
+
// unregisterListeners()
|
|
227
|
+
// }
|
|
228
|
+
// const errorListener = (ev: Event) => {
|
|
229
|
+
// reject(ev),
|
|
230
|
+
// unregisterListeners()
|
|
231
|
+
// }
|
|
232
|
+
// const unregisterListeners = () => {
|
|
233
|
+
// sourceBuffer.removeEventListener('updateend', updateEndListener)
|
|
234
|
+
// sourceBuffer.removeEventListener('abort', abortListener)
|
|
235
|
+
// sourceBuffer.removeEventListener('error', errorListener)
|
|
236
|
+
// }
|
|
237
|
+
// sourceBuffer.addEventListener('updateend', updateEndListener, { once: true })
|
|
238
|
+
// sourceBuffer.addEventListener('abort', abortListener, { once: true })
|
|
239
|
+
// sourceBuffer.addEventListener('error', errorListener, { once: true })
|
|
240
|
+
// }
|
|
241
|
+
|
|
242
|
+
// export const appendBuffer =
|
|
243
|
+
// (sourceBuffer: SourceBuffer) =>
|
|
244
|
+
// (buffer: ArrayBuffer) =>
|
|
245
|
+
// new Promise<Event>((resolve, reject) => {
|
|
246
|
+
// listenForOperationResult(sourceBuffer)(resolve, reject)
|
|
247
|
+
// sourceBuffer.appendBuffer(buffer)
|
|
248
|
+
// })
|
|
249
|
+
|
|
250
|
+
// export const removeRange =
|
|
251
|
+
// (sourceBuffer: SourceBuffer) =>
|
|
252
|
+
// ({ start, end, index }: { start: number, end: number, index: number }) =>
|
|
253
|
+
// listenForOperationResult(sourceBuffer)(() => {
|
|
254
|
+
// sourceBuffer.remove(
|
|
255
|
+
// Math.max(sourceBuffer.buffered.start(index), start),
|
|
256
|
+
// Math.min(sourceBuffer.buffered.end(index), end)
|
|
257
|
+
// )
|
|
258
|
+
// })
|
|
259
|
+
|
|
260
|
+
// export const abort =
|
|
261
|
+
// (sourceBuffer: SourceBuffer) =>
|
|
262
|
+
// listenForOperationResult(sourceBuffer)(() => {
|
|
263
|
+
// sourceBuffer.abort()
|
|
264
|
+
// })
|
|
265
|
+
|
|
266
|
+
// export const appendChunk =
|
|
267
|
+
// (sourceBuffer: SourceBuffer) =>
|
|
268
|
+
// async (chunk: Chunk) => {
|
|
269
|
+
// await appendBuffer(sourceBuffer)(chunk.arrayBuffer.buffer)
|
|
270
|
+
// }
|
|
271
|
+
|
|
272
|
+
// export const removeChunk =
|
|
273
|
+
// (sourceBuffer: SourceBuffer) =>
|
|
274
|
+
// async (chunk: Chunk) => {
|
|
275
|
+
// if (chunk.keyframeIndex < 0) return console.log('skipped remove', chunk)
|
|
276
|
+
// const range = getTimeRange(sourceBuffer)(chunk.startTime) ?? getTimeRange(sourceBuffer)(chunk.endTime)
|
|
277
|
+
// if (!range) throw new RangeError('No TimeRange found with this chunk')
|
|
278
|
+
// await removeRange(sourceBuffer)({ start: chunk.startTime, end: chunk.endTime, index: range.index })
|
|
279
|
+
// }
|
|
280
|
+
|
|
281
|
+
// const PRE_SEEK_NEEDED_BUFFERS_IN_SECONDS = 15
|
|
282
|
+
// const POST_SEEK_NEEDED_BUFFERS_IN_SECONDS = 30
|
|
283
|
+
|
|
284
|
+
// // todo: fix issue with last chunk not properly loaded
|
|
285
|
+
// export const updateSourceBuffer =
|
|
286
|
+
// (sourceBuffer: SourceBuffer, getChunkArrayBuffer: (id: number) => Promise<Uint8Array | undefined>) => {
|
|
287
|
+
// const cache: Map<number, Uint8Array | Promise<Uint8Array | undefined>> = new Map()
|
|
288
|
+
// const bufferedChunksMap: Map<number, Uint8Array> = new Map()
|
|
289
|
+
// let renderCount = 0
|
|
290
|
+
|
|
291
|
+
// const update = async ({ currentTime, chunks, retry = false }: { currentTime: number, chunks: Chunk[], retry: boolean }) => {
|
|
292
|
+
// const currentRenderCount = renderCount
|
|
293
|
+
// renderCount++
|
|
294
|
+
|
|
295
|
+
// const neededChunks =
|
|
296
|
+
// [
|
|
297
|
+
// // header chunk
|
|
298
|
+
// { keyframeIndex: 0, startTime: 0, endTime: 0 },
|
|
299
|
+
// ...chunks
|
|
300
|
+
// .filter(({ startTime, endTime }) =>
|
|
301
|
+
// currentTime - PRE_SEEK_NEEDED_BUFFERS_IN_SECONDS < startTime
|
|
302
|
+
// && currentTime + POST_SEEK_NEEDED_BUFFERS_IN_SECONDS > endTime
|
|
303
|
+
// )
|
|
304
|
+
// ]
|
|
305
|
+
|
|
306
|
+
// // todo: improve perf by making this loop inclusive of bufferedChunksMap instead of chunks
|
|
307
|
+
// const shouldUnbufferChunks =
|
|
308
|
+
// chunks
|
|
309
|
+
// .filter(chunk => !neededChunks.includes(chunk))
|
|
310
|
+
|
|
311
|
+
// for (const chunk of shouldUnbufferChunks) {
|
|
312
|
+
// if (cache.has(chunk.keyframeIndex)) cache.delete(chunk.keyframeIndex)
|
|
313
|
+
// }
|
|
314
|
+
|
|
315
|
+
// if (sourceBuffer.updating) {
|
|
316
|
+
// await abort(sourceBuffer).catch((err) => {
|
|
317
|
+
// if (!(err instanceof Event)) throw err
|
|
318
|
+
// })
|
|
319
|
+
// }
|
|
320
|
+
// for (const chunk of shouldUnbufferChunks) {
|
|
321
|
+
// if (!bufferedChunksMap.has(chunk.keyframeIndex)) continue
|
|
322
|
+
// try {
|
|
323
|
+
// await removeChunk(sourceBuffer)(chunk)
|
|
324
|
+
// bufferedChunksMap.delete(chunk.keyframeIndex)
|
|
325
|
+
// } catch (err) {
|
|
326
|
+
// if (err.message === 'No TimeRange found with this chunk') {
|
|
327
|
+
// bufferedChunksMap.delete(chunk.keyframeIndex)
|
|
328
|
+
// }
|
|
329
|
+
// if (err.message !== 'No TimeRange found with this chunk') throw err
|
|
330
|
+
// }
|
|
331
|
+
// }
|
|
332
|
+
// const bufferedOutOfRangeRanges =
|
|
333
|
+
// getTimeRanges(sourceBuffer)
|
|
334
|
+
// .filter(({ start, end }) =>
|
|
335
|
+
// currentTime - PRE_SEEK_NEEDED_BUFFERS_IN_SECONDS > start && currentTime - PRE_SEEK_NEEDED_BUFFERS_IN_SECONDS > end ||
|
|
336
|
+
// currentTime + POST_SEEK_NEEDED_BUFFERS_IN_SECONDS < start && currentTime + POST_SEEK_NEEDED_BUFFERS_IN_SECONDS < end
|
|
337
|
+
// )
|
|
338
|
+
// for (const range of bufferedOutOfRangeRanges) {
|
|
339
|
+
// try {
|
|
340
|
+
// await removeRange(sourceBuffer)(range)
|
|
341
|
+
// } catch (err) {
|
|
342
|
+
// throw err
|
|
343
|
+
// }
|
|
344
|
+
// }
|
|
345
|
+
// for (const chunk of neededChunks) {
|
|
346
|
+
// // console.log('chunk', chunk, neededChunks, bufferedChunksMap.has(chunk.keyframeIndex), chunk.keyframeIndex + 1 === chunks.length)
|
|
347
|
+
// if (bufferedChunksMap.has(chunk.keyframeIndex) || (chunk.keyframeIndex !== 0 && chunk.keyframeIndex + 1 === chunks.length)) continue
|
|
348
|
+
// // console.log('check PASSED', chunk, neededChunks)
|
|
349
|
+
// try {
|
|
350
|
+
// const cachedBuffer = cache.get(chunk.keyframeIndex)
|
|
351
|
+
// if (!cachedBuffer) {
|
|
352
|
+
// const fetchBuffer =
|
|
353
|
+
// getChunkArrayBuffer(chunk.keyframeIndex)
|
|
354
|
+
// .then(arrayBuffer => {
|
|
355
|
+
// if (arrayBuffer) cache.set(chunk.keyframeIndex, arrayBuffer)
|
|
356
|
+
// return arrayBuffer
|
|
357
|
+
// })
|
|
358
|
+
// cache.set(chunk.keyframeIndex, fetchBuffer)
|
|
359
|
+
// }
|
|
360
|
+
// const buffer = await cache.get(chunk.keyframeIndex)
|
|
361
|
+
// if (renderCount !== currentRenderCount + 1) return
|
|
362
|
+
// if (!buffer) continue
|
|
363
|
+
// const _chunk = { ...chunk, arrayBuffer: buffer }
|
|
364
|
+
// await appendChunk(sourceBuffer)(_chunk).catch(err => {
|
|
365
|
+
// bufferedChunksMap.delete(chunk.keyframeIndex)
|
|
366
|
+
// throw err
|
|
367
|
+
// })
|
|
368
|
+
// bufferedChunksMap.set(chunk.keyframeIndex, buffer)
|
|
369
|
+
// } catch (err) {
|
|
370
|
+
// if (!(err instanceof Event)) {
|
|
371
|
+
// for (const range of getTimeRanges(sourceBuffer)) {
|
|
372
|
+
// await removeRange(sourceBuffer)(range)
|
|
373
|
+
// // todo: remove cached buffers from Maps
|
|
374
|
+
// }
|
|
375
|
+
// if (!retry) await update({ currentTime, chunks, retry: true })
|
|
376
|
+
// else throw err
|
|
377
|
+
// }
|
|
378
|
+
// // if (err.message !== 'Failed to execute \'appendBuffer\' on \'SourceBuffer\': This SourceBuffer is still processing an \'appendBuffer\' or \'remove\' operation.') throw err
|
|
379
|
+
// break
|
|
380
|
+
// }
|
|
381
|
+
// }
|
|
382
|
+
// }
|
|
383
|
+
|
|
384
|
+
// return update
|
|
385
|
+
// }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/// <reference types="vite/client" />
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ESNext",
|
|
4
|
+
"outDir": "build",
|
|
5
|
+
"lib": ["DOM", "DOM.Iterable", "ESNext"],
|
|
6
|
+
"allowJs": false,
|
|
7
|
+
"skipLibCheck": true,
|
|
8
|
+
"esModuleInterop": false,
|
|
9
|
+
"allowSyntheticDefaultImports": true,
|
|
10
|
+
"strict": true,
|
|
11
|
+
"forceConsistentCasingInFileNames": true,
|
|
12
|
+
"module": "ESNext",
|
|
13
|
+
"moduleResolution": "Node",
|
|
14
|
+
"resolveJsonModule": true,
|
|
15
|
+
"isolatedModules": true,
|
|
16
|
+
"noEmit": false,
|
|
17
|
+
"declaration": true,
|
|
18
|
+
"emitDeclarationOnly": true,
|
|
19
|
+
"jsx": "react-jsx",
|
|
20
|
+
"paths": {
|
|
21
|
+
"mp4box": ["./src/mp4box.ts"]
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"include": ["src"],
|
|
25
|
+
"references": [{ "path": "./tsconfig.node.json" }]
|
|
26
|
+
}
|