@tscaps/engine 0.3.0 → 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.
- package/README.md +35 -8
- package/dist/modules/document/CssVariable.d.ts +6 -0
- package/dist/modules/document/CssVariable.d.ts.map +1 -1
- package/dist/modules/document/CssVariable.js +6 -0
- package/dist/modules/document/CssVariable.js.map +1 -1
- package/dist/modules/document/Document.d.ts +3 -0
- package/dist/modules/document/Document.d.ts.map +1 -1
- package/dist/modules/document/Document.js +12 -1
- package/dist/modules/document/Document.js.map +1 -1
- package/dist/modules/document/DocumentEditor.d.ts +16 -4
- package/dist/modules/document/DocumentEditor.d.ts.map +1 -1
- package/dist/modules/document/DocumentEditor.js +14 -10
- package/dist/modules/document/DocumentEditor.js.map +1 -1
- package/dist/modules/document/Line.d.ts +6 -0
- package/dist/modules/document/Line.d.ts.map +1 -1
- package/dist/modules/document/Line.js +10 -0
- package/dist/modules/document/Line.js.map +1 -1
- package/dist/modules/document/Word.d.ts +8 -0
- package/dist/modules/document/Word.d.ts.map +1 -1
- package/dist/modules/document/Word.js +11 -1
- package/dist/modules/document/Word.js.map +1 -1
- package/dist/modules/pipeline/RenderPipelineBuilder.d.ts +1 -1
- package/dist/modules/pipeline/RenderPipelineBuilder.d.ts.map +1 -1
- package/dist/modules/pipeline/RenderPipelineBuilder.js +15 -5
- package/dist/modules/pipeline/RenderPipelineBuilder.js.map +1 -1
- package/dist/modules/rendering/BrowserSubtitleFrameRenderer.d.ts +18 -8
- package/dist/modules/rendering/BrowserSubtitleFrameRenderer.d.ts.map +1 -1
- package/dist/modules/rendering/BrowserSubtitleFrameRenderer.js +27 -21
- package/dist/modules/rendering/BrowserSubtitleFrameRenderer.js.map +1 -1
- package/dist/modules/rendering/SubtitleFrameRenderer.d.ts +41 -33
- package/dist/modules/rendering/SubtitleFrameRenderer.d.ts.map +1 -1
- package/dist/modules/rendering/index.d.ts +4 -0
- package/dist/modules/rendering/index.d.ts.map +1 -1
- package/dist/modules/rendering/index.js +2 -0
- package/dist/modules/rendering/index.js.map +1 -1
- package/dist/modules/rendering/subtitle/ActiveRenderSession.d.ts +13 -6
- package/dist/modules/rendering/subtitle/ActiveRenderSession.d.ts.map +1 -1
- package/dist/modules/rendering/subtitle/ActiveRenderSession.js +16 -9
- package/dist/modules/rendering/subtitle/ActiveRenderSession.js.map +1 -1
- package/dist/modules/rendering/subtitle/ActiveRenderSessionFactory.d.ts +5 -2
- package/dist/modules/rendering/subtitle/ActiveRenderSessionFactory.d.ts.map +1 -1
- package/dist/modules/rendering/subtitle/ActiveRenderSessionFactory.js +26 -8
- package/dist/modules/rendering/subtitle/ActiveRenderSessionFactory.js.map +1 -1
- package/dist/modules/rendering/subtitle/AnimationStateFingerprint.d.ts +20 -0
- package/dist/modules/rendering/subtitle/AnimationStateFingerprint.d.ts.map +1 -0
- package/dist/modules/rendering/subtitle/AnimationStateFingerprint.js +2 -0
- package/dist/modules/rendering/subtitle/AnimationStateFingerprint.js.map +1 -0
- package/dist/modules/rendering/subtitle/AssetGroupBuilder.d.ts +4 -0
- package/dist/modules/rendering/subtitle/AssetGroupBuilder.d.ts.map +1 -1
- package/dist/modules/rendering/subtitle/AssetGroupBuilder.js +8 -0
- package/dist/modules/rendering/subtitle/AssetGroupBuilder.js.map +1 -1
- package/dist/modules/rendering/subtitle/BatchPlanner.d.ts +50 -5
- package/dist/modules/rendering/subtitle/BatchPlanner.d.ts.map +1 -1
- package/dist/modules/rendering/subtitle/BatchPlanner.js +97 -15
- package/dist/modules/rendering/subtitle/BatchPlanner.js.map +1 -1
- package/dist/modules/rendering/subtitle/ElementWidthMeasurer.d.ts +56 -0
- package/dist/modules/rendering/subtitle/ElementWidthMeasurer.d.ts.map +1 -0
- package/dist/modules/rendering/subtitle/ElementWidthMeasurer.js +119 -0
- package/dist/modules/rendering/subtitle/ElementWidthMeasurer.js.map +1 -0
- package/dist/modules/rendering/subtitle/ElementWidths.d.ts +23 -0
- package/dist/modules/rendering/subtitle/ElementWidths.d.ts.map +1 -0
- package/dist/modules/rendering/subtitle/ElementWidths.js +29 -0
- package/dist/modules/rendering/subtitle/ElementWidths.js.map +1 -0
- package/dist/modules/rendering/subtitle/ImageDecodeSpriteSheetRasterProbe.d.ts +18 -0
- package/dist/modules/rendering/subtitle/ImageDecodeSpriteSheetRasterProbe.d.ts.map +1 -0
- package/dist/modules/rendering/subtitle/ImageDecodeSpriteSheetRasterProbe.js +42 -0
- package/dist/modules/rendering/subtitle/ImageDecodeSpriteSheetRasterProbe.js.map +1 -0
- package/dist/modules/rendering/subtitle/KeyframeScanAnimationStateFingerprint.d.ts +35 -0
- package/dist/modules/rendering/subtitle/KeyframeScanAnimationStateFingerprint.d.ts.map +1 -0
- package/dist/modules/rendering/subtitle/KeyframeScanAnimationStateFingerprint.js +64 -0
- package/dist/modules/rendering/subtitle/KeyframeScanAnimationStateFingerprint.js.map +1 -0
- package/dist/modules/rendering/subtitle/PreparedStyle.d.ts +2 -0
- package/dist/modules/rendering/subtitle/PreparedStyle.d.ts.map +1 -1
- package/dist/modules/rendering/subtitle/PreparedStyleFactory.d.ts.map +1 -1
- package/dist/modules/rendering/subtitle/PreparedStyleFactory.js +12 -1
- package/dist/modules/rendering/subtitle/PreparedStyleFactory.js.map +1 -1
- package/dist/modules/rendering/subtitle/SegmentAnchorVarsBuilder.d.ts +28 -0
- package/dist/modules/rendering/subtitle/SegmentAnchorVarsBuilder.d.ts.map +1 -0
- package/dist/modules/rendering/subtitle/SegmentAnchorVarsBuilder.js +23 -0
- package/dist/modules/rendering/subtitle/SegmentAnchorVarsBuilder.js.map +1 -0
- package/dist/modules/rendering/subtitle/SegmentSubtreeHtmlBuilder.d.ts +3 -0
- package/dist/modules/rendering/subtitle/SegmentSubtreeHtmlBuilder.d.ts.map +1 -1
- package/dist/modules/rendering/subtitle/SegmentSubtreeHtmlBuilder.js +12 -3
- package/dist/modules/rendering/subtitle/SegmentSubtreeHtmlBuilder.js.map +1 -1
- package/dist/modules/rendering/subtitle/SegmentWrapperRenderer.d.ts +7 -1
- package/dist/modules/rendering/subtitle/SegmentWrapperRenderer.d.ts.map +1 -1
- package/dist/modules/rendering/subtitle/SegmentWrapperRenderer.js +23 -5
- package/dist/modules/rendering/subtitle/SegmentWrapperRenderer.js.map +1 -1
- package/dist/modules/rendering/subtitle/SpriteSheetProbeObserver.d.ts +29 -0
- package/dist/modules/rendering/subtitle/SpriteSheetProbeObserver.d.ts.map +1 -0
- package/dist/modules/rendering/subtitle/SpriteSheetProbeObserver.js +2 -0
- package/dist/modules/rendering/subtitle/SpriteSheetProbeObserver.js.map +1 -0
- package/dist/modules/rendering/subtitle/SpriteSheetRasterProbe.d.ts +19 -0
- package/dist/modules/rendering/subtitle/SpriteSheetRasterProbe.d.ts.map +1 -0
- package/dist/modules/rendering/subtitle/SpriteSheetRasterProbe.js +2 -0
- package/dist/modules/rendering/subtitle/SpriteSheetRasterProbe.js.map +1 -0
- package/dist/modules/rendering/subtitle/SpriteSheetSizeProbe.d.ts +31 -0
- package/dist/modules/rendering/subtitle/SpriteSheetSizeProbe.d.ts.map +1 -0
- package/dist/modules/rendering/subtitle/SpriteSheetSizeProbe.js +89 -0
- package/dist/modules/rendering/subtitle/SpriteSheetSizeProbe.js.map +1 -0
- package/dist/modules/rendering/subtitle/SubtreeAnimationReading.d.ts +49 -0
- package/dist/modules/rendering/subtitle/SubtreeAnimationReading.d.ts.map +1 -0
- package/dist/modules/rendering/subtitle/SubtreeAnimationReading.js +87 -0
- package/dist/modules/rendering/subtitle/SubtreeAnimationReading.js.map +1 -0
- package/dist/modules/rendering/subtitle/SubtreeAnimationSupport.d.ts +17 -0
- package/dist/modules/rendering/subtitle/SubtreeAnimationSupport.d.ts.map +1 -0
- package/dist/modules/rendering/subtitle/SubtreeAnimationSupport.js +53 -0
- package/dist/modules/rendering/subtitle/SubtreeAnimationSupport.js.map +1 -0
- package/dist/modules/rendering/subtitle/SubtreeMountAnimationStateFingerprint.d.ts +62 -0
- package/dist/modules/rendering/subtitle/SubtreeMountAnimationStateFingerprint.d.ts.map +1 -0
- package/dist/modules/rendering/subtitle/SubtreeMountAnimationStateFingerprint.js +153 -0
- package/dist/modules/rendering/subtitle/SubtreeMountAnimationStateFingerprint.js.map +1 -0
- package/dist/modules/rendering/subtitle/SvgFilterStateFingerprint.d.ts +47 -0
- package/dist/modules/rendering/subtitle/SvgFilterStateFingerprint.d.ts.map +1 -0
- package/dist/modules/rendering/subtitle/SvgFilterStateFingerprint.js +69 -0
- package/dist/modules/rendering/subtitle/SvgFilterStateFingerprint.js.map +1 -0
- package/dist/modules/rendering/subtitle/UnknownAnimationStateFingerprint.d.ts +9 -0
- package/dist/modules/rendering/subtitle/UnknownAnimationStateFingerprint.d.ts.map +1 -0
- package/dist/modules/rendering/subtitle/UnknownAnimationStateFingerprint.js +10 -0
- package/dist/modules/rendering/subtitle/UnknownAnimationStateFingerprint.js.map +1 -0
- package/dist/modules/rendering/subtitle/VideoFrameVarsBuilder.d.ts.map +1 -1
- package/dist/modules/rendering/subtitle/VideoFrameVarsBuilder.js +2 -0
- package/dist/modules/rendering/subtitle/VideoFrameVarsBuilder.js.map +1 -1
- package/dist/modules/rendering/types/ElementRenderOverrides.d.ts +2 -0
- package/dist/modules/rendering/types/ElementRenderOverrides.d.ts.map +1 -1
- package/dist/modules/rendering/types/ElementRenderOverrides.js +4 -0
- package/dist/modules/rendering/types/ElementRenderOverrides.js.map +1 -1
- package/dist/modules/splitting/BalancedLineSplitter.d.ts +9 -0
- package/dist/modules/splitting/BalancedLineSplitter.d.ts.map +1 -1
- package/dist/modules/splitting/BalancedLineSplitter.js +15 -3
- package/dist/modules/splitting/BalancedLineSplitter.js.map +1 -1
- package/dist/modules/splitting/BalancedPixelWidthLineSplitter.d.ts +1 -4
- package/dist/modules/splitting/BalancedPixelWidthLineSplitter.d.ts.map +1 -1
- package/dist/modules/splitting/BalancedPixelWidthLineSplitter.js +5 -7
- package/dist/modules/splitting/BalancedPixelWidthLineSplitter.js.map +1 -1
- package/dist/modules/splitting/DomProbeCanvasTextMeasurer.d.ts +16 -7
- package/dist/modules/splitting/DomProbeCanvasTextMeasurer.d.ts.map +1 -1
- package/dist/modules/splitting/DomProbeCanvasTextMeasurer.js +44 -33
- package/dist/modules/splitting/DomProbeCanvasTextMeasurer.js.map +1 -1
- package/dist/modules/splitting/TextMeasurer.d.ts +9 -4
- package/dist/modules/splitting/TextMeasurer.d.ts.map +1 -1
- package/dist/modules/svg-filter/SvgFilter.d.ts +9 -0
- package/dist/modules/svg-filter/SvgFilter.d.ts.map +1 -1
- package/dist/modules/svg-filter/SvgFilter.js +17 -0
- package/dist/modules/svg-filter/SvgFilter.js.map +1 -1
- package/dist/modules/svg-filter/SvgFilterDefinitions.d.ts +7 -0
- package/dist/modules/svg-filter/SvgFilterDefinitions.d.ts.map +1 -1
- package/dist/modules/svg-filter/SvgFilterDefinitions.js +17 -0
- package/dist/modules/svg-filter/SvgFilterDefinitions.js.map +1 -1
- package/dist/modules/tagging/RegexTagger.js +1 -2
- package/dist/modules/tagging/RegexTagger.js.map +1 -1
- package/dist/modules/tagging/SpanTagger.js +1 -2
- package/dist/modules/tagging/SpanTagger.js.map +1 -1
- package/dist/modules/tagging/StructureTagger.js +1 -2
- package/dist/modules/tagging/StructureTagger.js.map +1 -1
- package/dist/modules/tagging/WordlistTagger.js +1 -2
- package/dist/modules/tagging/WordlistTagger.js.map +1 -1
- package/dist/modules/transcription/AudioSegmentLayout.d.ts +23 -0
- package/dist/modules/transcription/AudioSegmentLayout.d.ts.map +1 -0
- package/dist/modules/transcription/AudioSegmentLayout.js +40 -0
- package/dist/modules/transcription/AudioSegmentLayout.js.map +1 -0
- package/dist/modules/transcription/FallbackAudioDecoder.d.ts +25 -0
- package/dist/modules/transcription/FallbackAudioDecoder.d.ts.map +1 -0
- package/dist/modules/transcription/FallbackAudioDecoder.js +46 -0
- package/dist/modules/transcription/FallbackAudioDecoder.js.map +1 -0
- package/dist/modules/transcription/MediaBunnyAudioOnlyRemuxer.d.ts +71 -0
- package/dist/modules/transcription/MediaBunnyAudioOnlyRemuxer.d.ts.map +1 -0
- package/dist/modules/transcription/MediaBunnyAudioOnlyRemuxer.js +145 -0
- package/dist/modules/transcription/MediaBunnyAudioOnlyRemuxer.js.map +1 -0
- package/dist/modules/transcription/WebAudioAudioDecoder.d.ts +46 -0
- package/dist/modules/transcription/WebAudioAudioDecoder.d.ts.map +1 -0
- package/dist/modules/transcription/WebAudioAudioDecoder.js +123 -0
- package/dist/modules/transcription/WebAudioAudioDecoder.js.map +1 -0
- package/dist/modules/transcription/index.d.ts +4 -0
- package/dist/modules/transcription/index.d.ts.map +1 -1
- package/dist/modules/transcription/index.js +3 -0
- package/dist/modules/transcription/index.js.map +1 -1
- package/dist/modules/video/RenderJob.d.ts +23 -0
- package/dist/modules/video/RenderJob.d.ts.map +1 -1
- package/dist/modules/video/index.d.ts +5 -3
- package/dist/modules/video/index.d.ts.map +1 -1
- package/dist/modules/video/index.js +2 -0
- package/dist/modules/video/index.js.map +1 -1
- package/dist/modules/video/mediabunny/MediaBunnyTranscodeCoordinator.d.ts +33 -1
- package/dist/modules/video/mediabunny/MediaBunnyTranscodeCoordinator.d.ts.map +1 -1
- package/dist/modules/video/mediabunny/MediaBunnyTranscodeCoordinator.js +97 -20
- package/dist/modules/video/mediabunny/MediaBunnyTranscodeCoordinator.js.map +1 -1
- package/dist/modules/video/mediabunny/MediaBunnyVideoRenderer.d.ts.map +1 -1
- package/dist/modules/video/mediabunny/MediaBunnyVideoRenderer.js +1 -0
- package/dist/modules/video/mediabunny/MediaBunnyVideoRenderer.js.map +1 -1
- package/dist/modules/video/mediabunny/caption/BatchedSubtitleLayerSource.d.ts +20 -9
- package/dist/modules/video/mediabunny/caption/BatchedSubtitleLayerSource.d.ts.map +1 -1
- package/dist/modules/video/mediabunny/caption/BatchedSubtitleLayerSource.js +56 -14
- package/dist/modules/video/mediabunny/caption/BatchedSubtitleLayerSource.js.map +1 -1
- package/dist/modules/video/mediabunny/caption/ComposedSubtitleLayerSource.d.ts +29 -10
- package/dist/modules/video/mediabunny/caption/ComposedSubtitleLayerSource.d.ts.map +1 -1
- package/dist/modules/video/mediabunny/caption/ComposedSubtitleLayerSource.js +48 -17
- package/dist/modules/video/mediabunny/caption/ComposedSubtitleLayerSource.js.map +1 -1
- package/dist/modules/video/mediabunny/caption/SubtitleLayerSource.d.ts +28 -11
- package/dist/modules/video/mediabunny/caption/SubtitleLayerSource.d.ts.map +1 -1
- package/dist/modules/video/mediabunny/caption/VideoBoundSubtitleLayerSource.d.ts +33 -12
- package/dist/modules/video/mediabunny/caption/VideoBoundSubtitleLayerSource.d.ts.map +1 -1
- package/dist/modules/video/mediabunny/caption/VideoBoundSubtitleLayerSource.js +53 -18
- package/dist/modules/video/mediabunny/caption/VideoBoundSubtitleLayerSource.js.map +1 -1
- package/dist/modules/video/mediabunny/encoder/MediaBunnyCanvasVideoTrackEncoder.d.ts.map +1 -1
- package/dist/modules/video/mediabunny/encoder/MediaBunnyCanvasVideoTrackEncoder.js +7 -3
- package/dist/modules/video/mediabunny/encoder/MediaBunnyCanvasVideoTrackEncoder.js.map +1 -1
- package/dist/modules/video/mediabunny/frame/BufferedVideoFrameSource.d.ts +45 -0
- package/dist/modules/video/mediabunny/frame/BufferedVideoFrameSource.d.ts.map +1 -0
- package/dist/modules/video/mediabunny/frame/BufferedVideoFrameSource.js +93 -0
- package/dist/modules/video/mediabunny/frame/BufferedVideoFrameSource.js.map +1 -0
- package/dist/modules/video/mediabunny/frame/DefaultVideoFrameDecoderFactory.d.ts.map +1 -1
- package/dist/modules/video/mediabunny/frame/DefaultVideoFrameDecoderFactory.js +3 -1
- package/dist/modules/video/mediabunny/frame/DefaultVideoFrameDecoderFactory.js.map +1 -1
- package/dist/modules/video/mediabunny/frame/RetainedVideoFrame.d.ts +26 -0
- package/dist/modules/video/mediabunny/frame/RetainedVideoFrame.d.ts.map +1 -0
- package/dist/modules/video/mediabunny/frame/RetainedVideoFrame.js +55 -0
- package/dist/modules/video/mediabunny/frame/RetainedVideoFrame.js.map +1 -0
- package/dist/modules/video/mediabunny/frame/VideoFrameDecoderFactory.d.ts +6 -1
- package/dist/modules/video/mediabunny/frame/VideoFrameDecoderFactory.d.ts.map +1 -1
- package/dist/modules/video/mediabunny/frame/VideoFrameDecoderSelectionFailedError.d.ts +14 -0
- package/dist/modules/video/mediabunny/frame/VideoFrameDecoderSelectionFailedError.d.ts.map +1 -0
- package/dist/modules/video/mediabunny/frame/VideoFrameDecoderSelectionFailedError.js +14 -0
- package/dist/modules/video/mediabunny/frame/VideoFrameDecoderSelectionFailedError.js.map +1 -0
- package/dist/modules/video/mediabunny/frame/WebCodecsOnlyVideoFrameDecoderFactory.d.ts +16 -0
- package/dist/modules/video/mediabunny/frame/WebCodecsOnlyVideoFrameDecoderFactory.d.ts.map +1 -0
- package/dist/modules/video/mediabunny/frame/WebCodecsOnlyVideoFrameDecoderFactory.js +23 -0
- package/dist/modules/video/mediabunny/frame/WebCodecsOnlyVideoFrameDecoderFactory.js.map +1 -0
- package/dist/modules/video/mediabunny/painter/CaptionsOverlayFramePainter.d.ts +9 -3
- package/dist/modules/video/mediabunny/painter/CaptionsOverlayFramePainter.d.ts.map +1 -1
- package/dist/modules/video/mediabunny/painter/CaptionsOverlayFramePainter.js +24 -7
- package/dist/modules/video/mediabunny/painter/CaptionsOverlayFramePainter.js.map +1 -1
- package/dist/modules/video/mediabunny/painter/FramePainter.d.ts +35 -14
- package/dist/modules/video/mediabunny/painter/FramePainter.d.ts.map +1 -1
- package/package.json +4 -1
- package/dist/modules/rendering/subtitle/AbstractAnim.d.ts +0 -13
- package/dist/modules/rendering/subtitle/AbstractAnim.d.ts.map +0 -1
- package/dist/modules/rendering/subtitle/AbstractAnim.js +0 -2
- package/dist/modules/rendering/subtitle/AbstractAnim.js.map +0 -1
- package/dist/modules/rendering/subtitle/AnimationProbe.d.ts +0 -39
- package/dist/modules/rendering/subtitle/AnimationProbe.d.ts.map +0 -1
- package/dist/modules/rendering/subtitle/AnimationProbe.js +0 -203
- package/dist/modules/rendering/subtitle/AnimationProbe.js.map +0 -1
- package/dist/modules/rendering/subtitle/SpriteSheetSizeProber.d.ts +0 -17
- package/dist/modules/rendering/subtitle/SpriteSheetSizeProber.d.ts.map +0 -1
- package/dist/modules/rendering/subtitle/SpriteSheetSizeProber.js +0 -58
- package/dist/modules/rendering/subtitle/SpriteSheetSizeProber.js.map +0 -1
- package/dist/modules/video/mediabunny/frame/CurrentFrameVideoSource.d.ts +0 -27
- package/dist/modules/video/mediabunny/frame/CurrentFrameVideoSource.d.ts.map +0 -1
- package/dist/modules/video/mediabunny/frame/CurrentFrameVideoSource.js +0 -84
- package/dist/modules/video/mediabunny/frame/CurrentFrameVideoSource.js.map +0 -1
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { profiler } from '../../../profiling/Profiler';
|
|
2
|
+
/**
|
|
3
|
+
* A decoded frame's pixels copied onto a canvas of the caller's own, so
|
|
4
|
+
* they outlive the decoder's frame.
|
|
5
|
+
*
|
|
6
|
+
* A decoder hands out frames it expects back promptly: holding several
|
|
7
|
+
* at once back-pressures the frame pool into a stall. Copying breaks
|
|
8
|
+
* that tie — the decoder's frame closes immediately and what stays
|
|
9
|
+
* alive is an ordinary canvas, at the cost of one full-frame draw and
|
|
10
|
+
* `width × height × 4` bytes per frame held.
|
|
11
|
+
*/
|
|
12
|
+
export class RetainedVideoFrame {
|
|
13
|
+
timestamp;
|
|
14
|
+
duration;
|
|
15
|
+
/**
|
|
16
|
+
* Copies `frame` at the given dimensions. Does not close `frame`;
|
|
17
|
+
* the caller keeps that responsibility and may do so as soon as this
|
|
18
|
+
* returns.
|
|
19
|
+
*/
|
|
20
|
+
static copyOf(frame, width, height) {
|
|
21
|
+
const canvas = new OffscreenCanvas(width, height);
|
|
22
|
+
const context = canvas.getContext('2d', { alpha: false });
|
|
23
|
+
if (!context) {
|
|
24
|
+
throw new Error('Unable to acquire a 2D context to retain a video frame.');
|
|
25
|
+
}
|
|
26
|
+
// Smoothing left at the context default, which matters whenever the
|
|
27
|
+
// export was asked for dimensions the source does not have: this is
|
|
28
|
+
// the only resample those pixels get before they reach the encoder.
|
|
29
|
+
profiler.time('RetainedVideoFrame.copy', () => frame.draw(context, 0, 0, width, height));
|
|
30
|
+
return new RetainedVideoFrame(canvas, frame.timestamp, frame.duration);
|
|
31
|
+
}
|
|
32
|
+
canvas;
|
|
33
|
+
constructor(canvas, timestamp, duration) {
|
|
34
|
+
this.timestamp = timestamp;
|
|
35
|
+
this.duration = duration;
|
|
36
|
+
this.canvas = canvas;
|
|
37
|
+
}
|
|
38
|
+
draw(context, dx, dy, dWidth, dHeight) {
|
|
39
|
+
if (!this.canvas) {
|
|
40
|
+
throw new Error('RetainedVideoFrame.draw called after close.');
|
|
41
|
+
}
|
|
42
|
+
context.drawImage(this.canvas, dx, dy, dWidth, dHeight);
|
|
43
|
+
}
|
|
44
|
+
close() {
|
|
45
|
+
// Dropping the reference is what frees the pixels; an OffscreenCanvas
|
|
46
|
+
// has no explicit release. Sizing it to nothing first hands the
|
|
47
|
+
// buffer back without waiting for a collection.
|
|
48
|
+
if (this.canvas) {
|
|
49
|
+
this.canvas.width = 0;
|
|
50
|
+
this.canvas.height = 0;
|
|
51
|
+
}
|
|
52
|
+
this.canvas = null;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=RetainedVideoFrame.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RetainedVideoFrame.js","sourceRoot":"","sources":["../../../../../src/modules/video/mediabunny/frame/RetainedVideoFrame.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAEvD;;;;;;;;;GASG;AACH,MAAM,OAAO,kBAAkB;IAwBlB;IACA;IAvBX;;;;OAIG;IACH,MAAM,CAAC,MAAM,CAAC,KAAwB,EAAE,KAAa,EAAE,MAAc;QACnE,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAClD,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;QAC1D,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;QAC7E,CAAC;QACD,oEAAoE;QACpE,oEAAoE;QACpE,oEAAoE;QACpE,QAAQ,CAAC,IAAI,CAAC,yBAAyB,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;QACzF,OAAO,IAAI,kBAAkB,CAAC,MAAM,EAAE,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;IACzE,CAAC;IAEO,MAAM,CAAyB;IAEvC,YACE,MAAuB,EACd,SAAiB,EACjB,QAAgB;QADhB,cAAS,GAAT,SAAS,CAAQ;QACjB,aAAQ,GAAR,QAAQ,CAAQ;QAEzB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,IAAI,CACF,OAAqE,EACrE,EAAU,EACV,EAAU,EACV,MAAc,EACd,OAAe;QAEf,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;QACjE,CAAC;QACD,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1D,CAAC;IAED,KAAK;QACH,sEAAsE;QACtE,gEAAgE;QAChE,gDAAgD;QAChD,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC;YACtB,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;QACzB,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;IACrB,CAAC;CACF"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { InputVideoTrack } from 'mediabunny';
|
|
2
2
|
import type { VideoFrameDecoder } from '../../../video/mediabunny/frame/VideoFrameDecoder';
|
|
3
|
-
import type { FallbackDecoderInfo } from '../../../video/RenderJob';
|
|
3
|
+
import type { FallbackDecoderInfo, VideoFrameDecoderSelection } from '../../../video/RenderJob';
|
|
4
4
|
export interface VideoFrameDecoderRequest {
|
|
5
5
|
/** The primary video track from the input file. */
|
|
6
6
|
track: InputVideoTrack;
|
|
@@ -12,6 +12,11 @@ export interface VideoFrameDecoderRequest {
|
|
|
12
12
|
* the factory uses the fallback without asking.
|
|
13
13
|
*/
|
|
14
14
|
confirmFallback?: (info: FallbackDecoderInfo) => Promise<boolean>;
|
|
15
|
+
/**
|
|
16
|
+
* Called with the decoder the factory settled on, before it is
|
|
17
|
+
* returned. Not invoked when the factory aborts instead.
|
|
18
|
+
*/
|
|
19
|
+
onDecoderSelected?: (selection: VideoFrameDecoderSelection) => void;
|
|
15
20
|
}
|
|
16
21
|
/**
|
|
17
22
|
* Picks an appropriate {@link VideoFrameDecoder} for the given input track.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VideoFrameDecoderFactory.d.ts","sourceRoot":"","sources":["../../../../../src/modules/video/mediabunny/frame/VideoFrameDecoderFactory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mDAAmD,CAAC;AAC3F,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"VideoFrameDecoderFactory.d.ts","sourceRoot":"","sources":["../../../../../src/modules/video/mediabunny/frame/VideoFrameDecoderFactory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mDAAmD,CAAC;AAC3F,OAAO,KAAK,EAAE,mBAAmB,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AAEhG,MAAM,WAAW,wBAAwB;IACvC,mDAAmD;IACnD,KAAK,EAAE,eAAe,CAAC;IACvB,0EAA0E;IAC1E,MAAM,EAAE,IAAI,CAAC;IACb;;;;OAIG;IACH,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,mBAAmB,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAClE;;;OAGG;IACH,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,0BAA0B,KAAK,IAAI,CAAC;CACrE;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,MAAM,CAAC,OAAO,EAAE,wBAAwB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;CACvE"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Raised when no decoder the factory is allowed to use can handle the
|
|
3
|
+
* input's video track. Fired before any frame is decoded.
|
|
4
|
+
*
|
|
5
|
+
* The `.name` string is set explicitly, and exposed as `ERROR_NAME` on
|
|
6
|
+
* the class, so consumers can recognise the failure across a boundary
|
|
7
|
+
* that preserves string fields but not class identity — a Worker, or a
|
|
8
|
+
* browser driven from outside the page.
|
|
9
|
+
*/
|
|
10
|
+
export declare class VideoFrameDecoderSelectionFailedError extends Error {
|
|
11
|
+
static readonly ERROR_NAME = "VideoFrameDecoderSelectionFailedError";
|
|
12
|
+
readonly name = "VideoFrameDecoderSelectionFailedError";
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=VideoFrameDecoderSelectionFailedError.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VideoFrameDecoderSelectionFailedError.d.ts","sourceRoot":"","sources":["../../../../../src/modules/video/mediabunny/frame/VideoFrameDecoderSelectionFailedError.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,qBAAa,qCAAsC,SAAQ,KAAK;IAC9D,MAAM,CAAC,QAAQ,CAAC,UAAU,2CAA2C;IACrE,QAAQ,CAAC,IAAI,2CAAoD;CAClE"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Raised when no decoder the factory is allowed to use can handle the
|
|
3
|
+
* input's video track. Fired before any frame is decoded.
|
|
4
|
+
*
|
|
5
|
+
* The `.name` string is set explicitly, and exposed as `ERROR_NAME` on
|
|
6
|
+
* the class, so consumers can recognise the failure across a boundary
|
|
7
|
+
* that preserves string fields but not class identity — a Worker, or a
|
|
8
|
+
* browser driven from outside the page.
|
|
9
|
+
*/
|
|
10
|
+
export class VideoFrameDecoderSelectionFailedError extends Error {
|
|
11
|
+
static ERROR_NAME = 'VideoFrameDecoderSelectionFailedError';
|
|
12
|
+
name = VideoFrameDecoderSelectionFailedError.ERROR_NAME;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=VideoFrameDecoderSelectionFailedError.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VideoFrameDecoderSelectionFailedError.js","sourceRoot":"","sources":["../../../../../src/modules/video/mediabunny/frame/VideoFrameDecoderSelectionFailedError.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,OAAO,qCAAsC,SAAQ,KAAK;IAC9D,MAAM,CAAU,UAAU,GAAG,uCAAuC,CAAC;IAC5D,IAAI,GAAG,qCAAqC,CAAC,UAAU,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { VideoFrameDecoder } from '../../../video/mediabunny/frame/VideoFrameDecoder';
|
|
2
|
+
import type { VideoFrameDecoderFactory, VideoFrameDecoderRequest } from '../../../video/mediabunny/frame/VideoFrameDecoderFactory';
|
|
3
|
+
/**
|
|
4
|
+
* Returns the WebCodecs decoder or nothing at all.
|
|
5
|
+
*
|
|
6
|
+
* The `<video>` element fallback the default factory reaches for is
|
|
7
|
+
* bounded by playback speed, so a host that decodes a source only that
|
|
8
|
+
* way is better served by rewriting the source than by driving it. This
|
|
9
|
+
* factory makes that refusal explicit instead of quietly taking the
|
|
10
|
+
* slow path: it raises {@link VideoFrameDecoderSelectionFailedError},
|
|
11
|
+
* and whoever asked decides what to rewrite.
|
|
12
|
+
*/
|
|
13
|
+
export declare class WebCodecsOnlyVideoFrameDecoderFactory implements VideoFrameDecoderFactory {
|
|
14
|
+
create(request: VideoFrameDecoderRequest): Promise<VideoFrameDecoder>;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=WebCodecsOnlyVideoFrameDecoderFactory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WebCodecsOnlyVideoFrameDecoderFactory.d.ts","sourceRoot":"","sources":["../../../../../src/modules/video/mediabunny/frame/WebCodecsOnlyVideoFrameDecoderFactory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mDAAmD,CAAC;AAC3F,OAAO,KAAK,EACV,wBAAwB,EACxB,wBAAwB,EACzB,MAAM,0DAA0D,CAAC;AAIlE;;;;;;;;;GASG;AACH,qBAAa,qCAAsC,YAAW,wBAAwB;IAE9E,MAAM,CAAC,OAAO,EAAE,wBAAwB,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAU5E"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { VideoFrameDecoderSelectionFailedError } from '../../../video/mediabunny/frame/VideoFrameDecoderSelectionFailedError';
|
|
2
|
+
import { WebCodecsVideoFrameDecoder } from '../../../video/mediabunny/frame/WebCodecsVideoFrameDecoder';
|
|
3
|
+
/**
|
|
4
|
+
* Returns the WebCodecs decoder or nothing at all.
|
|
5
|
+
*
|
|
6
|
+
* The `<video>` element fallback the default factory reaches for is
|
|
7
|
+
* bounded by playback speed, so a host that decodes a source only that
|
|
8
|
+
* way is better served by rewriting the source than by driving it. This
|
|
9
|
+
* factory makes that refusal explicit instead of quietly taking the
|
|
10
|
+
* slow path: it raises {@link VideoFrameDecoderSelectionFailedError},
|
|
11
|
+
* and whoever asked decides what to rewrite.
|
|
12
|
+
*/
|
|
13
|
+
export class WebCodecsOnlyVideoFrameDecoderFactory {
|
|
14
|
+
async create(request) {
|
|
15
|
+
const inputCodec = (await request.track.getCodec()) ?? 'unknown';
|
|
16
|
+
if (!(await request.track.canDecode())) {
|
|
17
|
+
throw new VideoFrameDecoderSelectionFailedError(`WebCodecs cannot decode the input video codec (${inputCodec}).`);
|
|
18
|
+
}
|
|
19
|
+
request.onDecoderSelected?.({ kind: 'web-codecs', inputCodec });
|
|
20
|
+
return new WebCodecsVideoFrameDecoder(request.track);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=WebCodecsOnlyVideoFrameDecoderFactory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WebCodecsOnlyVideoFrameDecoderFactory.js","sourceRoot":"","sources":["../../../../../src/modules/video/mediabunny/frame/WebCodecsOnlyVideoFrameDecoderFactory.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,qCAAqC,EAAE,MAAM,uEAAuE,CAAC;AAC9H,OAAO,EAAE,0BAA0B,EAAE,MAAM,4DAA4D,CAAC;AAExG;;;;;;;;;GASG;AACH,MAAM,OAAO,qCAAqC;IAEhD,KAAK,CAAC,MAAM,CAAC,OAAiC;QAC5C,MAAM,UAAU,GAAG,CAAC,MAAM,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,IAAI,SAAS,CAAC;QACjE,IAAI,CAAC,CAAC,MAAM,OAAO,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC;YACvC,MAAM,IAAI,qCAAqC,CAC7C,kDAAkD,UAAU,IAAI,CACjE,CAAC;QACJ,CAAC;QACD,OAAO,CAAC,iBAAiB,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC,CAAC;QAChE,OAAO,IAAI,0BAA0B,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACvD,CAAC;CACF"}
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import type { Document } from '../../../document/Document';
|
|
2
2
|
import type { OverlayFrameRenderer } from '../../../rendering/OverlayFrameRenderer';
|
|
3
3
|
import type { SubtitleStyle } from '../../../rendering/SubtitleFrameRenderer';
|
|
4
|
-
import type { DecodedVideoFrame } from '../../../video/mediabunny/frame/VideoFrameDecoder';
|
|
5
4
|
import type { FrameCompositor } from '../../../video/mediabunny/frame/FrameCompositor';
|
|
6
5
|
import type { SubtitleLayerSource } from '../../../video/mediabunny/caption/SubtitleLayerSource';
|
|
7
6
|
import type { TopLayerSource } from '../../../video/mediabunny/painter/TopLayerSource';
|
|
8
7
|
import type { PaintFrame } from '../../../video/mediabunny/encoder/VideoTrackEncoder';
|
|
9
|
-
import type { FramePainter } from '../../../video/mediabunny/painter/FramePainter';
|
|
8
|
+
import type { FramePainter, FramePaintRequest } from '../../../video/mediabunny/painter/FramePainter';
|
|
10
9
|
/**
|
|
11
10
|
* Paints each output frame as the source frame composited with a
|
|
12
11
|
* per-timestamp caption raster and a frame-invariant overlay. The
|
|
@@ -29,7 +28,14 @@ export declare class CaptionsOverlayFramePainter implements FramePainter {
|
|
|
29
28
|
private overlay;
|
|
30
29
|
constructor(subtitleLayer: SubtitleLayerSource, overlayRenderer: OverlayFrameRenderer, frameCompositor: FrameCompositor, document: Document, styles: Readonly<Record<string, SubtitleStyle>>, overlayHtml: string | undefined, topLayer: TopLayerSource | null);
|
|
31
30
|
begin(width: number, height: number, fps: number): Promise<void>;
|
|
32
|
-
|
|
31
|
+
lookAhead(): number;
|
|
32
|
+
paint(requests: ReadonlyArray<FramePaintRequest>): Promise<PaintFrame[]>;
|
|
33
|
+
/**
|
|
34
|
+
* One per request, or all null when no top layer is configured. Kept
|
|
35
|
+
* frame by frame because the top layer reads the frame it occludes
|
|
36
|
+
* and has no batch of its own to amortize.
|
|
37
|
+
*/
|
|
38
|
+
private paintTopLayers;
|
|
33
39
|
end(): void;
|
|
34
40
|
}
|
|
35
41
|
//# sourceMappingURL=CaptionsOverlayFramePainter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CaptionsOverlayFramePainter.d.ts","sourceRoot":"","sources":["../../../../../src/modules/video/mediabunny/painter/CaptionsOverlayFramePainter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,KAAK,EAAgB,oBAAoB,EAAE,MAAM,yCAAyC,CAAC;AAClG,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0CAA0C,CAAC;AAC9E,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"CaptionsOverlayFramePainter.d.ts","sourceRoot":"","sources":["../../../../../src/modules/video/mediabunny/painter/CaptionsOverlayFramePainter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,KAAK,EAAgB,oBAAoB,EAAE,MAAM,yCAAyC,CAAC;AAClG,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0CAA0C,CAAC;AAC9E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iDAAiD,CAAC;AACvF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uDAAuD,CAAC;AACjG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kDAAkD,CAAC;AACvF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qDAAqD,CAAC;AACtF,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,gDAAgD,CAAC;AAUtG;;;;;;;;GAQG;AACH,qBAAa,2BAA4B,YAAW,YAAY;IAO5D,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAX3B,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,OAAO,CAA6B;gBAGzB,aAAa,EAAE,mBAAmB,EAClC,eAAe,EAAE,oBAAoB,EACrC,eAAe,EAAE,eAAe,EAChC,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,EAC/C,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,QAAQ,EAAE,cAAc,GAAG,IAAI;IAG5C,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAatE,SAAS,IAAI,MAAM;IAIb,KAAK,CAAC,QAAQ,EAAE,aAAa,CAAC,iBAAiB,CAAC,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAiB9E;;;;OAIG;YACW,cAAc;IAW5B,GAAG,IAAI,IAAI;CAKZ"}
|
|
@@ -46,19 +46,36 @@ export class CaptionsOverlayFramePainter {
|
|
|
46
46
|
await this.topLayer.open(width, height);
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
lookAhead() {
|
|
50
|
+
return this.subtitleLayer.lookAhead();
|
|
51
|
+
}
|
|
52
|
+
async paint(requests) {
|
|
53
|
+
const captions = await this.subtitleLayer.framesFor(requests.map(({ frame }) => ({ time: frame.timestamp, videoFrame: frame })));
|
|
54
|
+
const topLayers = await this.paintTopLayers(requests);
|
|
55
|
+
return requests.map(({ frame }, i) => (ctx) => {
|
|
53
56
|
this.frameCompositor.compose(ctx, {
|
|
54
57
|
frame,
|
|
55
|
-
captions,
|
|
58
|
+
captions: captions[i] ?? null,
|
|
56
59
|
overlay: this.overlay,
|
|
57
|
-
topLayer,
|
|
60
|
+
topLayer: topLayers[i] ?? null,
|
|
58
61
|
width: this.width,
|
|
59
62
|
height: this.height,
|
|
60
63
|
});
|
|
61
|
-
};
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* One per request, or all null when no top layer is configured. Kept
|
|
68
|
+
* frame by frame because the top layer reads the frame it occludes
|
|
69
|
+
* and has no batch of its own to amortize.
|
|
70
|
+
*/
|
|
71
|
+
async paintTopLayers(requests) {
|
|
72
|
+
if (this.topLayer === null)
|
|
73
|
+
return requests.map(() => null);
|
|
74
|
+
const layers = [];
|
|
75
|
+
for (const { frame } of requests) {
|
|
76
|
+
layers.push(await this.topLayer.frameAt(frame.timestamp, frame));
|
|
77
|
+
}
|
|
78
|
+
return layers;
|
|
62
79
|
}
|
|
63
80
|
end() {
|
|
64
81
|
this.subtitleLayer.close();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CaptionsOverlayFramePainter.js","sourceRoot":"","sources":["../../../../../src/modules/video/mediabunny/painter/CaptionsOverlayFramePainter.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"CaptionsOverlayFramePainter.js","sourceRoot":"","sources":["../../../../../src/modules/video/mediabunny/painter/CaptionsOverlayFramePainter.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import type { DecodedVideoFrame } from '../../../video/mediabunny/frame/VideoFrameDecoder';
|
|
2
2
|
import type { PaintFrame } from '../../../video/mediabunny/encoder/VideoTrackEncoder';
|
|
3
|
+
/** One output frame to paint: the decoded source frame and where it lands on the output timeline. */
|
|
4
|
+
export interface FramePaintRequest {
|
|
5
|
+
readonly frame: DecodedVideoFrame;
|
|
6
|
+
readonly outputTimestamp: number;
|
|
7
|
+
}
|
|
3
8
|
/**
|
|
4
9
|
* Owns the pixel work for a single transcode run: what to draw into
|
|
5
10
|
* every output frame's canvas. The transcode coordinator owns the
|
|
@@ -8,16 +13,16 @@ import type { PaintFrame } from '../../../video/mediabunny/encoder/VideoTrackEnc
|
|
|
8
13
|
*
|
|
9
14
|
* Lifecycle is per-run: {@link begin} once at the start with the
|
|
10
15
|
* resolved output dimensions and source frame rate, {@link paint} for
|
|
11
|
-
* each decoded
|
|
12
|
-
* {@link end} once at the end (called on both success and
|
|
13
|
-
* Instances are single-use unless the concrete class
|
|
14
|
-
* otherwise.
|
|
16
|
+
* each run of decoded frames in monotonically advancing source-time
|
|
17
|
+
* order, and {@link end} once at the end (called on both success and
|
|
18
|
+
* failure). Instances are single-use unless the concrete class
|
|
19
|
+
* documents otherwise.
|
|
15
20
|
*
|
|
16
21
|
* The two-step {@link paint} contract exists because
|
|
17
22
|
* {@link VideoTrackEncoder.encode} takes a synchronous paint callback:
|
|
18
|
-
* any
|
|
19
|
-
*
|
|
20
|
-
*
|
|
23
|
+
* any work that has to be awaited (e.g. rasterizing a caption layer)
|
|
24
|
+
* happens inside {@link paint}, and the returned closures run
|
|
25
|
+
* synchronously against the encoder's canvas.
|
|
21
26
|
*/
|
|
22
27
|
export interface FramePainter {
|
|
23
28
|
/**
|
|
@@ -28,14 +33,30 @@ export interface FramePainter {
|
|
|
28
33
|
*/
|
|
29
34
|
begin(width: number, height: number, fps: number): Promise<void>;
|
|
30
35
|
/**
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
36
|
+
* How many consecutive frames the painter wants handed to one
|
|
37
|
+
* {@link paint} call to work at its best. `1` means it is happy frame
|
|
38
|
+
* by frame; a larger number means it amortizes work across the run,
|
|
39
|
+
* and the caller should gather that many before painting — which
|
|
40
|
+
* costs it holding them all until the run is painted and encoded.
|
|
41
|
+
*
|
|
42
|
+
* A preference, not a requirement: {@link paint} accepts any length,
|
|
43
|
+
* and the last run of a render is short by nature. Meaningful only
|
|
44
|
+
* after {@link begin}.
|
|
45
|
+
*/
|
|
46
|
+
lookAhead(): number;
|
|
47
|
+
/**
|
|
48
|
+
* Resolves any state the run needs asynchronously and returns one
|
|
49
|
+
* synchronous paint step per request, in the order given.
|
|
50
|
+
*
|
|
51
|
+
* Each request's `outputTimestamp` is that frame's presentation time
|
|
52
|
+
* on the output timeline (already mapped through any skip ranges by
|
|
53
|
+
* the caller); its `frame.timestamp` carries the source-timeline time
|
|
54
|
+
* and stays authoritative for any lookup against source-aligned data
|
|
55
|
+
* (captions, per-source overlays).
|
|
56
|
+
*
|
|
57
|
+
* The frames must stay open until every returned step has run.
|
|
37
58
|
*/
|
|
38
|
-
paint(
|
|
59
|
+
paint(requests: ReadonlyArray<FramePaintRequest>): Promise<PaintFrame[]>;
|
|
39
60
|
/**
|
|
40
61
|
* Releases the per-run resources opened by {@link begin}. Called on
|
|
41
62
|
* both success and failure paths of the enclosing run. Idempotent:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FramePainter.d.ts","sourceRoot":"","sources":["../../../../../src/modules/video/mediabunny/painter/FramePainter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mDAAmD,CAAC;AAC3F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qDAAqD,CAAC;AAEtF;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;;OAKG;IACH,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjE
|
|
1
|
+
{"version":3,"file":"FramePainter.d.ts","sourceRoot":"","sources":["../../../../../src/modules/video/mediabunny/painter/FramePainter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mDAAmD,CAAC;AAC3F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qDAAqD,CAAC;AAEtF,qGAAqG;AACrG,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,KAAK,EAAE,iBAAiB,CAAC;IAClC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;CAClC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;;OAKG;IACH,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjE;;;;;;;;;;OAUG;IACH,SAAS,IAAI,MAAM,CAAC;IAEpB;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,QAAQ,EAAE,aAAa,CAAC,iBAAiB,CAAC,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IAEzE;;;;OAIG;IACH,GAAG,IAAI,IAAI,CAAC;CACb"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tscaps/engine",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Burn subtitles into video in the browser. CSS-styled captions, frame-accurate export, no server.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"subtitles",
|
|
@@ -56,6 +56,9 @@
|
|
|
56
56
|
"bidi-js": "^1.0.3",
|
|
57
57
|
"mediabunny": "^1.51.0"
|
|
58
58
|
},
|
|
59
|
+
"peerDependencies": {
|
|
60
|
+
"onnxruntime-web": "^1.27.0"
|
|
61
|
+
},
|
|
59
62
|
"devDependencies": {
|
|
60
63
|
"@eslint/js": "10.0.1",
|
|
61
64
|
"@playwright/test": "^1.49.0",
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { CssVariable } from '../../document/CssVariable';
|
|
2
|
-
/**
|
|
3
|
-
* One animation timing extracted from a probed element's computed
|
|
4
|
-
* style: the CSS variable whose start moment anchors the active
|
|
5
|
-
* window, and the duration the rule runs for once that moment passes.
|
|
6
|
-
* `durationS` is `Infinity` for an `animation-iteration-count:
|
|
7
|
-
* infinite` rule.
|
|
8
|
-
*/
|
|
9
|
-
export interface AbstractAnim {
|
|
10
|
-
cssVar: CssVariable;
|
|
11
|
-
durationS: number;
|
|
12
|
-
}
|
|
13
|
-
//# sourceMappingURL=AbstractAnim.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AbstractAnim.d.ts","sourceRoot":"","sources":["../../../../src/modules/rendering/subtitle/AbstractAnim.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAEjE;;;;;;GAMG;AACH,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,WAAW,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AbstractAnim.js","sourceRoot":"","sources":["../../../../src/modules/rendering/subtitle/AbstractAnim.ts"],"names":[],"mappings":""}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import type { Segment } from '../../document/Segment';
|
|
2
|
-
import type { PreparedStyle } from '../../rendering/subtitle/PreparedStyle';
|
|
3
|
-
/**
|
|
4
|
-
* Decides whether a render item should redraw every frame: builds
|
|
5
|
-
* throw-away DOM chains matching what the renderer emits, reads back
|
|
6
|
-
* resolved `animation-duration` / `animation-delay` from
|
|
7
|
-
* `getComputedStyle`, and decodes each timing back to the CSS
|
|
8
|
-
* variable that anchored its window. Caches per chain so the same one
|
|
9
|
-
* is probed at most once. `clear` empties the cache.
|
|
10
|
-
*
|
|
11
|
-
* A chain carries the element ids the renderer stamps as well as the
|
|
12
|
-
* classes, because a stylesheet can address one element rather than a
|
|
13
|
-
* class of them. Built from classes alone, the chain resolves a
|
|
14
|
-
* different animation than the node it stands for — none at all where
|
|
15
|
-
* only the element carries one, and the wrong window where the
|
|
16
|
-
* element's beats the template's. Either way the tile is reused across
|
|
17
|
-
* a frame that moved, and the animation exports as a still image.
|
|
18
|
-
*
|
|
19
|
-
* Only ids the stylesheet actually addresses go on, so a caption
|
|
20
|
-
* nobody has styled probes one chain per class combination as before.
|
|
21
|
-
*/
|
|
22
|
-
export declare class AnimationProbe {
|
|
23
|
-
private readonly timingByKey;
|
|
24
|
-
isItemAnimating(style: PreparedStyle, seg: Segment, t: number): boolean;
|
|
25
|
-
clear(): void;
|
|
26
|
-
/** The element as the probe will build it, addressed only where the stylesheet says so. */
|
|
27
|
-
private probed;
|
|
28
|
-
private animates;
|
|
29
|
-
private timingOf;
|
|
30
|
-
private describe;
|
|
31
|
-
/** Mounts the chain, reads what the leaf resolved to, and takes it back out. */
|
|
32
|
-
private probeChain;
|
|
33
|
-
private createNode;
|
|
34
|
-
private injectProbeMagic;
|
|
35
|
-
private readAnimTimings;
|
|
36
|
-
private parseDurationsS;
|
|
37
|
-
private evalAnims;
|
|
38
|
-
}
|
|
39
|
-
//# sourceMappingURL=AnimationProbe.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AnimationProbe.d.ts","sourceRoot":"","sources":["../../../../src/modules/rendering/subtitle/AnimationProbe.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAEzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2CAA2C,CAAC;AA2B/E;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqC;IAEjE,eAAe,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO;IAwCvE,KAAK,IAAI,IAAI;IAIb,2FAA2F;IAC3F,OAAO,CAAC,MAAM;IASd,OAAO,CAAC,QAAQ;IAShB,OAAO,CAAC,QAAQ;IAUhB,OAAO,CAAC,QAAQ;IAIhB,gFAAgF;IAChF,OAAO,CAAC,UAAU;IAYlB,OAAO,CAAC,UAAU;IAUlB,OAAO,CAAC,gBAAgB;IAMxB,OAAO,CAAC,eAAe;IAwBvB,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,SAAS;CA6BlB"}
|