Removing Video Watermarks Entirely in the Browser with MI-GAN, ONNX Runtime Web, and WebGPU A developer built a browser-based video editor that removes watermarks and unwanted objects entirely on the user's device using MI-GAN, ONNX Runtime Web, and WebGPU, eliminating upload latency, infrastructure costs, and privacy concerns. The implementation handles multiple repair regions, moving watermarks, time ranges, progressive frame previews, and final video encoding without sending media to a server. Watermark and unwanted-object removal is one of those features that looks simple in a model demo and becomes much more complicated when you put it inside a real video editor. The obvious implementation is to upload the media to a GPU server, run an inpainting model, and return the result. That works, but it introduces upload latency, infrastructure cost, and privacy concerns—especially for large or unpublished videos. For our browser video editor, we took a different approach: Run MI-GAN locally with ONNX Runtime Web and WebGPU, so images and videos never need to leave the user's device. This article covers more than model inference. It explains the product-level work required for multiple repair regions, time ranges, moving watermarks, progressive frame previews, before/after comparison, cancellation, and final video encoding. Use object-removal tools only on media you own or are authorized to edit. Removing ownership or attribution marks from third-party content may violate licenses or platform rules. A server-side pipeline usually requires: Browser-local inference moves the initial cost to downloading the model. Once the runtime and model artifacts are cached, repeated edits are much faster to start, and the original media remains local. Our implementation uses: Image repair is a single inference task. Video repair has a time axis, so the pipeline is substantially different: php Source media - user defines repair regions and time ranges - resolve regions active at the current timestamp - decode a video frame - build a mask - run MI-GAN inference - composite the repaired pixels over the source frame - commit the progressive preview - encode the processed frame - create a new media asset The model is only one stage. A production-quality experience also requires the canvas, playhead, processed-frame count, and progress indicator to share the same clock. In image mode, the user draws one or more rectangles over the canvas. We store each rectangle in normalized coordinates so the selection remains correct across different preview sizes. js function createMask width, height, regions { const canvas = new OffscreenCanvas width, height ; const context = canvas.getContext "2d" ; context.fillStyle = " 000"; context.fillRect 0, 0, width, height ; context.fillStyle = " fff"; for const region of regions { context.fillRect region.x width, region.y height, region.width width, region.height height ; } return context.getImageData 0, 0, width, height ; } Each region uses values between 0 and 1 . The same rectangle can therefore be mapped back to the full-resolution source instead of the CSS-sized preview. After inference, we do not immediately commit the result. The editor displays a draggable vertical comparison line: