yt-dlp Command Generator for X (Twitter)
Build a yt-dlp command for a video on X, with predictable file names and the options sensitive media requires.
Notes for X
Both x.com and twitter.com URLs work. What people call GIFs on X are really short MP4 videos, so they download like anything else; convert afterwards if you need an actual GIF.
Sensitive-media posts require a logged-in session with the corresponding setting enabled. The default template names files by author and post id, which keeps a folder of them navigable.
X has changed its API surface several times, and the practical consequence is that extractor fixes arrive in yt-dlp updates within days — an install more than a few weeks old is where most "X is broken" reports actually live. Update before debugging: yt-dlp -U. Guest access comes and goes; when it is withdrawn, a logged-in session with cookies is the working route, and that is also the only route to sensitive media.
Threads and quote-posts are where URLs get confusing. A tweet containing a video embeds it; the same video on the profile media tab is a separate entry. For a whole account, the media tab URL fetches everything posted with media, paginated, and the archive file plus keep-going-on-errors handles the deleted posts an active account inevitably accumulates. Search-URL downloads are deliberately not supported here: results drift between requests, and an archive against a moving search is meaningless.
X serves video as HLS fragments with an MP4 fallback in most cases, so merges are common and ffmpeg is the dependency to check first. The "GIF" posts are the exception worth knowing: they arrive as MP4 like everything else, and converting to a real GIF afterwards is a job for ffmpeg, not for yt-dlp — a looping WebM is usually closer to what the sender meant anyway.
Age-restricted and sensitive posts are the hard wall: the setting lives in the account, not the command. Log in through the browser once, enable the sensitive-media setting, hand the cookies over, and it works — no cookie-free workaround exists, because X checks the session server-side. Deleted posts behave like anywhere else: gone is gone, and the mirrors that used to keep copies shut down years ago.