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.