Trim a video

Cut a video down to the part you want, and remove the bits in the middle you do not, all in this browser tab.

How it works

Most video trimmers send your file to a server first, which means a wait, and a copy of your footage on someone else’s disk. This one does the whole cut inside your browser tab.

The tool holds an edit list rather than a single start and end, so you can take a section out of the middle and the parts either side are joined back together. Cuts are frame accurate: the clip is re-encoded to MP4 rather than sliced at the nearest keyframe, so the cut lands exactly where you put the handle.

The first trim downloads the video engine, about 30 MB, and caches it for next time. Because the clip is re-encoded, expect the export to take roughly as long as the part you kept.

How to use it

  1. 1 Choose a video (MP4, MOV or WebM) or a GIF.
  2. 2 Drag the two handles around the part you care about.
  3. 3 Press “Keep only this”, or “Cut this out” to drop a section from the middle.
  4. 4 Export the trim, and download the MP4.

Good to know

  • Take out as many sections as you like. What is left is joined back together in order.
  • Arrow keys nudge a handle by a tenth of a second, and Shift moves it a full second.
  • Undo steps back through your cuts, and Reset starts the clip over.
  • Your video is never uploaded. The whole trim runs in this browser tab.

Browser support

  • Chrome 94 and later
  • Firefox 113 and later · full speed from 130
  • Safari 16.4 and later
  • Edge 94 and later

These are the oldest versions with everything the tool uses. They are worked out from the tool itself, so they change when it does.

Version numbers checked on 2026-09-04.

A cut lands where you put it, or it lands on the nearest keyframe

Ask a browser-based trimmer for the ten seconds starting at 0:32 and there is a good chance you get the ten seconds starting at 0:29. The reason is that the cheap way to cut a video is not to cut it at all. H.264 stores most frames as differences from earlier ones, and only every couple of seconds does it store a complete picture, a keyframe. Copy the compressed stream instead of re-encoding it and you can only begin at one of those complete pictures, because everything after one is meaningless without it. That copy is close to instant and loses nothing, and the price is that your in-point silently moves to wherever the previous keyframe happened to be. On phone footage that is usually one or two seconds and sometimes ten. This tool re-encodes instead, which costs roughly the duration of the clip you kept, and buys a cut that lands on the frame you chose.

Once cuts are frame accurate the interesting question is what the tool should remember. A start and an end is the obvious answer and it stops being enough the moment somebody wants a cough removed from the middle, because that is two ranges, and taking a second piece out of one of those is three. So the state here is a list of kept segments in source time, and every edit is a transform of that list. Removing a range walks the list once: segments the cut misses are copied, a segment the cut lands inside becomes two, and one the cut merely overlaps has an edge moved. Keeping a range is the same function called twice, once on everything before the selection and once on everything after, which is why the two buttons in the interface share all of their logic. Pieces shorter than fifty milliseconds are dropped rather than encoded, because dragging a handle to almost the start of a clip leaves a sliver nobody meant to keep and some encoders refuse outright.

That list compiles to ffmpeg arguments in a way chosen for speed, because the obvious compilation is slow in exactly the case people reach for. A kept range becomes an input seek: -ss placed before -i lets the decoder jump to the keyframe before that point instead of decoding from zero, and decoding carries on from there only as far as the frame you asked for, so the cut is still exact. The duration goes in as -t rather than -to, because -to as an input option has a long history of ambiguity about whether it counts from the start of the file or from the seek point, and a flag that is sometimes wrong is worse than a flag that is longer to write. Several kept ranges each get the same treatment as a separate seeked input of the same file, and a filter graph does nothing but concatenate them. That was not the first design. Trimming every range out of a single decode from zero is the textbook graph and produces the same frames, but it decodes everything between the ranges on the way to them, so keeping two half-minute pieces two hours apart in a lecture recording took around two and a half minutes that way, most of it spent decoding footage that was thrown away, and about six seconds as separate inputs, with every output frame identical.

The filter graph is also where a missing audio track stops being a detail. Concatenation is declared with a fixed number of streams per segment, so a graph that asks for audio from a file that has none does not quietly produce a silent video, it fails the whole encode. GIFs have no audio, and neither do plenty of screen recordings and drone clips. The tool therefore asks before it builds the graph, by running ffmpeg against the input with no output file at all: that prints the stream table and then exits complaining, having decoded nothing, and the stream table is the answer. Video-only inputs get a graph with no audio branch and an explicit -an, and everything else gets both.

GIFs need one more thing before they can go on a timeline, which is a duration, and the browser will not give one. A GIF cannot be loaded into a video element, so there is nothing to ask. Reading it directly turns out to be cheap, because the answer is in the headers rather than in the pixels: a GIF is a sequence of blocks, each frame preceded by a graphic control extension carrying its delay in hundredths of a second, and walking that structure while skipping over colour tables and image data gives both the frame count and the total running time without ever decompressing an image. The delays need one correction that is not in the specification. Every major browser renders a delay of zero or one hundredth as a tenth of a second instead, a compatibility rule inherited from the animated-GIF era, so a hundred-frame GIF full of zero delays really does run for ten seconds and the timeline has to say so. Output is padded to even dimensions as well, since H.264 requires them and GIFs are frequently odd.

The progress bar is derived from ffmpeg’s own output rather than from the library that wraps it. That wrapper computes progress as a ratio against the input duration, which is documented as accurate only when the input and the output are the same length, and trimming is precisely the operation that guarantees they are not: a ten second cut from a ten minute source would crawl to one per cent and stop. Reading the time= field out of the encoder log lines and dividing by the total kept duration is both simpler and correct in the only case that matters here.

Frequently asked questions

How do I cut the middle out of a video?

Drag the handles around the part you want gone and press “Cut this out”. The pieces either side are joined back together, and you can do it as many times as you need.

Why does trimming take a while instead of being instant?

Because the clip is re-encoded, so the cut lands exactly where you put the handle. Slicing at the nearest keyframe is instant, but it can miss by several seconds, which is the usual reason a trimmed clip starts in the wrong place.

Does trimming lose quality?

A re-encode is never quite lossless, but this one is set so you can’t see the difference rather than to make a small file. If you also need to hit a size limit, run the result through the video compressor afterwards.

Can I trim a GIF?

Yes. A GIF can’t be scrubbed in a browser, so you set the cut points by time. The export is an MP4, which plays anywhere and is much smaller than a GIF.

Is my video uploaded to a server?

No. The whole trim runs inside your browser tab.

Related tools

Your files are processed on your device and are not uploaded. You can verify this in your browser’s developer tools under the Network tab.