+1
-1
package.json
+1
-1
package.json
+23
-17
pnpm-lock.yaml
+23
-17
pnpm-lock.yaml
···
129
129
idb:
130
130
specifier: ^8.0.3
131
131
version: 8.0.3
132
+
mediabunny:
133
+
specifier: ^1.25.7
134
+
version: 1.25.7
132
135
nanoid:
133
136
specifier: ^5.1.6
134
137
version: 5.1.6
···
138
141
solid-js:
139
142
specifier: ^1.9.10
140
143
version: 1.9.10(patch_hash=9cf3f9930aa2f8d4e60502a75153adf9468eb53b42f69e86cac05dfaea3f82e7)
141
-
webm-muxer:
142
-
specifier: ^5.1.4
143
-
version: 5.1.4
144
144
devDependencies:
145
145
'@badrap/valita':
146
146
specifier: ^0.4.6
···
1575
1575
'@types/dom-close-watcher@1.0.0':
1576
1576
resolution: {integrity: sha512-7pL0By56sVVGMSJ3HdSY+u08Id0ljStCaf1VnGFxwfpuNdA0HMz0sl2J24eSi9M6ptl9ySkVK35jF75Fn8trUg==}
1577
1577
1578
+
'@types/dom-mediacapture-transform@0.1.11':
1579
+
resolution: {integrity: sha512-Y2p+nGf1bF2XMttBnsVPHUWzRRZzqUoJAKmiP10b5umnO6DDrWI0BrGDJy1pOHoOULVmGSfFNkQrAlC5dcj6nQ==}
1580
+
1581
+
'@types/dom-webcodecs@0.1.13':
1582
+
resolution: {integrity: sha512-O5hkiFIcjjszPIYyUSyvScyvrBoV3NOEEZx/pMlsu44TKzWNkLVBBxnxJz42in5n3QIolYOcBYFCPZZ0h8SkwQ==}
1583
+
1578
1584
'@types/dom-webcodecs@0.1.18':
1579
1585
resolution: {integrity: sha512-vAvE8C9DGWR+tkb19xyjk1TSUlJ7RUzzp4a9Anu7mwBT+fpyePWK1UxmH14tMO5zHmrnrRIMg5NutnnDztLxgg==}
1580
1586
···
1592
1598
1593
1599
'@types/trusted-types@2.0.7':
1594
1600
resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==}
1595
-
1596
-
'@types/wicg-file-system-access@2020.9.8':
1597
-
resolution: {integrity: sha512-ggMz8nOygG7d/stpH40WVaNvBwuyYLnrg5Mbyf6bmsj/8+gb6Ei4ZZ9/4PNpcPNTT8th9Q8sM8wYmWGjMWLX/A==}
1598
1601
1599
1602
acorn-walk@8.3.2:
1600
1603
resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==}
···
2075
2078
2076
2079
magic-string@0.25.9:
2077
2080
resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==}
2081
+
2082
+
mediabunny@1.25.7:
2083
+
resolution: {integrity: sha512-DL0E1h29HTDaD9bYRXLSSHiAoLbDBksrdYS+4OHWA+aNhQeN+CAGEG7EU6wlhPZ8MOpwXIeC7uv06lo4ziohQQ==}
2078
2084
2079
2085
merge-anything@5.1.7:
2080
2086
resolution: {integrity: sha512-eRtbOb1N5iyH0tkQDAoQ4Ipsp/5qSR79Dzrz8hEPxRX10RWWR/iQXdoKmBSRCThY1Fh5EhISDtpSc93fpxUniQ==}
···
2655
2661
webidl-conversions@4.0.2:
2656
2662
resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==}
2657
2663
2658
-
webm-muxer@5.1.4:
2659
-
resolution: {integrity: sha512-ditzgFVFbfqPaugkIr4mGhAdob5K9HY6Rzlh7TRsA368yA1sp/m5O7nQCcMLdgFDeNGtFPg8B+MeXLtpzKWX6Q==}
2660
-
deprecated: This library is superseded by Mediabunny. Please migrate to it.
2661
-
2662
2664
whatwg-url@7.1.0:
2663
2665
resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==}
2664
2666
···
4114
4116
4115
4117
'@types/dom-close-watcher@1.0.0': {}
4116
4118
4119
+
'@types/dom-mediacapture-transform@0.1.11':
4120
+
dependencies:
4121
+
'@types/dom-webcodecs': 0.1.18
4122
+
4123
+
'@types/dom-webcodecs@0.1.13': {}
4124
+
4117
4125
'@types/dom-webcodecs@0.1.18': {}
4118
4126
4119
4127
'@types/estree@0.0.39': {}
···
4127
4135
'@types/resolve@1.20.2': {}
4128
4136
4129
4137
'@types/trusted-types@2.0.7': {}
4130
-
4131
-
'@types/wicg-file-system-access@2020.9.8': {}
4132
4138
4133
4139
acorn-walk@8.3.2: {}
4134
4140
···
4575
4581
magic-string@0.25.9:
4576
4582
dependencies:
4577
4583
sourcemap-codec: 1.4.8
4584
+
4585
+
mediabunny@1.25.7:
4586
+
dependencies:
4587
+
'@types/dom-mediacapture-transform': 0.1.11
4588
+
'@types/dom-webcodecs': 0.1.13
4578
4589
4579
4590
merge-anything@5.1.7:
4580
4591
dependencies:
···
5088
5099
vite: 7.2.6(@types/node@24.10.1)(jiti@1.21.7)(terser@5.44.1)
5089
5100
5090
5101
webidl-conversions@4.0.2: {}
5091
-
5092
-
webm-muxer@5.1.4:
5093
-
dependencies:
5094
-
'@types/dom-webcodecs': 0.1.18
5095
-
'@types/wicg-file-system-access': 2020.9.8
5096
5102
5097
5103
whatwg-url@7.1.0:
5098
5104
dependencies:
+19
-25
src/components/composer/workers/gif-conversion.ts
+19
-25
src/components/composer/workers/gif-conversion.ts
···
1
1
import { expose } from 'comlink';
2
-
import { ArrayBufferTarget, Muxer } from 'webm-muxer';
2
+
import { BufferTarget, Output, VideoSample, VideoSampleSource, WebMOutputFormat } from 'mediabunny';
3
3
4
4
export type GifWorkerApi = typeof api;
5
5
const api = {
···
9
9
10
10
const frameCount = decoder.tracks.selectedTrack!.frameCount;
11
11
12
-
let muxer: Muxer<ArrayBufferTarget>;
13
-
let encoder: VideoEncoder | undefined;
14
-
15
12
if (frameCount === 0) {
16
13
throw new Error(`GIF has no frames`);
17
14
}
18
15
19
-
for (let idx = 0, configured = false; idx < frameCount; idx++) {
20
-
const { image } = await decoder.decode({ frameIndex: idx });
21
-
22
-
if (!configured) {
23
-
const width = image.displayWidth;
24
-
const height = image.displayHeight;
16
+
let output: Output<WebMOutputFormat, BufferTarget>;
17
+
let videoSource: VideoSampleSource;
25
18
26
-
configured = true;
19
+
{
20
+
const { image } = await decoder.decode({ frameIndex: 0 });
27
21
28
-
muxer = new Muxer({
29
-
target: new ArrayBufferTarget(),
30
-
video: { codec: 'V_VP9', width, height },
31
-
});
22
+
output = new Output({
23
+
format: new WebMOutputFormat(),
24
+
target: new BufferTarget(),
25
+
});
32
26
33
-
encoder = new VideoEncoder({
34
-
output: (chunk) => muxer.addVideoChunk(chunk),
35
-
error: (err) => console.error(err),
36
-
});
27
+
videoSource = new VideoSampleSource({ codec: 'vp9', bitrate: 1e6 });
28
+
output.addVideoTrack(videoSource);
37
29
38
-
encoder.configure({ codec: 'vp09.00.10.08', width, height });
39
-
}
30
+
await output.start();
31
+
await videoSource.add(new VideoSample(image));
32
+
}
40
33
41
-
encoder!.encode(image);
34
+
for (let idx = 1; idx < frameCount; idx++) {
35
+
const { image } = await decoder.decode({ frameIndex: idx });
36
+
await videoSource.add(new VideoSample(image));
42
37
}
43
38
44
-
await encoder!.flush();
45
-
muxer!.finalize();
39
+
await output.finalize();
46
40
47
-
const buffer = muxer!.target.buffer;
41
+
const buffer = output.target.buffer!;
48
42
return new Blob([buffer], { type: 'video/webm' });
49
43
},
50
44
};