@browser-mc/browser-movie-converter 0.0.1
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 +167 -0
- package/dist/conversion-options.d.ts +74 -0
- package/dist/conversion-options.d.ts.map +1 -0
- package/dist/conversion-options.js +292 -0
- package/dist/conversion-options.js.map +1 -0
- package/dist/hls.d.ts +37 -0
- package/dist/hls.d.ts.map +1 -0
- package/dist/hls.js +117 -0
- package/dist/hls.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/package.json +34 -0
package/README.md
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# @browser-mc/browser-movie-converter
|
|
2
|
+
|
|
3
|
+
Browser movie conversion package using Mediabunny for demux/mux/encode orchestration and the local WebCodecs color helpers for resizing.
|
|
4
|
+
|
|
5
|
+
- Caller-provided Mediabunny `Input` for MP4/MOV/WebM and other supported sources
|
|
6
|
+
- MP4/WebM output through Mediabunny `Conversion`
|
|
7
|
+
- HLS output through local Mediabunny helpers
|
|
8
|
+
- Streaming scene detection and keyframe forcing through `@browser-mc/mediabunny-scene-keyframes`
|
|
9
|
+
- Raw planar resize through `@browser-mc/webcodecs-color`
|
|
10
|
+
- Input color-space inspection and color metadata copying for raw-resized samples
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
```sh
|
|
15
|
+
pnpm add @browser-mc/browser-movie-converter mediabunny
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Build Mediabunny conversion options
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
import {
|
|
22
|
+
BlobSource,
|
|
23
|
+
BufferTarget,
|
|
24
|
+
Conversion,
|
|
25
|
+
Input,
|
|
26
|
+
Mp4OutputFormat,
|
|
27
|
+
Output,
|
|
28
|
+
QuickTimeInputFormat,
|
|
29
|
+
} from 'mediabunny';
|
|
30
|
+
import {
|
|
31
|
+
buildMovieConversionOptions,
|
|
32
|
+
} from '@browser-mc/browser-movie-converter';
|
|
33
|
+
|
|
34
|
+
const input = new Input({
|
|
35
|
+
source: new BlobSource(file),
|
|
36
|
+
formats: [new QuickTimeInputFormat()],
|
|
37
|
+
});
|
|
38
|
+
const target = new BufferTarget();
|
|
39
|
+
const output = new Output({
|
|
40
|
+
target,
|
|
41
|
+
format: new Mp4OutputFormat({ fastStart: 'in-memory' }),
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
const plan = await buildMovieConversionOptions({
|
|
45
|
+
input,
|
|
46
|
+
output,
|
|
47
|
+
videoTrackQuery: {
|
|
48
|
+
filter: (track) => track.number === 1,
|
|
49
|
+
},
|
|
50
|
+
video: {
|
|
51
|
+
codec: 'avc',
|
|
52
|
+
bitrate: { quality: 0.75 },
|
|
53
|
+
},
|
|
54
|
+
resize: {
|
|
55
|
+
width: 1280,
|
|
56
|
+
},
|
|
57
|
+
sceneDetection: {
|
|
58
|
+
sampleRate: 'all',
|
|
59
|
+
threshold: 0.2,
|
|
60
|
+
},
|
|
61
|
+
colorMetadata: 'preserve',
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
const conversion = await Conversion.init(plan.options);
|
|
65
|
+
if (!conversion.isValid) {
|
|
66
|
+
throw new Error('Mediabunny could not create a valid conversion');
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
await conversion.execute();
|
|
70
|
+
console.log(plan.sceneKeyFrames?.state.keyFrameTimestamps);
|
|
71
|
+
console.log(plan.videoColor?.colorSpace);
|
|
72
|
+
console.log(plan.resize);
|
|
73
|
+
console.log(target.buffer);
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## HLS
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
import {
|
|
80
|
+
BlobSource,
|
|
81
|
+
Input,
|
|
82
|
+
QuickTimeInputFormat,
|
|
83
|
+
} from 'mediabunny';
|
|
84
|
+
import {
|
|
85
|
+
convertMovieToHls,
|
|
86
|
+
decodeMovieHlsText,
|
|
87
|
+
} from '@browser-mc/browser-movie-converter';
|
|
88
|
+
|
|
89
|
+
const input = new Input({
|
|
90
|
+
source: new BlobSource(file),
|
|
91
|
+
formats: [new QuickTimeInputFormat()],
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
for await (const asset of convertMovieToHls({
|
|
95
|
+
input,
|
|
96
|
+
tracks: 'primary',
|
|
97
|
+
videoTrackQuery: {
|
|
98
|
+
filter: (track) => track.number === 1,
|
|
99
|
+
},
|
|
100
|
+
targetDuration: 2,
|
|
101
|
+
resize: {
|
|
102
|
+
width: 640,
|
|
103
|
+
},
|
|
104
|
+
variants: [
|
|
105
|
+
{
|
|
106
|
+
resize: {
|
|
107
|
+
width: 1280,
|
|
108
|
+
},
|
|
109
|
+
video: {
|
|
110
|
+
bitrate: 4_000_000,
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
video: {
|
|
115
|
+
bitrate: 1_500_000,
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
],
|
|
119
|
+
sceneDetection: {
|
|
120
|
+
sampleRate: 'all',
|
|
121
|
+
threshold: 0.2,
|
|
122
|
+
},
|
|
123
|
+
})) {
|
|
124
|
+
if (asset.path.endsWith('.m3u8')) {
|
|
125
|
+
const bytes = new Uint8Array(await new Response(asset.data).arrayBuffer());
|
|
126
|
+
console.log(asset.path, decodeMovieHlsText(bytes));
|
|
127
|
+
} else {
|
|
128
|
+
await uploadSegment(asset.path, asset.data);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Advanced Options
|
|
134
|
+
|
|
135
|
+
`quantizer` is an advanced encoder-control option for AVC/H.264 style quantizer tuning:
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
const plan = await buildMovieConversionOptions({
|
|
139
|
+
input,
|
|
140
|
+
output,
|
|
141
|
+
video: {
|
|
142
|
+
codec: 'avc',
|
|
143
|
+
bitrate: 4_000_000,
|
|
144
|
+
},
|
|
145
|
+
quantizer: {
|
|
146
|
+
keyFrame: 28,
|
|
147
|
+
deltaFrame: 36,
|
|
148
|
+
},
|
|
149
|
+
});
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
It accepts either a single integer or `{ keyFrame, deltaFrame }`. Lower values preserve more quality, and higher values compress more aggressively. Values must be integers from 0 to 63.
|
|
153
|
+
|
|
154
|
+
When using `quantizer`, still set `video.bitrate` as a compatibility hint. Mediabunny uses bitrate, not quantizer values, when choosing the AVC/H.264 level for the generated codec string.
|
|
155
|
+
|
|
156
|
+
When split `quantizer` values are used with `keyFrameInterval`, the interval is handled by this package so interval key frames can receive the `keyFrame` quantizer.
|
|
157
|
+
|
|
158
|
+
## Notes
|
|
159
|
+
|
|
160
|
+
- This package builds Mediabunny `ConversionOptions`; callers choose the `Output`, target, and final `Conversion` lifecycle.
|
|
161
|
+
- When `resize` is set, the generated video options use `VideoSample.toVideoFrame()` plus `webcodecs-color.resizeFrameRaw()` inside Mediabunny's `process` hook.
|
|
162
|
+
- `convertMovieToHls` streams HLS assets through `ReadableStream<Uint8Array>` and requires `variants`, producing one HLS video encode per variant. Top-level resize, scene detection, quantizer, color metadata, force transcode, and key-frame options act as defaults; variant values override them. Audio is encoded once and paired with every video variant.
|
|
163
|
+
- For AVC/H.264 transcodes, Mediabunny currently builds `avc1.64....` codec strings by default, which corresponds to High Profile. If the video track is copied without transcoding, the source profile is preserved instead.
|
|
164
|
+
- Resize dimensions are rounded down to a multiple of `dimensionAlignment`, defaulting to `2`, which avoids odd-size 4:2:0/NV12 artifacts and encoder constraints.
|
|
165
|
+
- Scene detection defaults to `sampleRate: 'all'`, so every decoded video sample is considered while conversion runs. Detected scene samples are marked immediately with Mediabunny `VideoSample` encode options to force key frames.
|
|
166
|
+
- `colorMetadata: 'preserve'` copies the source sample's `VideoColorSpace` metadata to raw-resized samples. `colorMetadata: 'canvas-sdr'` draws frames through an sRGB Canvas path and marks output samples as BT.709 SDR; it is a practical browser conversion path, not a dedicated HDR tone-mapping engine.
|
|
167
|
+
- For browser tests with H.264/AAC material, use a browser build that has proprietary codec support, such as installed Chrome/Electron rather than Playwright's bundled Chromium.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { Input, type ConversionAudioOptions, type ConversionOptions, type ConversionVideoOptions, type InputAudioTrack, type InputTrackQuery, type InputVideoTrack, type Output } from 'mediabunny';
|
|
2
|
+
import { SceneKeyFrameDetector, type SceneDetectionOptions, type SceneKeyFrameState } from '@browser-mc/mediabunny-scene-keyframes';
|
|
3
|
+
import { type ResizeRawOptions } from '@browser-mc/webcodecs-color';
|
|
4
|
+
export type BrowserMovieColorMetadataPolicy = 'preserve' | 'canvas-sdr';
|
|
5
|
+
export type BrowserMovieResizeFit = 'contain' | 'cover' | 'fill';
|
|
6
|
+
export type BrowserMovieResizePath = 'raw';
|
|
7
|
+
export type BrowserMovieResizeOptions = {
|
|
8
|
+
width?: number;
|
|
9
|
+
height?: number;
|
|
10
|
+
fit?: BrowserMovieResizeFit;
|
|
11
|
+
rawAlgorithm?: ResizeRawOptions['algorithm'];
|
|
12
|
+
dimensionAlignment?: 1 | 2 | 4 | 8;
|
|
13
|
+
};
|
|
14
|
+
export type BrowserMovieQuantizerOptions = number | {
|
|
15
|
+
keyFrame?: number;
|
|
16
|
+
deltaFrame?: number;
|
|
17
|
+
};
|
|
18
|
+
export type BrowserMovieConversionOptionsInput = {
|
|
19
|
+
input: Input;
|
|
20
|
+
output: Output;
|
|
21
|
+
video?: Omit<ConversionVideoOptions, 'process' | 'forceTranscode' | 'width' | 'height' | 'fit' | 'processedWidth' | 'processedHeight'>;
|
|
22
|
+
audio?: ConversionAudioOptions;
|
|
23
|
+
resize?: BrowserMovieResizeOptions;
|
|
24
|
+
sceneDetection?: false | SceneDetectionOptions;
|
|
25
|
+
quantizer?: BrowserMovieQuantizerOptions;
|
|
26
|
+
colorMetadata?: BrowserMovieColorMetadataPolicy;
|
|
27
|
+
forceTranscode?: boolean;
|
|
28
|
+
tracks?: ConversionOptions['tracks'];
|
|
29
|
+
videoTrackQuery?: InputTrackQuery<InputVideoTrack>;
|
|
30
|
+
};
|
|
31
|
+
export type BrowserMovieVideoConversionOptionsInput = {
|
|
32
|
+
track: InputVideoTrack;
|
|
33
|
+
video?: Omit<ConversionVideoOptions, 'process' | 'forceTranscode' | 'width' | 'height' | 'fit' | 'processedWidth' | 'processedHeight'>;
|
|
34
|
+
resize?: BrowserMovieResizeOptions;
|
|
35
|
+
sceneDetection?: false | SceneDetectionOptions;
|
|
36
|
+
quantizer?: BrowserMovieQuantizerOptions;
|
|
37
|
+
colorMetadata?: BrowserMovieColorMetadataPolicy;
|
|
38
|
+
forceTranscode?: boolean;
|
|
39
|
+
};
|
|
40
|
+
export type BrowserMovieVideoConversionPlan = {
|
|
41
|
+
options: ConversionVideoOptions;
|
|
42
|
+
sceneKeyFrames: SceneKeyFrameDetector | null;
|
|
43
|
+
videoColor: BrowserMovieTrackColor;
|
|
44
|
+
resize: {
|
|
45
|
+
width: number;
|
|
46
|
+
height: number;
|
|
47
|
+
path: BrowserMovieResizePath | 'none';
|
|
48
|
+
} | null;
|
|
49
|
+
};
|
|
50
|
+
export type BrowserMovieTrackColor = {
|
|
51
|
+
colorSpace: VideoColorSpaceInit | null;
|
|
52
|
+
hasHighDynamicRange: boolean;
|
|
53
|
+
};
|
|
54
|
+
export type BrowserMovieConversionPlan = {
|
|
55
|
+
options: ConversionOptions;
|
|
56
|
+
sceneKeyFrames: SceneKeyFrameDetector | null;
|
|
57
|
+
videoColor: BrowserMovieTrackColor | null;
|
|
58
|
+
resize: {
|
|
59
|
+
width: number;
|
|
60
|
+
height: number;
|
|
61
|
+
path: BrowserMovieResizePath | 'none';
|
|
62
|
+
} | null;
|
|
63
|
+
};
|
|
64
|
+
export declare function buildMovieConversionOptions(options: BrowserMovieConversionOptionsInput): Promise<BrowserMovieConversionPlan>;
|
|
65
|
+
export declare function buildMovieVideoConversionOptions(options: BrowserMovieVideoConversionOptionsInput): Promise<BrowserMovieVideoConversionPlan>;
|
|
66
|
+
export declare function inspectMovie(input: Input, videoTrackQuery?: InputTrackQuery<InputVideoTrack>): Promise<{
|
|
67
|
+
videoColor: BrowserMovieTrackColor | null;
|
|
68
|
+
scenePlan: SceneKeyFrameState | null;
|
|
69
|
+
}>;
|
|
70
|
+
export declare function inspectVideoTrackColor(track: InputVideoTrack): Promise<BrowserMovieTrackColor>;
|
|
71
|
+
export declare function getSelectedVideoTracks(input: Input, tracks: NonNullable<ConversionOptions['tracks']>, videoTrackQuery?: InputTrackQuery<InputVideoTrack>): Promise<InputVideoTrack[]>;
|
|
72
|
+
export declare function getSelectedAudioTracks(input: Input, tracks: NonNullable<ConversionOptions['tracks']>): Promise<InputAudioTrack[]>;
|
|
73
|
+
export type { SceneDetectionOptions, SceneKeyFrameState, };
|
|
74
|
+
//# sourceMappingURL=conversion-options.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversion-options.d.ts","sourceRoot":"","sources":["../src/conversion-options.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
import { Input, VideoSample, } from 'mediabunny';
|
|
2
|
+
import { planSceneKeyFrames, SceneKeyFrameDetector, } from '@browser-mc/mediabunny-scene-keyframes';
|
|
3
|
+
import { convertFrameToCanvasSdr, resizeFrameRaw, sdrVideoColorSpaceInit, } from '@browser-mc/webcodecs-color';
|
|
4
|
+
const defaultMovieSceneDetectionOptions = {
|
|
5
|
+
sensitivity: 'high',
|
|
6
|
+
sampleRate: 'all',
|
|
7
|
+
};
|
|
8
|
+
export async function buildMovieConversionOptions(options) {
|
|
9
|
+
const tracks = options.tracks ?? 'primary';
|
|
10
|
+
const videoTracks = await getSelectedVideoTracks(options.input, tracks, options.videoTrackQuery);
|
|
11
|
+
const videoPlans = new Map();
|
|
12
|
+
await Promise.all(videoTracks.map(async (track) => {
|
|
13
|
+
videoPlans.set(track, await buildMovieVideoConversionOptions({
|
|
14
|
+
track,
|
|
15
|
+
video: options.video,
|
|
16
|
+
resize: options.resize,
|
|
17
|
+
sceneDetection: options.sceneDetection,
|
|
18
|
+
quantizer: options.quantizer,
|
|
19
|
+
colorMetadata: options.colorMetadata,
|
|
20
|
+
forceTranscode: options.forceTranscode,
|
|
21
|
+
}));
|
|
22
|
+
}));
|
|
23
|
+
const firstVideoPlan = videoTracks[0] ? videoPlans.get(videoTracks[0]) ?? null : null;
|
|
24
|
+
const audioTracks = await getSelectedAudioTracks(options.input, tracks);
|
|
25
|
+
return {
|
|
26
|
+
options: {
|
|
27
|
+
input: options.input,
|
|
28
|
+
output: options.output,
|
|
29
|
+
tracks: 'all',
|
|
30
|
+
video: videoTracks.length > 0
|
|
31
|
+
? (track) => videoPlans.get(track)?.options
|
|
32
|
+
: undefined,
|
|
33
|
+
audio: audioTracks.length > 0
|
|
34
|
+
? (track) => audioTracks.includes(track) ? (options.audio ?? {}) : undefined
|
|
35
|
+
: undefined,
|
|
36
|
+
},
|
|
37
|
+
sceneKeyFrames: firstVideoPlan?.sceneKeyFrames ?? null,
|
|
38
|
+
videoColor: firstVideoPlan?.videoColor ?? null,
|
|
39
|
+
resize: firstVideoPlan?.resize ?? null,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export async function buildMovieVideoConversionOptions(options) {
|
|
43
|
+
const sceneKeyFrames = options.sceneDetection !== false
|
|
44
|
+
? new SceneKeyFrameDetector(options.sceneDetection ?? defaultMovieSceneDetectionOptions)
|
|
45
|
+
: null;
|
|
46
|
+
const videoColor = await inspectVideoTrackColor(options.track);
|
|
47
|
+
const resize = options.resize
|
|
48
|
+
? await resolveTrackResize(options.track, options.resize)
|
|
49
|
+
: null;
|
|
50
|
+
return {
|
|
51
|
+
options: makeVideoOptions({
|
|
52
|
+
base: options.video,
|
|
53
|
+
resize,
|
|
54
|
+
sceneKeyFrames,
|
|
55
|
+
quantizer: options.quantizer,
|
|
56
|
+
forceTranscode: options.forceTranscode,
|
|
57
|
+
colorMetadata: options.colorMetadata ?? 'preserve',
|
|
58
|
+
}),
|
|
59
|
+
sceneKeyFrames,
|
|
60
|
+
videoColor,
|
|
61
|
+
resize: resize
|
|
62
|
+
? { width: resize.width, height: resize.height, path: resize.path }
|
|
63
|
+
: null,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
export async function inspectMovie(input, videoTrackQuery) {
|
|
67
|
+
const primaryVideo = await input.getPrimaryVideoTrack(videoTrackQuery);
|
|
68
|
+
if (!primaryVideo)
|
|
69
|
+
return { videoColor: null, scenePlan: null };
|
|
70
|
+
return {
|
|
71
|
+
videoColor: await inspectVideoTrackColor(primaryVideo),
|
|
72
|
+
scenePlan: await planSceneKeyFrames(primaryVideo),
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
export async function inspectVideoTrackColor(track) {
|
|
76
|
+
return {
|
|
77
|
+
colorSpace: await track.getColorSpace(),
|
|
78
|
+
hasHighDynamicRange: await track.hasHighDynamicRange(),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
export async function getSelectedVideoTracks(input, tracks, videoTrackQuery) {
|
|
82
|
+
if (tracks === 'all')
|
|
83
|
+
return input.getVideoTracks(videoTrackQuery);
|
|
84
|
+
const primaryVideo = await input.getPrimaryVideoTrack(videoTrackQuery);
|
|
85
|
+
return primaryVideo ? [primaryVideo] : [];
|
|
86
|
+
}
|
|
87
|
+
export async function getSelectedAudioTracks(input, tracks) {
|
|
88
|
+
if (tracks === 'all')
|
|
89
|
+
return input.getAudioTracks();
|
|
90
|
+
const primaryAudio = await input.getPrimaryAudioTrack();
|
|
91
|
+
return primaryAudio ? [primaryAudio] : [];
|
|
92
|
+
}
|
|
93
|
+
function makeVideoOptions(options) {
|
|
94
|
+
const quantizer = normalizeQuantizerOptions(options.quantizer);
|
|
95
|
+
const keyFrameInterval = options.base?.keyFrameInterval;
|
|
96
|
+
const intervalKeyFrames = quantizer?.split && keyFrameInterval !== undefined
|
|
97
|
+
? new IntervalKeyFrameDetector(keyFrameInterval)
|
|
98
|
+
: null;
|
|
99
|
+
const base = intervalKeyFrames ? omitKeyFrameInterval(options.base) : options.base;
|
|
100
|
+
const forceTranscode = options.colorMetadata === 'canvas-sdr'
|
|
101
|
+
? true
|
|
102
|
+
: (options.forceTranscode ?? Boolean(options.sceneKeyFrames || options.resize || quantizer || intervalKeyFrames));
|
|
103
|
+
const resizeProcess = options.resize
|
|
104
|
+
? makeResizeProcessor(options.resize, options.colorMetadata)
|
|
105
|
+
: undefined;
|
|
106
|
+
const colorProcess = !resizeProcess && options.colorMetadata === 'canvas-sdr'
|
|
107
|
+
? makeCanvasSdrProcessor()
|
|
108
|
+
: undefined;
|
|
109
|
+
const baseProcess = resizeProcess ?? colorProcess;
|
|
110
|
+
const process = options.sceneKeyFrames || quantizer || intervalKeyFrames
|
|
111
|
+
? makeEncodeOptionsProcessor({
|
|
112
|
+
sceneKeyFrames: options.sceneKeyFrames,
|
|
113
|
+
intervalKeyFrames,
|
|
114
|
+
quantizer,
|
|
115
|
+
process: baseProcess,
|
|
116
|
+
})
|
|
117
|
+
: baseProcess;
|
|
118
|
+
return {
|
|
119
|
+
...base,
|
|
120
|
+
forceTranscode,
|
|
121
|
+
process,
|
|
122
|
+
processedWidth: options.resize ? options.resize.width : undefined,
|
|
123
|
+
processedHeight: options.resize ? options.resize.height : undefined,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
function makeEncodeOptionsProcessor(options) {
|
|
127
|
+
return async (sample) => {
|
|
128
|
+
const processed = options.process ? await options.process(sample) : sample;
|
|
129
|
+
const sceneDecision = options.sceneKeyFrames?.detectSample(processed);
|
|
130
|
+
const intervalKeyFrame = options.intervalKeyFrames?.detectSample(processed).keyFrame ?? false;
|
|
131
|
+
const keyFrame = Boolean(sceneDecision?.keyFrame || intervalKeyFrame);
|
|
132
|
+
const quantizer = resolveSampleQuantizer(options.quantizer, keyFrame);
|
|
133
|
+
const encodeOptions = {
|
|
134
|
+
...processed.encodeOptions,
|
|
135
|
+
...(keyFrame ? { keyFrame: true } : {}),
|
|
136
|
+
...(quantizer === undefined ? {} : { quantizer }),
|
|
137
|
+
};
|
|
138
|
+
if (keyFrame || quantizer !== undefined)
|
|
139
|
+
processed.setEncodeOptions(encodeOptions);
|
|
140
|
+
return processed;
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
class IntervalKeyFrameDetector {
|
|
144
|
+
interval;
|
|
145
|
+
keyFrameTimestamps = [0];
|
|
146
|
+
lastKeyFrameTimestamp = 0;
|
|
147
|
+
constructor(interval) {
|
|
148
|
+
this.interval = interval;
|
|
149
|
+
validatePositiveNumber(interval, 'keyFrameInterval');
|
|
150
|
+
}
|
|
151
|
+
detectSample(sample) {
|
|
152
|
+
const keyFrame = sample.timestamp === 0 || sample.timestamp - this.lastKeyFrameTimestamp >= this.interval;
|
|
153
|
+
if (keyFrame) {
|
|
154
|
+
if (sample.timestamp !== 0)
|
|
155
|
+
this.keyFrameTimestamps.push(sample.timestamp);
|
|
156
|
+
this.lastKeyFrameTimestamp = sample.timestamp === 0 ? 0 : this.lastKeyFrameTimestamp + this.interval;
|
|
157
|
+
}
|
|
158
|
+
return { keyFrame, timestamp: sample.timestamp };
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
function normalizeQuantizerOptions(quantizer) {
|
|
162
|
+
if (quantizer === undefined)
|
|
163
|
+
return null;
|
|
164
|
+
if (typeof quantizer === 'number') {
|
|
165
|
+
return { all: validateQuantizer(quantizer, 'quantizer'), split: false };
|
|
166
|
+
}
|
|
167
|
+
return {
|
|
168
|
+
keyFrame: quantizer.keyFrame === undefined ? undefined : validateQuantizer(quantizer.keyFrame, 'quantizer.keyFrame'),
|
|
169
|
+
deltaFrame: quantizer.deltaFrame === undefined ? undefined : validateQuantizer(quantizer.deltaFrame, 'quantizer.deltaFrame'),
|
|
170
|
+
split: true,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
function validateQuantizer(value, name) {
|
|
174
|
+
if (!Number.isFinite(value) || !Number.isInteger(value) || value < 0 || value > 63) {
|
|
175
|
+
throw new RangeError(`${name} must be an integer from 0 to 63.`);
|
|
176
|
+
}
|
|
177
|
+
return value;
|
|
178
|
+
}
|
|
179
|
+
function validatePositiveNumber(value, name) {
|
|
180
|
+
if (!Number.isFinite(value) || value <= 0) {
|
|
181
|
+
throw new RangeError(`${name} must be a positive finite number.`);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
function omitKeyFrameInterval(base) {
|
|
185
|
+
if (!base)
|
|
186
|
+
return undefined;
|
|
187
|
+
const rest = { ...base };
|
|
188
|
+
delete rest.keyFrameInterval;
|
|
189
|
+
return rest;
|
|
190
|
+
}
|
|
191
|
+
function resolveSampleQuantizer(quantizer, keyFrame) {
|
|
192
|
+
if (!quantizer)
|
|
193
|
+
return undefined;
|
|
194
|
+
if (!quantizer.split)
|
|
195
|
+
return quantizer.all;
|
|
196
|
+
return keyFrame ? quantizer.keyFrame : quantizer.deltaFrame;
|
|
197
|
+
}
|
|
198
|
+
async function resolveTrackResize(track, options) {
|
|
199
|
+
const sourceWidth = await track.getDisplayWidth();
|
|
200
|
+
const sourceHeight = await track.getDisplayHeight();
|
|
201
|
+
const size = resolveTargetSize(sourceWidth, sourceHeight, options);
|
|
202
|
+
return {
|
|
203
|
+
width: size.width,
|
|
204
|
+
height: size.height,
|
|
205
|
+
path: 'raw',
|
|
206
|
+
rawAlgorithm: options.rawAlgorithm ?? 'bilinear',
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
function makeResizeProcessor(resize, colorMetadata) {
|
|
210
|
+
return async (sample) => {
|
|
211
|
+
if (sample.displayWidth === resize.width && sample.displayHeight === resize.height) {
|
|
212
|
+
return colorMetadata === 'canvas-sdr' ? convertSampleToCanvasSdr(sample) : sample;
|
|
213
|
+
}
|
|
214
|
+
const frame = sample.toVideoFrame();
|
|
215
|
+
try {
|
|
216
|
+
const resized = await resizeFrameRaw(frame, {
|
|
217
|
+
width: resize.width,
|
|
218
|
+
height: resize.height,
|
|
219
|
+
algorithm: resize.rawAlgorithm,
|
|
220
|
+
});
|
|
221
|
+
if (colorMetadata === 'canvas-sdr') {
|
|
222
|
+
const converted = convertFrameToCanvasSdr(resized.frame);
|
|
223
|
+
resized.frame.close();
|
|
224
|
+
return makeVideoSampleFromFrame(converted.frame, sample, sdrVideoColorSpaceInit(), resize);
|
|
225
|
+
}
|
|
226
|
+
return makeVideoSampleFromFrame(resized.frame, sample, sample.colorSpace.toJSON(), resize);
|
|
227
|
+
}
|
|
228
|
+
finally {
|
|
229
|
+
frame.close();
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
function makeCanvasSdrProcessor() {
|
|
234
|
+
return (sample) => convertSampleToCanvasSdr(sample);
|
|
235
|
+
}
|
|
236
|
+
function convertSampleToCanvasSdr(sample) {
|
|
237
|
+
const frame = sample.toVideoFrame();
|
|
238
|
+
try {
|
|
239
|
+
const converted = convertFrameToCanvasSdr(frame);
|
|
240
|
+
return makeVideoSampleFromFrame(converted.frame, sample, sdrVideoColorSpaceInit(), {
|
|
241
|
+
width: sample.displayWidth,
|
|
242
|
+
height: sample.displayHeight,
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
finally {
|
|
246
|
+
frame.close();
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
function makeVideoSampleFromFrame(frame, sample, colorSpace, size) {
|
|
250
|
+
return new VideoSample(frame, {
|
|
251
|
+
timestamp: sample.timestamp,
|
|
252
|
+
duration: sample.duration,
|
|
253
|
+
colorSpace,
|
|
254
|
+
displayWidth: size.width,
|
|
255
|
+
displayHeight: size.height,
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
function resolveTargetSize(sourceWidth, sourceHeight, options) {
|
|
259
|
+
const alignment = options.dimensionAlignment ?? 2;
|
|
260
|
+
if (options.width === undefined && options.height === undefined) {
|
|
261
|
+
return alignSize({ width: sourceWidth, height: sourceHeight }, alignment);
|
|
262
|
+
}
|
|
263
|
+
if (options.width !== undefined && options.height === undefined) {
|
|
264
|
+
return alignSize({ width: options.width, height: Math.round(sourceHeight * options.width / sourceWidth) }, alignment);
|
|
265
|
+
}
|
|
266
|
+
if (options.height !== undefined && options.width === undefined) {
|
|
267
|
+
return alignSize({ width: Math.round(sourceWidth * options.height / sourceHeight), height: options.height }, alignment);
|
|
268
|
+
}
|
|
269
|
+
const boxWidth = options.width ?? sourceWidth;
|
|
270
|
+
const boxHeight = options.height ?? sourceHeight;
|
|
271
|
+
if ((options.fit ?? 'contain') === 'fill')
|
|
272
|
+
return alignSize({ width: boxWidth, height: boxHeight }, alignment);
|
|
273
|
+
const scale = (options.fit ?? 'contain') === 'cover'
|
|
274
|
+
? Math.max(boxWidth / sourceWidth, boxHeight / sourceHeight)
|
|
275
|
+
: Math.min(boxWidth / sourceWidth, boxHeight / sourceHeight);
|
|
276
|
+
return alignSize({
|
|
277
|
+
width: Math.round(sourceWidth * scale),
|
|
278
|
+
height: Math.round(sourceHeight * scale),
|
|
279
|
+
}, alignment);
|
|
280
|
+
}
|
|
281
|
+
function alignSize(size, alignment) {
|
|
282
|
+
return {
|
|
283
|
+
width: alignDimension(size.width, alignment),
|
|
284
|
+
height: alignDimension(size.height, alignment),
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
function alignDimension(value, alignment) {
|
|
288
|
+
if (alignment === 1)
|
|
289
|
+
return Math.max(1, Math.round(value));
|
|
290
|
+
return Math.max(alignment, Math.floor(Math.round(value) / alignment) * alignment);
|
|
291
|
+
}
|
|
292
|
+
//# sourceMappingURL=conversion-options.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversion-options.js","sourceRoot":"","sources":["../src/conversion-options.ts"],"names":[],"mappings":"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"}
|
package/dist/hls.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { HlsOutputFormat, Input, type ConversionAudioOptions, type ConversionOptions, type ConversionVideoOptions, type HlsOutputFormatOptions, type InputTrackQuery, type InputVideoTrack } from 'mediabunny';
|
|
2
|
+
import { type BrowserMovieColorMetadataPolicy, type BrowserMovieQuantizerOptions, type BrowserMovieResizeOptions, type SceneDetectionOptions } from './conversion-options.js';
|
|
3
|
+
export type MovieHlsAsset = {
|
|
4
|
+
path: string;
|
|
5
|
+
mimeType: string;
|
|
6
|
+
data: ReadableStream<Uint8Array>;
|
|
7
|
+
};
|
|
8
|
+
export type MovieHlsVariantOptions = {
|
|
9
|
+
video?: Omit<ConversionVideoOptions, 'process' | 'forceTranscode' | 'width' | 'height' | 'fit' | 'processedWidth' | 'processedHeight' | 'group'>;
|
|
10
|
+
resize?: BrowserMovieResizeOptions;
|
|
11
|
+
sceneDetection?: false | SceneDetectionOptions;
|
|
12
|
+
quantizer?: BrowserMovieQuantizerOptions;
|
|
13
|
+
colorMetadata?: BrowserMovieColorMetadataPolicy;
|
|
14
|
+
forceTranscode?: boolean;
|
|
15
|
+
keyFrameInterval?: number;
|
|
16
|
+
};
|
|
17
|
+
export type MovieHlsOptions = {
|
|
18
|
+
input: Input;
|
|
19
|
+
variants: MovieHlsVariantOptions[];
|
|
20
|
+
tracks?: ConversionOptions['tracks'];
|
|
21
|
+
videoTrackQuery?: InputTrackQuery<InputVideoTrack>;
|
|
22
|
+
targetDuration?: number;
|
|
23
|
+
rootPath?: string;
|
|
24
|
+
singleFilePerPlaylist?: boolean;
|
|
25
|
+
audio?: ConversionAudioOptions;
|
|
26
|
+
resize?: BrowserMovieResizeOptions;
|
|
27
|
+
sceneDetection?: false | SceneDetectionOptions;
|
|
28
|
+
quantizer?: BrowserMovieQuantizerOptions;
|
|
29
|
+
colorMetadata?: BrowserMovieColorMetadataPolicy;
|
|
30
|
+
forceTranscode?: boolean;
|
|
31
|
+
keyFrameInterval?: number;
|
|
32
|
+
onProgress?: (progress: number, processedTime: number) => unknown;
|
|
33
|
+
};
|
|
34
|
+
export declare function convertMovieToHls(options: MovieHlsOptions): AsyncGenerator<MovieHlsAsset>;
|
|
35
|
+
export declare function createMpegTsHlsFormat(options?: Pick<HlsOutputFormatOptions, 'targetDuration' | 'singleFilePerPlaylist'>): HlsOutputFormat;
|
|
36
|
+
export declare function decodeMovieHlsText(data: Uint8Array): string;
|
|
37
|
+
//# sourceMappingURL=hls.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hls.d.ts","sourceRoot":"","sources":["../src/hls.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,eAAe,EACf,KAAK,EAML,KAAK,sBAAsB,EAC3B,KAAK,iBAAiB,EACtB,KAAK,sBAAsB,EAC3B,KAAK,sBAAsB,EAC3B,KAAK,eAAe,EACpB,KAAK,eAAe,EACrB,MAAM,YAAY,CAAC;AACpB,OAAO,EAIL,KAAK,+BAA+B,EACpC,KAAK,4BAA4B,EACjC,KAAK,yBAAyB,EAC9B,KAAK,qBAAqB,EAC3B,MAAM,yBAAyB,CAAC;AAEjC,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,KAAK,CAAC,EAAE,IAAI,CAAC,sBAAsB,EAAE,SAAS,GAAG,gBAAgB,GAAG,OAAO,GAAG,QAAQ,GAAG,KAAK,GAAG,gBAAgB,GAAG,iBAAiB,GAAG,OAAO,CAAC,CAAC;IACjJ,MAAM,CAAC,EAAE,yBAAyB,CAAC;IACnC,cAAc,CAAC,EAAE,KAAK,GAAG,qBAAqB,CAAC;IAC/C,SAAS,CAAC,EAAE,4BAA4B,CAAC;IACzC,aAAa,CAAC,EAAE,+BAA+B,CAAC;IAChD,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,sBAAsB,EAAE,CAAC;IACnC,MAAM,CAAC,EAAE,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IACrC,eAAe,CAAC,EAAE,eAAe,CAAC,eAAe,CAAC,CAAC;IACnD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,KAAK,CAAC,EAAE,sBAAsB,CAAC;IAC/B,MAAM,CAAC,EAAE,yBAAyB,CAAC;IACnC,cAAc,CAAC,EAAE,KAAK,GAAG,qBAAqB,CAAC;IAC/C,SAAS,CAAC,EAAE,4BAA4B,CAAC;IACzC,aAAa,CAAC,EAAE,+BAA+B,CAAC;IAChD,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,KAAK,OAAO,CAAC;CACnE,CAAC;AAEF,wBAAuB,iBAAiB,CAAC,OAAO,EAAE,eAAe,GAAG,cAAc,CAAC,aAAa,CAAC,CA+BhG;AAED,wBAAgB,qBAAqB,CAAC,OAAO,GAAE,IAAI,CAAC,sBAAsB,EAAE,gBAAgB,GAAG,uBAAuB,CAAM,mBAQ3H;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,UAAU,UAElD"}
|
package/dist/hls.js
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { AppendOnlyStreamTarget, Conversion, HlsOutputFormat, Input, MpegTsOutputFormat, Output, OutputTrackGroup, PathedTarget, Target, } from 'mediabunny';
|
|
2
|
+
import { buildMovieVideoConversionOptions, getSelectedAudioTracks, getSelectedVideoTracks, } from './conversion-options.js';
|
|
3
|
+
export async function* convertMovieToHls(options) {
|
|
4
|
+
if (options.variants.length === 0) {
|
|
5
|
+
throw new Error('convertMovieToHls requires at least one HLS variant.');
|
|
6
|
+
}
|
|
7
|
+
const pending = [];
|
|
8
|
+
let notify = null;
|
|
9
|
+
let conversionDone = false;
|
|
10
|
+
let conversionError = null;
|
|
11
|
+
const pathedTarget = new PathedTarget(options.rootPath ?? 'master.m3u8', (request) => {
|
|
12
|
+
const { readable, writable } = new TransformStream();
|
|
13
|
+
pending.push({ path: request.path, mimeType: request.mimeType, data: readable });
|
|
14
|
+
notify?.();
|
|
15
|
+
return new AppendOnlyStreamTarget(writable);
|
|
16
|
+
});
|
|
17
|
+
runHlsConversion(pathedTarget, options)
|
|
18
|
+
.then(() => { conversionDone = true; notify?.(); })
|
|
19
|
+
.catch((error) => { conversionError = error; conversionDone = true; notify?.(); });
|
|
20
|
+
while (!conversionDone || pending.length > 0) {
|
|
21
|
+
if (pending.length > 0) {
|
|
22
|
+
yield pending.shift();
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
await new Promise((resolve) => { notify = resolve; });
|
|
26
|
+
notify = null;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
if (conversionError)
|
|
30
|
+
throw conversionError;
|
|
31
|
+
}
|
|
32
|
+
export function createMpegTsHlsFormat(options = {}) {
|
|
33
|
+
return new HlsOutputFormat({
|
|
34
|
+
segmentFormat: new MpegTsOutputFormat(),
|
|
35
|
+
targetDuration: options.targetDuration ?? 2,
|
|
36
|
+
singleFilePerPlaylist: options.singleFilePerPlaylist ?? false,
|
|
37
|
+
getPlaylistPath: (info) => `playlist-${info.n}.m3u8`,
|
|
38
|
+
getSegmentPath: (info) => `segment-${info.playlist.n}-${info.n}.ts`,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
export function decodeMovieHlsText(data) {
|
|
42
|
+
return new TextDecoder().decode(data);
|
|
43
|
+
}
|
|
44
|
+
async function runHlsConversion(target, options) {
|
|
45
|
+
const output = new Output({
|
|
46
|
+
target,
|
|
47
|
+
format: createMpegTsHlsFormat({
|
|
48
|
+
targetDuration: options.targetDuration,
|
|
49
|
+
singleFilePerPlaylist: options.singleFilePerPlaylist,
|
|
50
|
+
}),
|
|
51
|
+
});
|
|
52
|
+
const plan = await buildMovieHlsConversionOptions(options.input, output, options);
|
|
53
|
+
const conversion = await Conversion.init(plan);
|
|
54
|
+
if (!conversion.isValid) {
|
|
55
|
+
throw new Error(`Mediabunny could not create a valid HLS conversion: ${conversion.discardedTracks.map((track) => `${track.track.type}:${track.reason}`).join(', ')}`);
|
|
56
|
+
}
|
|
57
|
+
if (options.onProgress)
|
|
58
|
+
conversion.onProgress = options.onProgress;
|
|
59
|
+
await conversion.execute();
|
|
60
|
+
}
|
|
61
|
+
async function buildMovieHlsConversionOptions(input, output, options) {
|
|
62
|
+
const tracks = options.tracks ?? 'primary';
|
|
63
|
+
const videoTracks = await getSelectedVideoTracks(input, tracks, options.videoTrackQuery);
|
|
64
|
+
const audioTracks = await getSelectedAudioTracks(input, tracks);
|
|
65
|
+
const groups = videoTracks.flatMap(() => options.variants.map(() => new OutputTrackGroup()));
|
|
66
|
+
return {
|
|
67
|
+
input,
|
|
68
|
+
output,
|
|
69
|
+
tracks: 'all',
|
|
70
|
+
video: videoTracks.length > 0
|
|
71
|
+
? async (track) => {
|
|
72
|
+
const trackIndex = videoTracks.indexOf(track);
|
|
73
|
+
if (trackIndex === -1)
|
|
74
|
+
return undefined;
|
|
75
|
+
return Promise.all(options.variants.map(async (variant, variantIndex) => {
|
|
76
|
+
const resolved = resolveVariantOptions(options, variant);
|
|
77
|
+
const plan = await buildMovieVideoConversionOptions({
|
|
78
|
+
track,
|
|
79
|
+
video: {
|
|
80
|
+
...resolved.video,
|
|
81
|
+
keyFrameInterval: resolved.keyFrameInterval,
|
|
82
|
+
},
|
|
83
|
+
resize: resolved.resize,
|
|
84
|
+
sceneDetection: resolved.sceneDetection,
|
|
85
|
+
quantizer: resolved.quantizer,
|
|
86
|
+
colorMetadata: resolved.colorMetadata,
|
|
87
|
+
forceTranscode: resolved.forceTranscode,
|
|
88
|
+
});
|
|
89
|
+
return {
|
|
90
|
+
...plan.options,
|
|
91
|
+
group: groups[trackIndex * options.variants.length + variantIndex],
|
|
92
|
+
};
|
|
93
|
+
}));
|
|
94
|
+
}
|
|
95
|
+
: undefined,
|
|
96
|
+
audio: audioTracks.length > 0
|
|
97
|
+
? (track) => audioTracks.includes(track)
|
|
98
|
+
? {
|
|
99
|
+
...options.audio,
|
|
100
|
+
group: groups,
|
|
101
|
+
}
|
|
102
|
+
: undefined
|
|
103
|
+
: undefined,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
function resolveVariantOptions(options, variant) {
|
|
107
|
+
return {
|
|
108
|
+
video: variant.video,
|
|
109
|
+
resize: variant.resize ?? options.resize,
|
|
110
|
+
sceneDetection: variant.sceneDetection ?? options.sceneDetection,
|
|
111
|
+
quantizer: variant.quantizer ?? options.quantizer,
|
|
112
|
+
colorMetadata: variant.colorMetadata ?? options.colorMetadata,
|
|
113
|
+
forceTranscode: variant.forceTranscode ?? options.forceTranscode ?? true,
|
|
114
|
+
keyFrameInterval: variant.keyFrameInterval ?? options.keyFrameInterval ?? options.targetDuration ?? 2,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=hls.js.map
|
package/dist/hls.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hls.js","sourceRoot":"","sources":["../src/hls.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { convertMovieToHls, decodeMovieHlsText, type MovieHlsAsset, type MovieHlsOptions, type MovieHlsVariantOptions } from './hls.js';
|
|
2
|
+
import { buildMovieConversionOptions, inspectMovie, inspectVideoTrackColor, type BrowserMovieColorMetadataPolicy, type BrowserMovieQuantizerOptions, type BrowserMovieResizeFit, type BrowserMovieResizeOptions, type BrowserMovieResizePath, type BrowserMovieTrackColor, type SceneDetectionOptions, type SceneKeyFrameState } from './conversion-options.js';
|
|
3
|
+
export type { BrowserMovieColorMetadataPolicy, BrowserMovieQuantizerOptions, BrowserMovieResizeFit, BrowserMovieResizeOptions, BrowserMovieResizePath, BrowserMovieTrackColor, MovieHlsAsset, MovieHlsOptions, MovieHlsVariantOptions, SceneDetectionOptions, SceneKeyFrameState, };
|
|
4
|
+
export { buildMovieConversionOptions, convertMovieToHls, decodeMovieHlsText, inspectMovie, inspectVideoTrackColor, };
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,sBAAsB,EAC5B,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,2BAA2B,EAC3B,YAAY,EACZ,sBAAsB,EACtB,KAAK,+BAA+B,EACpC,KAAK,4BAA4B,EACjC,KAAK,qBAAqB,EAC1B,KAAK,yBAAyB,EAC9B,KAAK,sBAAsB,EAC3B,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EACxB,MAAM,yBAAyB,CAAC;AAEjC,YAAY,EACV,+BAA+B,EAC/B,4BAA4B,EAC5B,qBAAqB,EACrB,yBAAyB,EACzB,sBAAsB,EACtB,sBAAsB,EACtB,aAAa,EACb,eAAe,EACf,sBAAsB,EACtB,qBAAqB,EACrB,kBAAkB,GACnB,CAAC;AAEF,OAAO,EACL,2BAA2B,EAC3B,iBAAiB,EACjB,kBAAkB,EAClB,YAAY,EACZ,sBAAsB,GACvB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { convertMovieToHls, decodeMovieHlsText, } from './hls.js';
|
|
2
|
+
import { buildMovieConversionOptions, inspectMovie, inspectVideoTrackColor, } from './conversion-options.js';
|
|
3
|
+
export { buildMovieConversionOptions, convertMovieToHls, decodeMovieHlsText, inspectMovie, inspectVideoTrackColor, };
|
|
4
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,kBAAkB,GAInB,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,2BAA2B,EAC3B,YAAY,EACZ,sBAAsB,GASvB,MAAM,yBAAyB,CAAC;AAgBjC,OAAO,EACL,2BAA2B,EAC3B,iBAAiB,EACjB,kBAAkB,EAClB,YAAY,EACZ,sBAAsB,GACvB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@browser-mc/browser-movie-converter",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"import": "./dist/index.js"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"mediabunny": "^1.46.0",
|
|
15
|
+
"@browser-mc/mediabunny-scene-keyframes": "^0.0.1",
|
|
16
|
+
"@browser-mc/webcodecs-color": "^0.0.1"
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist",
|
|
20
|
+
"README.md"
|
|
21
|
+
],
|
|
22
|
+
"publishConfig": {
|
|
23
|
+
"access": "public"
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"prebuild": "pnpm --filter @browser-mc/mediabunny-scene-keyframes build && pnpm --filter @browser-mc/webcodecs-color build",
|
|
27
|
+
"build": "tsc -p tsconfig.json",
|
|
28
|
+
"pretypecheck": "pnpm --filter @browser-mc/mediabunny-scene-keyframes build && pnpm --filter @browser-mc/webcodecs-color build",
|
|
29
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
30
|
+
"test": "pnpm build",
|
|
31
|
+
"test:electron": "pnpm build && env -u ELECTRON_RUN_AS_NODE xvfb-run -a node test/electron-smoke.mjs",
|
|
32
|
+
"test:hls:electron": "pnpm build && env -u ELECTRON_RUN_AS_NODE xvfb-run -a node test/hls-electron-smoke.mjs"
|
|
33
|
+
}
|
|
34
|
+
}
|