@revideo/2d 0.4.4 → 0.4.6-alpha.1017
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.
|
@@ -71,6 +71,9 @@ export class Video extends Media {
|
|
|
71
71
|
this
|
|
72
72
|
>;
|
|
73
73
|
|
|
74
|
+
public detectedFileType: 'mp4' | 'webm' | 'hls' | 'unknown' = 'unknown';
|
|
75
|
+
private fileTypeWasDetected: boolean = false;
|
|
76
|
+
|
|
74
77
|
private static readonly pool: Record<string, HTMLVideoElement> = {};
|
|
75
78
|
|
|
76
79
|
private static readonly imageCommunication = !import.meta.hot
|
|
@@ -79,15 +82,6 @@ export class Video extends Media {
|
|
|
79
82
|
|
|
80
83
|
public constructor(props: VideoProps) {
|
|
81
84
|
super(props);
|
|
82
|
-
|
|
83
|
-
// If the file is not mp4, warn.
|
|
84
|
-
// strip the query string from the source
|
|
85
|
-
const src = this.fullSource().split('?')[0];
|
|
86
|
-
if (!src.endsWith('.mp4')) {
|
|
87
|
-
console.warn(
|
|
88
|
-
`WARNING: Video source is not an MP4 file. This may significantly slow down rendering: ${this.fullSource()}`,
|
|
89
|
-
);
|
|
90
|
-
}
|
|
91
85
|
}
|
|
92
86
|
|
|
93
87
|
protected override desiredSize(): SerializedVector2<DesiredLength> {
|
|
@@ -256,6 +250,10 @@ export class Video extends Media {
|
|
|
256
250
|
}
|
|
257
251
|
|
|
258
252
|
protected async seekFunction() {
|
|
253
|
+
if (!this.fileTypeWasDetected) {
|
|
254
|
+
this.detectedFileType = await this.detectFileType();
|
|
255
|
+
this.fileTypeWasDetected = true;
|
|
256
|
+
}
|
|
259
257
|
const playbackState = this.view().playbackState();
|
|
260
258
|
|
|
261
259
|
// During playback
|
|
@@ -283,16 +281,16 @@ export class Video extends Media {
|
|
|
283
281
|
return this.webcodecSeekedVideo();
|
|
284
282
|
}
|
|
285
283
|
|
|
286
|
-
// If not set explicitly, use file
|
|
287
|
-
if (this.
|
|
288
|
-
return this.
|
|
284
|
+
// If not set explicitly, use detected file type to determine decoder
|
|
285
|
+
if (this.detectedFileType === 'webm') {
|
|
286
|
+
return this.ffmpegSeekedVideo();
|
|
289
287
|
}
|
|
290
288
|
|
|
291
|
-
if (this.
|
|
292
|
-
return this.
|
|
289
|
+
if (this.detectedFileType === 'hls') {
|
|
290
|
+
return this.seekedVideo();
|
|
293
291
|
}
|
|
294
292
|
|
|
295
|
-
return this.
|
|
293
|
+
return this.webcodecSeekedVideo();
|
|
296
294
|
}
|
|
297
295
|
|
|
298
296
|
protected override async draw(context: CanvasRenderingContext2D) {
|
|
@@ -326,4 +324,38 @@ export class Video extends Media {
|
|
|
326
324
|
this.ratio() ?? video.videoWidth / video.videoHeight
|
|
327
325
|
).toString();
|
|
328
326
|
}
|
|
327
|
+
|
|
328
|
+
private async detectFileType(): Promise<'mp4' | 'webm' | 'hls' | 'unknown'> {
|
|
329
|
+
if (this.fullSource().split('?')[0].endsWith('.mp4')) return 'mp4';
|
|
330
|
+
if (this.fullSource().split('?')[0].endsWith('.webm')) return 'webm';
|
|
331
|
+
if (this.fullSource().split('?')[0].endsWith('.m3u8')) return 'hls';
|
|
332
|
+
|
|
333
|
+
if (
|
|
334
|
+
this.fullSource().startsWith('http:') ||
|
|
335
|
+
this.fullSource().startsWith('https:')
|
|
336
|
+
) {
|
|
337
|
+
try {
|
|
338
|
+
const response = await fetch(this.fullSource(), {method: 'HEAD'});
|
|
339
|
+
const contentType = response.headers.get('Content-Type');
|
|
340
|
+
|
|
341
|
+
if (contentType) {
|
|
342
|
+
if (contentType.includes('video/mp4')) return 'mp4';
|
|
343
|
+
if (contentType.includes('video/webm')) return 'webm';
|
|
344
|
+
if (
|
|
345
|
+
contentType.includes('application/vnd.apple.mpegurl') ||
|
|
346
|
+
contentType.includes('application/x-mpegURL')
|
|
347
|
+
) {
|
|
348
|
+
return 'hls';
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
} catch (error) {
|
|
352
|
+
// do nothing
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
console.warn(
|
|
357
|
+
`WARNING: Could not detect file type of video (${this.fullSource()}), will default to using mp4 decoder. If your video file is no mp4 file, this will lead to an error - to fix this, reencode your video as an mp4 file (better performance) or specify a different decoder: https://docs.re.video/common-issues/slow-rendering#use-mp4-decoder`,
|
|
358
|
+
);
|
|
359
|
+
return 'unknown';
|
|
360
|
+
}
|
|
329
361
|
}
|