Add quotes, move assets around
@@ -47,6 +47,6 @@
|
||||
color: hsl(345, 100%, 85%);
|
||||
}
|
||||
|
||||
body {
|
||||
overflow-x: hidden;
|
||||
html, body {
|
||||
overflow-x: hidden !important;
|
||||
}
|
||||
|
After Width: | Height: | Size: 329 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 115 KiB After Width: | Height: | Size: 115 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#000000"><path d="M480-320 280-520l56-58 104 104v-326h80v326l104-104 56 58-200 200ZM240-160q-33 0-56.5-23.5T160-240v-120h80v120h480v-120h80v120q0 33-23.5 56.5T720-160H240Z"/></svg>
|
||||
|
After Width: | Height: | Size: 278 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="none" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="M3 7V5a2 2 0 0 1 2-2h2m10 0h2a2 2 0 0 1 2 2v2m0 10v2a2 2 0 0 1-2 2h-2M7 21H5a2 2 0 0 1-2-2v-2"/><rect width="10" height="8" x="7" y="8" rx="1"/></g></svg>
|
||||
|
After Width: | Height: | Size: 339 B |
@@ -0,0 +1 @@
|
||||
<svg width="98" height="96" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M48.854 0C21.839 0 0 22 0 49.217c0 21.756 13.993 40.172 33.405 46.69 2.427.49 3.316-1.059 3.316-2.362 0-1.141-.08-5.052-.08-9.127-13.59 2.934-16.42-5.867-16.42-5.867-2.184-5.704-5.42-7.17-5.42-7.17-4.448-3.015.324-3.015.324-3.015 4.934.326 7.523 5.052 7.523 5.052 4.367 7.496 11.404 5.378 14.235 4.074.404-3.178 1.699-5.378 3.074-6.6-10.839-1.141-22.243-5.378-22.243-24.283 0-5.378 1.94-9.778 5.014-13.2-.485-1.222-2.184-6.275.486-13.038 0 0 4.125-1.304 13.426 5.052a46.97 46.97 0 0 1 12.214-1.63c4.125 0 8.33.571 12.213 1.63 9.302-6.356 13.427-5.052 13.427-5.052 2.67 6.763.97 11.816.485 13.038 3.155 3.422 5.015 7.822 5.015 13.2 0 18.905-11.404 23.06-22.324 24.283 1.78 1.548 3.316 4.481 3.316 9.126 0 6.6-.08 11.897-.08 13.526 0 1.304.89 2.853 3.316 2.364 19.412-6.52 33.405-24.935 33.405-46.691C97.707 22 75.788 0 48.854 0z" fill="#24292f"/></svg>
|
||||
|
After Width: | Height: | Size: 963 B |
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="none" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><rect width="4" height="16" x="14" y="4" rx="1"/><rect width="4" height="16" x="6" y="4" rx="1"/></g></svg>
|
||||
|
After Width: | Height: | Size: 283 B |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="none" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m6 3l14 9l-14 9z"/></svg>
|
||||
|
After Width: | Height: | Size: 207 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="none" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 4.702a.705.705 0 0 0-1.203-.498L6.413 7.587A1.4 1.4 0 0 1 5.416 8H3a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h2.416a1.4 1.4 0 0 1 .997.413l3.383 3.384A.705.705 0 0 0 11 19.298z"/></svg>
|
||||
|
After Width: | Height: | Size: 359 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="none" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 4.702a.705.705 0 0 0-1.203-.498L6.413 7.587A1.4 1.4 0 0 1 5.416 8H3a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h2.416a1.4 1.4 0 0 1 .997.413l3.383 3.384A.705.705 0 0 0 11 19.298zM16 9a5 5 0 0 1 0 6"/></svg>
|
||||
|
After Width: | Height: | Size: 378 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="none" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 4.702a.705.705 0 0 0-1.203-.498L6.413 7.587A1.4 1.4 0 0 1 5.416 8H3a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h2.416a1.4 1.4 0 0 1 .997.413l3.383 3.384A.705.705 0 0 0 11 19.298zM16 9a5 5 0 0 1 0 6m3.364 3.364a9 9 0 0 0 0-12.728"/></svg>
|
||||
|
After Width: | Height: | Size: 409 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="none" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 9a5 5 0 0 1 .95 2.293m2.414-5.657a9 9 0 0 1 1.889 9.96M2 2l20 20M7 7l-.587.587A1.4 1.4 0 0 1 5.416 8H3a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h2.416a1.4 1.4 0 0 1 .997.413l3.383 3.384A.705.705 0 0 0 11 19.298V11M9.828 4.172A.686.686 0 0 1 11 4.657v.686"/></svg>
|
||||
|
After Width: | Height: | Size: 437 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="none" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 4.702a.705.705 0 0 0-1.203-.498L6.413 7.587A1.4 1.4 0 0 1 5.416 8H3a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h2.416a1.4 1.4 0 0 1 .997.413l3.383 3.384A.705.705 0 0 0 11 19.298zM22 9l-6 6m0-6l6 6"/></svg>
|
||||
|
After Width: | Height: | Size: 377 B |
@@ -409,7 +409,7 @@ The following audio sample formats are supported:
|
||||
|
||||
Planar formats store each channel's data contiguously, while interleaved formats store the channels' data interleaved together:
|
||||
|
||||

|
||||

|
||||
|
||||
### Inspecting audio samples
|
||||
|
||||
|
||||
@@ -17,9 +17,90 @@ hero:
|
||||
- theme: alt
|
||||
text: Examples
|
||||
link: /examples
|
||||
- theme: alt
|
||||
text: Sponsors
|
||||
link: "#sponsors"
|
||||
---
|
||||
|
||||
<div class="space-y-16 mt-8">
|
||||
<script setup>
|
||||
import AvatarKonstantin from './assets/avatar-konstantin.png';
|
||||
import AvatarYonatan from './assets/avatar-yonatan.jpeg';
|
||||
|
||||
const quotes = [
|
||||
{
|
||||
quote: 'The missing part in the JS ecosystem for building web-first media apps.',
|
||||
author: 'Yonatan, Gling AI',
|
||||
image: AvatarYonatan,
|
||||
url: 'https://www.gling.ai/',
|
||||
},
|
||||
{
|
||||
quote: 'Mediabunny gives you low-level control with high-level ease. It’s fast, lightweight, and finally feels like media processing built for the web, not ported to it.',
|
||||
author: 'Konstantin, Diffusion Studio',
|
||||
image: AvatarKonstantin,
|
||||
url: 'https://github.com/k9p5',
|
||||
}
|
||||
];
|
||||
|
||||
const benchmarks = [
|
||||
{
|
||||
name: 'Extract metadata',
|
||||
unit: 'ops/s',
|
||||
results: [
|
||||
{ name: 'Mediabunny', value: 1000/1.16 },
|
||||
{ name: '@remotion/media-parser', value: 1000/4.28 },
|
||||
{ name: 'web-demuxer', value: 1000/12.4 },
|
||||
{ name: 'mp4box.js', value: 1000/23 },
|
||||
{ name: 'ffmpeg.wasm', value: 1000/547 },
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'Iterate over all video packets',
|
||||
unit: 'packets/s',
|
||||
results: [
|
||||
{ name: 'Mediabunny', value: 10800 },
|
||||
{ name: 'web-demuxer', value: 2390 },
|
||||
{ name: '@remotion/media-parser', value: 842 },
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'Convert to .webm & resize to 320x180',
|
||||
unit: 'frames/s',
|
||||
results: [
|
||||
{ name: 'Mediabunny', value: 804 },
|
||||
{ name: '@remotion/webcodecs', value: 324 },
|
||||
{ name: 'ffmpeg.wasm', value: 12 },
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
const bundleSizes = [
|
||||
{ name: 'Reading .wav files', size: 5.1 },
|
||||
{ name: 'Writing .wav files', size: 5.79 },
|
||||
{ name: 'Writing .webm files', size: 11.36 },
|
||||
{ name: 'Reading .webm files', size: 15.2 },
|
||||
{ name: 'Reading .mp4 files', size: 16.03 },
|
||||
{ name: 'Writing .mp4 files', size: 17.28 },
|
||||
{ name: 'Reading all formats', size: 30.02 },
|
||||
{ name: 'mp4box.js', size: 37.3, isThirdParty: true },
|
||||
{ name: 'All features', size: 69.62 },
|
||||
{ name: '@remotion/webcodecs', size: 87.2 + 20.8, isThirdParty: true },
|
||||
];
|
||||
</script>
|
||||
|
||||
<div class="flex gap-4 flex-wrap justify-center items-center">
|
||||
<div v-for="quote in quotes" class="bg-(--vp-c-bg-soft) w-80 p-4 rounded-2xl flex shrink-0 flex-col relative">
|
||||
<svg class="size-8 absolute -top-3 left-2.5 text-(--vp-c-gray-1)" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill="currentColor" d="M12 12a1 1 0 0 0 1-1V8.558a1 1 0 0 0-1-1h-1.388q0-.527.062-1.054q.093-.558.31-.992t.559-.683q.34-.279.868-.279V3q-.868 0-1.52.372a3.3 3.3 0 0 0-1.085.992a4.9 4.9 0 0 0-.62 1.458A7.7 7.7 0 0 0 9 7.558V11a1 1 0 0 0 1 1zm-6 0a1 1 0 0 0 1-1V8.558a1 1 0 0 0-1-1H4.612q0-.527.062-1.054q.094-.558.31-.992q.217-.434.559-.683q.34-.279.868-.279V3q-.868 0-1.52.372a3.3 3.3 0 0 0-1.085.992a4.9 4.9 0 0 0-.62 1.458A7.7 7.7 0 0 0 3 7.558V11a1 1 0 0 0 1 1z"/></svg>
|
||||
<p class="!my-0 flex-1 text-sm !leading-6">{{ quote.quote }}</p>
|
||||
<div class="shrink-0 flex gap-2 items-center mt-1.5">
|
||||
<a :href="quote.url" target="_blank">
|
||||
<img :src="quote.image" class="size-8 rounded-full shrink-0" alt="Author image">
|
||||
</a>
|
||||
<p class="!my-0 flex-1 text-xs font-medium">{{ quote.author }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="space-y-16 mt-18">
|
||||
<div class="flex flex-col lg:flex-row lg:gap-20 lg:items-center">
|
||||
<div class="flex-1 min-w-0">
|
||||
<h1 class="inline-block" style="background: -webkit-linear-gradient(-30deg, #ff45ac, #ff78c2); -webkit-background-clip: text; color: transparent;">Read any media file, efficiently</h1>
|
||||
@@ -139,7 +220,7 @@ await conversion.execute();
|
||||
<div class="flex flex-col-reverse lg:flex-row gap-4 lg:gap-20 lg:items-center">
|
||||
<div class="relative flex-1 min-w-0">
|
||||
<div class="absolute size-70 rounded-full bg-[#ff45ac]/0 top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 blur-[200px]" />
|
||||
<img class="relative" src="./inspiring-io.svg">
|
||||
<img class="relative" src="./assets/inspiring-io.svg">
|
||||
</div>
|
||||
<div class="flex-1 min-w-0">
|
||||
<h1 class="inline-block" style="background: -webkit-linear-gradient(-30deg, #ff45ac, #ff78c2); -webkit-background-clip: text; color: transparent;">Universal I/O</h1>
|
||||
@@ -158,64 +239,17 @@ await conversion.execute();
|
||||
</div>
|
||||
<div class="grid place-items-center relative flex-1 min-w-0">
|
||||
<div class="absolute size-70 rounded-full bg-[#ff45ac]/0 top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 blur-[200px]" />
|
||||
<img class="relative" src="./codec-soup.svg">
|
||||
<img class="relative" src="./assets/codec-soup.svg">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script setup>
|
||||
const benchmarks = [
|
||||
{
|
||||
name: 'Extract metadata',
|
||||
unit: 'ops/s',
|
||||
results: [
|
||||
{ name: 'Mediabunny', value: 1000/1.16 },
|
||||
{ name: '@remotion/media-parser', value: 1000/4.28 },
|
||||
{ name: 'web-demuxer', value: 1000/12.4 },
|
||||
{ name: 'mp4box.js', value: 1000/23 },
|
||||
{ name: 'ffmpeg.wasm', value: 1000/547 },
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'Iterate over all video packets',
|
||||
unit: 'packets/s',
|
||||
results: [
|
||||
{ name: 'Mediabunny', value: 10800 },
|
||||
{ name: 'web-demuxer', value: 2390 },
|
||||
{ name: '@remotion/media-parser', value: 842 },
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'Convert to .webm & resize to 320x180',
|
||||
unit: 'frames/s',
|
||||
results: [
|
||||
{ name: 'Mediabunny', value: 804 },
|
||||
{ name: '@remotion/webcodecs', value: 324 },
|
||||
{ name: 'ffmpeg.wasm', value: 12 },
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
const bundleSizes = [
|
||||
{ name: 'Reading .wav files', size: 5.1 },
|
||||
{ name: 'Writing .wav files', size: 5.79 },
|
||||
{ name: 'Writing .webm files', size: 11.36 },
|
||||
{ name: 'Reading .webm files', size: 15.2 },
|
||||
{ name: 'Reading .mp4 files', size: 16.03 },
|
||||
{ name: 'Writing .mp4 files', size: 17.28 },
|
||||
{ name: 'Reading all formats', size: 30.02 },
|
||||
{ name: 'mp4box.js', size: 37.3, isThirdParty: true },
|
||||
{ name: 'All features', size: 69.62 },
|
||||
{ name: '@remotion/webcodecs', size: 87.2 + 20.8, isThirdParty: true },
|
||||
];
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col-reverse lg:flex-row gap-4 lg:gap-20 lg:items-center">
|
||||
<div class="space-y-8 flex-1 min-w-0">
|
||||
<div v-for="benchmark in benchmarks" class="space-y-2">
|
||||
<p class="text-center font-medium text-sm !mt-0 !mb-2">{{ benchmark.name }}</p>
|
||||
<div v-for="result, i in benchmark.results" class="flex items-center gap-2">
|
||||
<p :class="{ '!text-[#ff78c2]': i === 0 }" class="!my-0 shrink-0 font-medium w-40 text-xs whitespace-nowrap text-right">{{ result.name }}</p>
|
||||
<div class="h-8 bg-[var(--vp-c-gray-2)] rounded-md" :style="{ width: `calc(${result.value / Math.max(...benchmark.results.map(x => x.value))}*(100% - 7.5rem - 10rem))`, background: i === 0 ? '-webkit-linear-gradient(-30deg, #ff45ac, #ff78c2)' : undefined }" />
|
||||
<div class="h-8 bg-(--vp-c-gray-2) rounded-md" :style="{ width: `calc(${result.value / Math.max(...benchmark.results.map(x => x.value))}*(100% - 7.5rem - 10rem))`, background: i === 0 ? '-webkit-linear-gradient(-30deg, #ff45ac, #ff78c2)' : undefined }" />
|
||||
<p :class="{ '!text-[#ff78c2]': i === 0, 'opacity-50': i > 0 }" class="!my-0 text-xs w-30">{{ result.value < 100 ? result.value.toPrecision(3) : Math.floor(result.value) }} {{ benchmark.unit }}</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -236,7 +270,7 @@ const bundleSizes = [
|
||||
<p class="text-center font-medium text-sm !mt-0 !mb-2">Bundle size, minified + gzipped</p>
|
||||
<div v-for="result in bundleSizes" class="flex items-center gap-2">
|
||||
<p :class="{ '!text-[#ff78c2]': !result.isThirdParty }" class="!my-0 shrink-0 font-medium w-40 text-xs whitespace-nowrap text-right">{{ result.name }}</p>
|
||||
<div class="h-8 bg-[var(--vp-c-gray-2)] rounded-md" :style="{ width: `calc(${result.size / Math.max(...bundleSizes.map(x => x.size))}*(100% - 7.5rem - 10rem))`, background: !result.isThirdParty ? '-webkit-linear-gradient(-30deg, #ff45ac, #ff78c2)' : undefined }" />
|
||||
<div class="h-8 bg-(--vp-c-gray-2) rounded-md" :style="{ width: `calc(${result.size / Math.max(...bundleSizes.map(x => x.size))}*(100% - 7.5rem - 10rem))`, background: !result.isThirdParty ? '-webkit-linear-gradient(-30deg, #ff45ac, #ff78c2)' : undefined }" />
|
||||
<p :class="{ '!text-[#ff78c2]': !result.isThirdParty, 'opacity-50': result.isThirdParty }" class="!my-0 text-xs w-30">{{ result.size < 100 ? result.size.toPrecision(3) : Math.floor(result.size) }} kB</p>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
@@ -249,4 +283,4 @@ const bundleSizes = [
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||