personal web client for Bluesky
typescript solidjs bluesky atcute

refactor: migrate to mediabunny

mary.my.id f5d87790 f54f22f0

verified
Changed files
+43 -43
src
components
composer
+1 -1
package.json
··· 44 44 "nanoid": "^5.1.6", 45 45 "solid-floating-ui": "~0.2.1", 46 46 "solid-js": "^1.9.10", 47 - "webm-muxer": "^5.1.4" 47 + "mediabunny": "^1.25.7" 48 48 }, 49 49 "devDependencies": { 50 50 "@badrap/valita": "^0.4.6",
+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
··· 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 };