Skip to main content

Command Palette

Search for a command to run...

I made a video editor with mediabunny, a library that AI thinks doesn't exist

Updated
5 min readView as Markdown
I made a video editor with mediabunny, a library that AI thinks doesn't exist
T

software developer && gamer passionate about software development && games ... catch my twitch streams on twitch where I stream: https://twitch.tv/techygrrrl

About 2 days ago, I learned that you can use web APIs to edit video.

In the past, I've used ffmpeg, which is an amazing open-source cross-platform command line tool that pretty much every company uses for their video editing. If an app processes video, you can guess it uses ffmpeg under the hood and you'd probably be right 99% of the time. In the past, I made a video editing CLI tool called sf6vid specifically to censor player data when sharing Street Fighter 6 replays and compress the video files so it can be more easily shared on social media services where gamers hang out (without having to pay for a premium subscription to said platforms).

This has served me for a while, but I find I wasn't heavily using the censoring functionality, and the resizing functionality was only slightly less complicated (and much less powerful) than using ffmpeg directly, so I ended up switching to using the trim feature in Microsoft Photos, and then Handbrake to shrink it down to share.

This multi-step process was a bit annoying, so when I learned a couple days ago that I could use web technologies, I thought why not try—it'll allow me to build a video editor in JavaScript that can live as a static website, without having to worry about (paying for) a backend.

Technologies

The following technologies were used:

  • TypeScript as the language

  • React as the UI library/framework/whatever

  • Tailwind CSS with my custom Tailwind theme for the stylesheet layer

  • Mediabunny for video manipulation

  • Vite for build tooling, and various other defaults it configured for me:

    • Rolldown for bundling

    • Babel for the TypeScript -> JavaScript stuff

    • oxlint for blazingly fast™ linting

  • Radix's UI slider for the range slider with 2 handles (this is buggy on mobile so I might end up replacing it)

  • Cloudflare Pages for free static webpage hosting

The main function that does the important part is called processVideo and at the time of writing, it looks like this:

/**
 * Perform the video trimming and compression
 */
const processVideo = useCallback(async () => {
  if (!file) return;
  setIsProcessing(true);

  try {
    const input = new Input({
      source: new BlobSource(file),
      formats: ALL_FORMATS,
    });

    const output = new Output({
      format: new Mp4OutputFormat(),
      target: new BufferTarget(),
    });

    const trimStart = trimRange[0]
    const trimEnd = trimRange[1]
    const bitrate = getBitrateForQuality(quality)
    const hardwareAcceleration = getHardwareAcceleration(encoder)

    const conversion = await Conversion.init({
      input,
      output,
      tracks: 'primary',
      video: {
        fit: 'contain',
        width: scaledWidth,
        height: scaledHeight,
        hardwareAcceleration,
        bitrate,
      },
      audio: {
        discard: shouldRemoveAudio,
        bitrate,
      },
      trim: {
        start: trimStart,
        end: trimEnd,
      },
      tags: {},
    });

    await conversion.execute();

    const buffer = output.target.buffer!;
    const processedBlob = new Blob([buffer], { type: 'video/mp4' });
    const processedUrl = URL.createObjectURL(processedBlob);

    const audioMeta = shouldRemoveAudio ? ' - No Audio - ' : ''
    const timestamp = `${formatDuration(trimStart * 1000)} to ${formatDuration(trimEnd * 1000)}`
    const filename = `${file.name} - ${scaledWidth}x${scaledHeight} - ${quality} - ${timestamp}${audioMeta}.mp4`;

    downloadFile({
      linkToFile: processedUrl,
      filename,
    })
  } catch (error) {
    console.error("Video processing failed:", error);
  } finally {
    setIsProcessing(false);
  }
}, [file, trimRange, scaledHeight, scaledWidth, quality, encoder, shouldRemoveAudio]);

The magic is done using their Conversion API.

You can see the rest of the source code on Github: https://github.com/techygrrrl/trimrrr

You can see a screenshot of what it looks like below.

Is mediabunny new? Gemini AI doesn't even know about it

This isn't a real question. This can be easily verified by looking at their Github releases, which shows their first release v1.0.0 is just over 1 year old! 🚀

I was feeling a bit lazy and decided to ask Gemini AI to implement the mediabunny API for me. Turns out, Gemini is convinced it doesn't exist and that I should use ffmpeg.

...

This part got me:

If mediabunny is a proprietary internal library, a newly released package, or a specific cloud-based media API unique to your environment, you will need to provide its official documentation or type definitions.

If I'm gonna do all that I might as well read those things myself lol

Again, I am reminded to stop being lazy and just RTFM (Read the F-ing Manual). I know it's the old school way but it's also infinitely less frustrating, because you can take your time to learn about the APIs and all the other things it offers. Also, their documentation search feature is really good. I found out how to do exactly what I needed to do by doing the following:

  • looking at their examples, specifically ones that closely resemble the task I'm trying to perform

  • reading their documentation for the API in said example

(instructions above provided for those who think they need AI to code... you don't, you can do it, I believe in you)

But yes, mediabunny is fairly new, and it looks like slop machines haven't slurped up implementations of it yet and therefore cannot slop out implementations.

While publishing this post: 2nd!

I decided to stop being lazy, read the docs, and then easily found my answer much quicker than it took a server to consume more drinking water in one prompt than I do in an afternoon. I really should drink more water though...

Conclusion

In conclusion, here are your takeaways:

  • It's now possible to do video processing in the browser, and this is made extremely easy using mediabunny (but I guess it was possible before with ffmpeg WASM too, I hadn't tried that though)

  • Here's the video editor if you want to use it: https://trimrrr.pages.dev

  • Here's the source code if you want to see it: https://github.com/techygrrrl/trimrrr

  • RTFM'ing rules, AI drools

  • I need to drink more water

  • In about a month, job posts will start saying "Must have 10 years of mediabunny experience"

Try it out, let me know what you think and if you find any bugs. You can file a bug in the issue queue here.

K

first day at Hashnode,and saw your post ,wow amazing...

N

Interesting 👍🏼