subsecond video meme clip trimming
you, a real human
If you're anything like me (I'm so sorry), you occasionally want to send a small part of some video as a meme to your friends. I'm sure a functional human being could hypothetically just link a timestamped url, but that sucks. You need to download a part and transcode a millisecond delimited clip out of it.
Why do you need this? Let's say you may want to send it on a messaging platform that only allows very small files (or you just don't want to be that person that sends 50MB of 3 second clips).
downloading
Pulling in chunks of video is surprisingly very handy (as long as you are on linux or have wsl set up or something. So not that convenient):
uv tool install yt-dlp
yt-dlp --output=example \
--download-sections "*636-650" \
https://example.com/video-path
I think the salient part is --download-sections, which is just followed by a total seconds from and to section. I forgot what the asterisk is for. I know how that sounds, but it works this way so I did not feel like being difficult.
problem solved
No in fact, not solved. The chunking is not perfectly accurate. It will be preceded by some audio you don't want and it will be followed by some audio and video you don't want.
It also comes in whatever format your website sent it to you in. Like webm or some other funky format. I like for them to be h264 encoded mp4, because discord plays those inline on mobile and desktop.
transcoding
So, to trim it properly and to get it in the correct format you need to transcode it. I tried a few GUIs for this because I guess I went temporarily insane. I should have known it would have sucked, because I used to work with video editing software professionally. I remember it being famously temperamental and today it is no different. Weird slowdowns, bad previews, you name it.
Do yourself a good turn: spend decades on a command line and become comfortable with ffmpeg. I was going to write something else, but I realised what it sounded like. It sounded like what I ended up writing. I'm not here to tell you CLIs are good (or even fit for purpose), but I am here to tell you I like them. Probably because of stockholm syndrome :)
getting to it
Expect about 10 iterations of
ffmpeg -i example.webm -c:v h264_nvenc \
-cq:v 36 -profile:v high -rc:v vbr \
-avoid_negative_ts make_zero -ss 00:00:05.995 \
-t 00:00:12.300 example-trim.mp4
which will eventually give you the exact bit of video you want to see.
The important bits are:
-c:v h264_nvenc- If you don't have an nvidia videocard (I'll get hatemail for saying this, but: why?) you're going to want a different video encoder. The tl;dr of that is that you want
libx264.
- If you don't have an nvidia videocard (I'll get hatemail for saying this, but: why?) you're going to want a different video encoder. The tl;dr of that is that you want
-avoid_negative_ts make_zero- This ensures ffmpeg starts counting time at zero, and not negative 3 or something (it varies). There's good reasons (well, reasons) why it does this, but they won't matter to you if you want it to work how any actual human expects at first
-ss 00:00:05.995- It will start the transcode on this timestamp on the source. It's formatted as
hours:minutes:seconds.milliseconds.
- It will start the transcode on this timestamp on the source. It's formatted as
-t 00:00:12.300- It will end the transcode on this timestamp on the source (and not, as the internet implied to me, after this amount of time after
-ss). It's formatted the same as-ss
- It will end the transcode on this timestamp on the source (and not, as the internet implied to me, after this amount of time after
in conclusion
Why did I write this? I spent a few hours getting a workflow that works well, with the correct inputs. This documents it for me. And now you can use it too!