Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Ffmpeg Buddy (evanhahn.github.io)
565 points by thunderbong on June 1, 2022 | hide | past | favorite | 147 comments


Kinda related, here's a few ffmpeg commands i've probably spent many hours getting to work just right recently (and they might not even the right way to do these things), perhaps someone will find it helpful. All of these are on a macbook.

- play facetime camera (or any avfoundation camera, like a capture card) to mpv

  ffmpeg -f avfoundation -video_size 1920x1080  -framerate 30 -drop_late_frames true -i "FaceTime HD Camera" -c:v rawvideo -f matroska -r 30 - | mpv -profile=low-latency -untimed -
- play raw video stream from the usb camlink capture card

  ffmpeg -f avfoundation -video_size 3840x2160 -framerate 23.98 -pixel_format uyvy422 -drop_late_frames true  -i "Cam Link 4K" -c:v rawvideo -f matroska - | mpv -profile=low-latency -untimed -
- Capture video, and do live HVEC hardware encoding on apple hardware and save result. Control quality with q variable. q=85 is around 250Mb/s:

  ffmpeg -f avfoundation -video_size 3840x2160 -framerate 23.98 -i "Cam Link 4K" -c:v hevc_videotoolbox -q:v 85 -r 23.98 -tag:v hvc1 <filename>_x265.mp4
- Use named pipe with mkfifo to play a stream. Sometimes this produces less input lag than other methods.

  mkfifo /tmp/fifo1
  cat /tmp/fifo1 | mpv -profile=low-latency -untimed -
  ffmpeg -f avfoundation -video_size 1920x1080  -framerate 30 -drop_late_frames true -i "FaceTime HD Camera" -c:v rawvideo -f matroska -r 30 - > /tmp/fifo1


Riffing off those, here's a ffmpeg/mpv command to run an audio frequency spectrum visualizer on a live microphone (or a virtual loopback one):

   ffmpeg -f avfoundation -i ":0" -flush_packets 1 -flags low_delay -muxdelay 0.01 -fflags nobuffer -f wav -c copy - | mpv - --profile=low-latency -untimed --lavfi-complex="[aid1]showcqt=fps=30:s=1280x720:count=5:axis=1:axis_h=6:bar_h=100:timeclamp=0.13[vo]" 
Specifically it's using ffmpeg's showcqt[0] filter, which I find to be by far ffmpeg's most beautiful/comprehensible frequency visualizer. In my example `-i ":0"` refers to my microphone at index "0". To find your system's microphone index you can run `ffmpeg -f avfoundation -list_devices true -i ""`.

here's a screenshot: https://dl.dropboxusercontent.com/s/yx5rlgpsmai3kej/showcqt_...

[0] https://ffmpeg.org/ffmpeg-filters.html#showcqt


Nice, thanks, just tried it, that's quite cool, saving it for later! Any reason you are running the filters within the `mpv` command vs within the `ffmpeg` command? I honestly have no idea which way is "better" if any, I think underneath both actually use `libavfilter` library?


They’re both the same really! Though I prefer doing the visualizing in mpv because than it’s easier to switch to different visualizations at runtime. With my mpv config I have obscure keyboard shortcuts that'll switch between different ones. But also possible to do it without mpv entirely.


And in windows batch. record your face with hardcoded timestamp for working on customer systems.

@echo on

setlocal

set ID=IDIDID

set VIDFILENAME=%date:~-4,4%%date:~-10,2%%date:~-7,2%_%time:~0,2%%time:~3,2%%time:~6,2%

echo "-segment_atclocktime 1 "

ffmpeg -loglevel error -rtbufsize 150M -y -f dshow -i video="YOUR HD Camera" -r 10 -f segment -segment_time 1800 -segment_format mp4 -vcodec libx264 -preset fast -threads 1 -crf 28 -tune zerolatency -thread_type slice -slices 1 -intra-refresh 1 -r 10 -g 60 -s 640x480 -aspect 4:3 -b:v 512k -minrate:v 256k -maxrate:v 2.5M -bufsize:v 5M -pix_fmt yuv420p -vf "drawtext=fontfile=/Windows/Fonts/arial.ttf:text='%%{localtime\:%%x %%X}': fontcolor=white@0.8: x=7: y=10" %ID%_%VIDFILENAME%-%%03d.mp4


Please stop using batch files grandpa. PowerShell has been around for 15 years now.


Even ignoring the fact that batch files still have their place in a world where PowerShell exists, that is a needlessly inflammatory reply to someone who shared their knowledge with everyone.


Tell that to the domain admin that keeps overwriting my work laptops registry to not allow powershell scripts to execute..


The first two might be possible with just MPV. Relevant thread on /r/GenkiLab: https://www.reddit.com/r/GenkiLab/comments/mzw9a2/lower_late...


I think I vaguely remembering trying it and eventually gave up as it wasn't working. I believe I arrived at this bug report which still seems open - https://github.com/mpv-player/mpv/issues/8818

Overall I just found it better to leave pretty much everything to the more battle-tested `ffmpeg` and then use mpv to play the content (or can also use ffplay, but I do have have some customizations in mpv which I like).


I wish their was a website were people uploaded their ffmpeg commands and people rated them.

So many bad ffmpeg commands, it's hard to filter them by quality



> - Capture video, and do live HVEC hardware encoding on apple hardware and save result.

Here's what I use to GPU encode/decode multiple IP camera feeds using motion on a 15W haswell system with enough CPU left free for other tasks.

  #motion.conf
  movie_extpipe_use on
  movie_extpipe ffmpeg -y -f rawvideo -pix_fmt yuv420p -video_size %wx%h -framerate %fps -vaapi_device /dev/dri/renderD128 -i pipe:0 -vf 'format=nv12,hwupload' -c:v h264_vaapi %f.mp4
  netcam_params decoder=vaapi,rtsp_transport=tcp,keepalive=off,tolerant_check=on


> q=85 is around 250Mb/s

Is that really true!? 1.8 GB per minute?


Yeah. h265 encoding is quite expensive so to be doing it live there is a tradeoff with speed/size. If you take a look at most cameras (I have Fujifilm XT4), if you're recording at 4k resolution with h265 at 60fps, you're looking at 400Mb/s. Which is still not much compared to something like say ProRes422 (~100MB/s) And nothing compared to raw uncompressed video (recorduing the literal raw video bytes coming uncompressed via HDMI cable) where you can get to something like 1GB/s even (https://www.gammaraydigital.com/blog/just-how-big-are-those-...). In fact in my above commands if you just keep the `rawvideo` format without passing any encoder and try to save to a file, you'll see how large these files can get!

Ever since I started playing with video recording I ended up getting a NAS with 10Gb/s ethernet card, definitely helps!


Some codecs, like h264, require the width and height be divisible by 2. Scaling with -1 will sometimes fail because of that.

If you use -2 instead it will adjust so that it is even.[^1]

For example:

    ffmpeg -i input.mp4 -vf scale=720:-2 output.mp4
[1]: https://trac.ffmpeg.org/wiki/Scaling#KeepingtheAspectRatio


It reminds me of a similar quirk where scaling by a single pixel extra in either dimension can introduce disproportional blurriness, so one solution is to pad by a 1px wide border on the would-be odd dimension.

This has saved me a lot: https://stackoverflow.com/a/53024964/511200


Ooh, if this also used ffmpeg-wasm [1], you could then run the command itself in the browser!

[1] https://github.com/ffmpegwasm/ffmpeg.wasm


Hmmm... not really, irrc you will be bound by memory limits of your browser/wasm context. Small videos would be fine, large ones, not so much...


FWIW we’ve been using ffmpeg-wasm on one of our products [0] for a couple months and the main issue is garbage collection. You’re limited to 4GB memory, but if you don’t kill and restart the workers every N operations it crashes the browser tab (even with proper unlinking of files in the virtual FS).

I suspect you could still make it work with clever usage of the File System Access API as a cache, and process larger files in chunks. Then you’d mostly be limited by the Blob storage limits [1], and memory required to merge processed chunks together.

[0] https://nft-inator.com/app

[1] https://chromium.googlesource.com/chromium/src/+/224e43ce1ca...


It works great for audio. Here's a wasm-ffmpeg solution I created trim audio.

https://wasm-audio-clipper.netlify.app/

Check the repo: https://github.com/marclundgren/wasm-audio-clipper. I ended up lazily registering the context. The memory footprint stays lower even after trimming multiple clips on the same session.


I wonder if this could be used to make video HDR versions of D3 visualizations, making more colors addressable at the cost of reducing interactivity after baking the movie file?


You could! I've done it before but ffmpeg-wasm is also very slow and there are memory limitations that come with WASM as well. At least on Chrome.


The concept of this would be incredibly useful...I use FFmpeg every few weeks, which is not often enough to remember all the commands I need.

But the execution here is a bit lacking. This only lets you input basically 10 parameters.

If this were to be expanded to include all FFmpeg params, it would be INCREDIBLY useful.


You might find this tool useful: https://handbrake.fr/


I don't use FFmpeg for transcoding, more for stream manipulation and frame/stream/subtitle extraction and related tasks, so unfortunately Handbrake isn't really a viable solution.


Maybe https://mkvtoolnix.download/ fits your usecase then. It allows you to select enabled streams, edit metadata and a lot of other things I haven't tried yet for mkv and other container formats.


If you have macOS, check out https://subler.org/ (free, open source).


> I use FFmpeg every few weeks, which is not often enough to remember all the commands I need.

Very Much this. Even the `ffmpeg` incantations I use frequently are tough to recall -- like creating a gif

    `ffmpeg -i input.mkv -vf "fps=8,scale=512:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" -loop 0 output.gif`
The info will be in my notes and `.bash_history`, but less friction recalling it helps stay in context of the incantation called for at the moment that prompted the search. I'll tag, edit, and add notes to running *ffmpeg recipes*[0] when I'm being diligent. This helps reïnforce details for next time, as does reviewing and rubber-ducking here, but still with less-than total recall. What else works to recall more / more quickly? c.f. `awk`, `grep`, `find` and others.

[0] https://smcnally.github.io/kb/ffmpeg%20recipes


https://github.com/mifi/lossless-cut exposes more ffmpeg params.


Would be nice, but also a big task to make a user interface for everything.

The filter chain system, for instance, is quite complicated.

But of course there could be some compromise.


Question for the peanut gallery, because it's vaguely topical and I've spent hours researching problem to no avail.

How can I mux arbitrary data streams into a container? Let's say I have a drone and I want to stream audio, video, and some avionics telemetry.

I know FFMPEG can pass through data encoded, and it lists a few binary stream formats:

     ffmpeg -codecs | grep '^ ..D'  # shows all -c=d codecs

    ..D... bin_data             binary data
    ..D... dvd_nav_packet       DVD Nav packet
    ..D... epg                  Electronic Program Guide
    ..D... klv                  SMPTE 336M Key-Length-Value (KLV) metadata
    ..D... mpegts               raw MPEG-TS stream
    ..D... otf                  OpenType font
    ..D... scte_35              SCTE 35 Message Queue
    ..D... timed_id3            timed ID3 metadata
    ..D... ttf                  TrueType font
But I have no idea how to pack some new data stream into the filtergraph.


With -map. https://trac.ffmpeg.org/wiki/Map

ffmpeg -i input1.mkv -i input2.mkv -i input3.mkv -map 0:v -map 1:a -map 0:d -c copy output.mkv

...will take the video from input1.mkv, the audio from input2.mkv, and the data stream from input3.mkv. If you telemetry isn't already packetized, you'll need to do that yourself. Converting your drone's telemetry into something that ffmpeg likes is generally non-trivial.

At my day job I maintain a tool that takes a .csv file and a raw video file and outputs a single file. Which can then be viewed, with the data displayed on the map and such. https://pro.arcgis.com/en/pro-app/latest/tool-reference/imag...


Many thanks!

> if you telemetry isn't already packetized, you'll need to do that yourself. Converting your drone's telemetry into something that ffmpeg likes is generally non-trivial.

Yes, this is exactly the non-trivial step I'm struggling with. Let's say I have every time step a msgpack-encoded binary blob with a timestamp. I want to packetize it and pack it into a data stream of some timestamped/sequenced packet/page/atom structures. I might be able to build those packets myself manually if I can find a viable format (mkv and ogg seem the easiest to reason about).

And ultimately I do want to do this with real-time streams, but I'll definitely look at this Video Multiplexer to start with! That at least scratches the itch of archiving this data.


Yup, unfortunately (but fortunately for my employer) there's no off the shelf tool that does this. Ultimately you just have to write a bunch of code.

There does exist a standardized way to encode the data: MISB (Motion Imagery Standards Board) ST 0601: https://nsgreg.nga.mil/doc/view?i=5093


How would you get around a live stream with different encoding that FFMGEG couldn't pick up? Like a m83.h file but I think I'm blanking on the name


Is the data packetized and with timestamps?


The data has temporal component, yes. But how would I packetize it in the first place? I have the high-level concept that I need to take each of my data chunks and put them into some kind of timestamped container/page/atom and feed them into the stream, but I have no idea how to actually emit those packets. Like let's say each time step I emit a binary blob of msgpack-encoded data. How do I wrap that with a timestamp/sequence number container?


Something like https://github.com/buma/GPSOverlay might give you some pointers.

Although it's not clear if you want to display your additional data as an overlay (like this example) or keep it as some kind of metadata stream. I'm not sure if the second option is even a thing.


Thanks, but it actually has to be a logical data stream. It's not actually drone GPS, but it's analogous.

It's definitely a thing that exists, I've seen stackoverflow issues talking about working with containers that have these sorts of streams, but for some reason, I've scoured the net and haven't found almost anything about actually writing those streams.


It's interesting. I've heard apocryphally that FFmpeg is used in many production video systems (https://twitter.com/id_aa_carmack/status/1258531455220609025). However, as far as I can tell, you can either use the quite low level libraries like libavfilter, or you can rely on the CLI tool. The former seems rather tedious; you have to set up the scaffolding yourself, chain all the demuxer to the filters to the muxer, etc. The latter is a very weird interface; you have to shell out to this CLI tool. Is that really the case?


I’ve had some luck with PyAV, which I’m pretty sure is just some straight-up Python->C bindings (in case shelling out and starting another process feels too weird. https://pyav.org/docs/stable/

However, I’d note that in my use case, I ended up going back to the shell after running some benchmarks and seeing that for my use case, I wasn’t saving any performance.


Pretty much the entire field contribution system of BBC News uses ffmpeg (or ffmbc, an ffmpeg fork from years back with some specific broadcast related additions) from the commandline (launched from a custom program), has done for about 15 years.


whats the problem with using the cli in production?


Yeah, I don't really see the difference between asking a database administrator to be fluent in SQL and asking a video processing expert to be fluent in ffmpeg (or similar tools).


requires creating a separate process? requires passing the memory from one process to the other.. requires a filesystem & requires the security analysis for having production software interact with the file-system?


> requires a filesystem

Unix has something called pipes that lets you send data as 'files' but they're really supplied as a stream by another process.


One of the nicer things about using a separate process is that resource isolation is much better than in-process. You can kill the process without worrying about mutexes, OS scheduling applies priority consistently, the entire heap is freed once a job completes, there's no worry about leaking resources, and so on.

Even if you could do less I/O by keeping stuff in-process - and I'm not sure that's true if you build your graph in ffmpeg, it's just the source and sink of data which are external, and they'll almost always be external.


I say this with the best of intentions: I wish this went a little farther. A lot of the complexity comes from transcoding options, filters/transformations applied to the video/audio streams, and control of how the file gets put back together.

(And sometimes there are oddities about how they interact, or there is one option that seems very deprecated. It's like Eclipse, it's an engineer's tool, it's extremely powerful but god had no hand in the creation of the UX whatsoever, it is the unholy amalgamation of hundreds of modules that usually work, usually, mostly.)

Give me checkboxes for "resize this video", "convert framerate", "decomb filter", "burn hardsubs filter", a reasonable set of x264 or x265 transcoding options, audio transcoding and downmux, and options for controlling how it all gets reassembled.

It might help to list out some simple use-cases and then look at the ffmpeg features that would be required to get there, and then support those. But again, it's sort of hard to capture everyone's use-cases, ffmpeg is such a swiss-army knife.

Personally I use it for:

* to direct-stream cut (no re-encoding) slices of videos for memes

* to handle game replay captures (sometimes with re-encoding, sometimes not) and combine separate audio tracks into a file for youtube

* to handle game replay captures (always with re-encoding) but with separate audio tracks preserved

* to cut out audio tracks/subs that I don't want from a given movie/show when it becomes annoying

* to transcode a movie/show for archival at the minimum size/maximum quality

etc

In particular I'm not sure how to really tell ffmpeg to handle multiple audio/sub streams without programmatic interaction - you kinda need to know there are 2 audio streams and 4 sub streams, because you need to tell it what to do with each stream you want included in the output file, even if you do the exact same thing to every stream. If you have one show that's a little weird, fine, but without some kind of front-end it gets difficult to handle arbitrary content that is similar but not quite.


Have you had a look at Handbrake (https://handbrake.fr/)?

At least some of your requirements are directly implemented in Handbrake, e.g., there are different transcoding presets [0] and burning in subs [1]. It uses ffmpeg under the hood as well.

[0] https://handbrake.fr/docs/en/1.5.0/technical/official-preset... [1] https://handbrake.fr/docs/en/1.5.0/advanced/subtitles.html


Not op, but I did use Handbrake multiple times, and thinking of just going back to cli ffmpeg. I wanted to see the exact incantation of ffmpeg that Handbrake issues to more easily switch, but from what I saw it doesn't fork into an ffmpeg process but probably uses the library, and it's hard to tell what the exact params are.

My problem with Handbrake was that it wasn't correctly copying creation datetime/makernotes/camera info into the new video and I had to manually later on issue bunch of ffmpeg commands for copying stream metadata, at which point I might as well do the whole conversion directly in ffmpeg.


The thing is depend what you are trying to do. To compress DVD/Blurays, I find handbrake invaluable, because it will automatically deal all kind of weird corner cases in term of pixel format, image ratio, cropping, deinterlacing, etc, that I don't have to write in a command line on every new file (and every disk seems to be doing something different).

But if you are dealing with repeatable, consistent file format (like files coming from the same camera), you are way better off going the command line route, and chances are the command will be pretty simple.


My main gripe with Handbrake is how annoying it is to trim a video. There's no preview of when the trim happens. And for some unknown reason it defaults to a chapter range rather than seconds or frames for trimming...


Yes. I ended up abandoning handbrake for a lot of reasons. For a long time its libraries were horrifically out of date (it was many many major versions behind the x265 trunk) and I don't feel like its "presets"/"batch mode" works properly. I always felt like I was second-guessing whether my manual settings were getting overridden and replaced by presets when inserting a batch.

I could have dived into the log files and looked more closely at what it was doing but, eh, I'm at the level where I just want a batch script where I can see exactly what it's doing upfront. If I want batching/task management that is more advanced than a batchfile can do I'll set up SLURM workload manager.


What's crazy is that there are so so many variations of GUI options for FFMPEG. Typically, the GUI is limited by what the creator's use of FFMPEG tends to be. Which by all means is not a knock against it. It serves a purpose, and if it serves a purpose for them it probably is useful to others in the same way.

Then there are those that want a more generic version that allows all the bells & whistles to become available in the GUI. However, now you need to have a much better understanding of FFMPEG which the vast majority of FFMPEG users don't know (I myself learn new things everytime a new task is given).

At the end of the day, give it a go yourself to build a UI on top of FFMPEG to expose all of the things you just requested and see how painful it can be. I've done it multiple times for multiple jobs and not one of them was the same. It gets even more fun when you have sources with a combination of discrete and interleaved audio streams with high channel counts. Now, you have to probe the source and provide that info to the user to allow for output audio considerations. Based on those, you then need to potentially merge/join/split/map the audio. It's maddingly fun to those with those sense of perversions like me.


The issue with FFmpeg is that it's complex, so you need to understand what all the options do, but the interface is also complex, so you need to understand how to format what you want to do, even if you already have a good understanding of what you want from FFmpeg. E.g. the order of different options matter, applying some options to one stream vs. another, chaining filters together, formatting the filters, specifying the output options, etc.


^An issue with FFMPEG

This isn't THE only issue with FFMPEG. There are many many problems with FFMPEG, but it's the best thing we have in this area. Warts and all, I would probably, no, definitely would not have been able to achieve many of the career accomplishments I have without it.

As you start to reveal the multitude of switches/options/etc available to FFMPEG via GUI, the GUI becomes gnarly and complicated very quickly. This then becomes just as daunting to the avg user as trying to build the command itself. There are many practical uses for a very simplified GUI to achieve a limited set of functionality. There's nothing wrong with it. In fact, I'd be willing to guess that if a UI came along that exposed every single thing that FFMPEG could do, fewer people would use it than a much more simplified version.


Yeah "modules that mostly work, usually, mostly" is no joke. And it's not that anyone really could do anything significantly better than ffmpeg, it is probably one of the best examples besides the kernel of an astonishingly complex library that is run extremely competently but the task space is just maddeningly complex and full of wild edge-cases. Especially when dealing with "legacy" formats and codecs from the 90s and early 00s - even today, have fun transcoding RealVideo or ASF files with some weird color space that nobody has used in 20 years.

There are infamously a lot of tasks that "look easy upfront but have a lot of underlying complexity" and ffmpeg is not one of them. It's a task that looks hard upfront and then when you get down into the weeds it's an eye-bleeding eldritch monstrosity.

The consensus around MP4 and MKV containers and some relatively small number of codecs (H264, H265, VP1, AV1, etc) has substantially eased things but video codecs, audio codecs, and container files are just complicated af.

And believe it or not - this is still way, way better than it used to be! Flaskmpeg was never stable, Virtualdub was nice but development ended with avi container files, there were some forks that added various features, etc, but ffmpeg and OBS Studio both actually just work incredibly well compared to what came before.


>has substantially eased things

except not everyone has decided to use that easing of the things. it seems like they go out of their way to make things difficult

My favorite is in how MP4s are not all the same. A video captured on a DSLR or other acquisition camera source might have +/- in the video/audio sync when imported into an NLE. Yes, the container utilizes PTS syncing to playback the video/audio streams in sync, but this +/- slop in sync is annoying AF to professionals capable of seeing the sync slop. Average consumers probably never notice. I thank all the gawds in all the heavens that I no longer have to edit MP4 source captured content and all of the manual slipping in the NLE.


If you want a single tool/library that does all the things ffmpeg does, I agree. ffmpeg does lots of things, some of them are inherently extremely complex, and it puts them together cohesively. That's impressive! I think the closest competition is gstreamer, and gstreamer ends up calling into ffmpeg for software H.264 decoding...

But...sometimes you want one particular thing, that thing is relatively simple (compared to e.g. H.264 decoding), and you have needs ffmpeg doesn't meet. Then you probably can do better. A couple examples that have come up for me:

* specialized .mp4 muxing. My NVR project does this in a way where it can do HTTP range serving, so put the moov up front, produce the length quickly, and produce a given byte range without iterating through all the bytes before. ffmpeg can't do that, understandably. Hard to do in a general-purpose library; the container muxing input interface doesn't expect all the necessary information is available up front. But it's not that bad as a one-off. As you say, the consensus around a small number of containers really helps.

* RTSP. Consistent with your "modules that mostly work, usually, mostly", ffmpeg has various long-standing bugs in its RTSP handling (e.g. https://trac.ffmpeg.org/ticket/5018), has the risk associated with protocol handling in a non-memory-safe language, doesn't have much of a test framework for this, etc. This problem is relatively approachable (though hardly trivial), so I had success making my own library.


GStreamer has a much more sane CLI interface. FFmpeg generally works better than GStreamer, but it's definitely possible to make a better command line interface.


This is, btw, a great time to plug "bropages". Manpages give you in-depth documentation on what each option does, bropages the idea is to give you a synthesis of an actual task being done with those command options, then you can mix-n-match to fit your use-case (if necessary).

http://bropages.org/ffmpeg

The antidote to ffmpeg's arcane command-line has always been finding someone else who already did it and seeing what they did differently. There are, of course, many ways to skin the cat in ffmpeg, but you often just need to see some finished, working commands and start from there.

You could of course build that on a wiki somewhere, ffmpeg does have various examples in their docs, but bropages is a place to curate that sort of stuff.


For even more brevity, there's tldr [1], which is short-n-sweet "how do I do the most common things with this tool."

You'll need a client for it (tldr itself is just the database). I recommend tealdeer [2].

Example:

    $ tldr tar

      Archiving utility.
      Often combined with a compression method, such as gzip or bzip2.
      More information: <https://www.gnu.org/software/tar>.

      [c]reate an archive and write it to a [f]ile:

          tar cf target.tar file1 file2 file3

      [c]reate a g[z]ipped archive and write it to a [f]ile:

          tar czf target.tar.gz file1 file2 file3
[1]: https://tldr.sh/

[2]: https://github.com/dbrgn/tealdeer


    Often combined with a compression method, such as gzip or bzip2.

    [...]

    [c]reate a g[z]ipped archive and write it to a [f]ile:

       tar czf target.tar.gz file1 file2 file3
That helpful bracketing notation is going to break down as soon as you actually want to deal with bzip2.

There's no real problem, but I never like it when I'm given an example that seems to be going out of its way to suggest something untrue.


Agreed. At this point probably just use CLI.

One thing I hate about CLI tool though, is that it's very hard to edit long commands in terminal.

For example, to replace the input filename from the previous command. I can do it in one second with my keyboard + mouse (use the mouse to select the old one, and type in the new one which would replace) in editor but you can't do so in terminal.

Another example is to change the order of some switches. Again very easy in text editor, not so much in terminal.

So, everytime I use FFMPEG for some complex one (especially when I need to go through trial and error, I have to write the thing in a text editor and them paste them into terminal.


ctrl-x e

> It's a small key sequence: ctrl-x e . What's this do? It takes the existing command that you currently have on your command line and opens it in your shell's editor


It's ctrl-x ctrl-e


> One thing I hate about CLI tool though, is that it's very hard to edit long commands in terminal.

Apart from the "wrap it in a shell script" advice, I would also note that in a bash-like terminal, home and end will jump to the start or the end of the current command buffer, and ctrl-del (or alt-del maybe?) or ctrl-arrow keys usually delete or move the cursor a whole word at a time, which makes it somewhat quicker to work rather than sitting there holding an arrow key or backspce.

Many here probably already know this, some may not!


Thanks, yeah I know these since I use them heavily in editor as well.

Now this got me thinking: the main problem with terminal is that it doesn't seem to support "cut" (and consequently, "paste to replace selection"). So re-arranging a command string is always gonna be a pain regardless the complexity.

I can see why it was this way historically, but not exactly sure why no modern terminal emulator gives this feature, even as optional.


one analogy might be the "cut and accumulate" feature in nano (and probably others) where a line is removed and appended to the clipboard, then you can paste and all those lines will be pasted off the clipboard at once. You could do that at a character level in the shell, if you wanted. No idea if any shells do though.


ctrl-a and ctrl-e to start/end of line


>One thing I hate about CLI tool though, is that it's very hard to edit long commands in terminal.

Only a madman would do this. I don't know anyone that's in the middle of R&D that builds directly in the CLI that's sane. Everyone tries it, and just at the point of losing sanity, does the rational thing of building the command in a text editor for a simple copy&paste into the CLI later.


Yep, or turn it into a script and use an IDE/Vim/etc and test in the terminal.


To me the most intuitive and flexible UI would be something like Avidemux where you have a picker of filters/transforms and you can add them to a box on the right (potentially you can add them multiple times, etc) and then configure them. That is a very powerful "general" UI flow that works reasonably well imo.

But yeah you're right, it's all a question of how much capability you want to surface, because the more you surface the more quickly it gets complex and inscrutable to anyone not in the know.


> In particular I'm not sure how to really tell ffmpeg to handle multiple audio/sub streams without programmatic interaction - you kinda need to know there are 2 audio streams and 4 sub streams, because you need to tell it what to do with each stream you want included in the output file, even if you do the exact same thing to every stream.

I made a script that converts all the videos in a directory above a certain bitrate to H.265 to save space and found that just using the flags `-map 0` to grab every stream, and `-c:s copy` was enough to avoid having to probe the source for every stream since subtitles were the most problematic if any streams were bitmaps. It then checks if there were any errors before replacing the original video. I still get the occasional outlier that I either fix by hand or just leave as is.

Also the script was written with python and argparse, so it would be relatively easy for me to create a GUI with Gooey[1] if there was interest.

[1] https://github.com/chriskiehl/Gooey


I've been using ffmpeg-python recently, and it will do a lot of the crazy complex transforms for you, and you can write sane python code vs. trying to deal with the crazy default ffmpeg syntax.

https://github.com/kkroening/ffmpeg-python


A good reason why it cannot be web based, you need to scan the source video to be useful, so you know which tracks are available (some subtitles aren't supported by ffmpeg). If you merge two files the fps or resolution might not be compatible. I think this calls more for a (or rather multiple) desktop apps.


My most common use case is to make something fit into a certain file size. It usually takes a few tries with 2 pass encoding to get an audio bitrate/downmix, video bitrate, framerate and resizing to find one I like. It would be great to automate that.


The way I typically approach this personally is to have a batch script that kicks off a couple "trial" encodes that run with "medium" quality (which will run reasonably fast) and then once I've identified an appropriate CRF value then I run a final encode with "placebo" quality.

Once I have identified a target CRF then I just apply that value to all similar files. I'm personally not concerned about exact size, I'm not squeezing them onto discs or anything, so having one file be 690mb and the next one be 695 mb is fine.

Contrary to the name, and contrary to popular belief: yes, placebo does still improve quality noticeably even over veryslow, when you are squeezing bitrate very hard. Actually typically you will get a noticeably smaller file than medium/slow (10% reduction is not atypical) and the quality will be better than veryslow. This applies less when you are giving adequate levels of bandwidth but when you are really squeezing the bitrate to the absolute limit (I've been known to use values in the CRF 31-37 range at some times to really go hard), going deeper into motion search yields more benefits. Like, you probably could still benefit from going even farther (placebo is just a preset tuning some motion-search parameters and you could tune them even higher).

At a minimum, veryslow does produce very significant quality gains over medium even if you don't want to go all the way to placebo though. Worth it for archival for sure.

And typically, the situation where I'm hand-tuning a file to hit an exact file limit... are ones where I'm seriously pushing the limits in terms of what I can fit into a given attachment-uploader file size limit or something. So when I am targeting a fixed file size I am almost always squeezing hard.

There's no perfect solution to avoid the trial-and-error process though, imo. Automated solutions can produce something reasonable but not optimal in terms of exactly hitting your filesize limit at the maximum possible quality. Tuning it down to the last MB, or deciding to resize a video to give a bit more motion bandwidth, isn't something that they can generally do.

Personally I don't worry about audio too much - 160kbps AAC or MP3 is fine and anything too far below that starts to get potentially noticeably poor. If something has DTS or AC3 yeah, I'm transcoding because nothing will play that on the internet, but if it's reasonably close I'll just copy source to avoid generational losses fromt anscoding. Yeah, sometimes a reduction in resolution can produce big gains with little noticeable quality gain... and sometimes (especially with anime/cartoons) a high-res file has so little high-frequency data that going big barely affects file size at all. Tune mode can also help a little bit at the edges.

I never mess with framerate or bit depth/color space unless I absolutely have to, though. Too many pitfalls there.


Check out Hybrid, it's the most full featured GUI codec tool I know. Amazing tool for video pros.


https://www.selur.de/ is where Hybrid can be found.

Not associated, just find it easier to link to something useful.


Hybrid or Hybrik now owned by Dolby?


https://github.com/EvanHahn/ffmpeg-buddy

If ya can maybe help em out and send a pull request? I think it's a neat little app and will take a look at it myself.


I'm an FFMPEG newb, but I can't find anything that handles subtitles correctly by default. Just leave all of the subtitles on (it's not like they take up any appreciable amount of space compared to the audio and video streams). If the output format requires a different type of subtitle, just convert it (rather than omitting the subtitle altogether). It's surprising to me that everyone has to learn FFMPEG in all of its complexity to do relatively basic things.


Subtitles are not a "basic thing". There's several formats of subtitles and even multiple ways to associate them with a video file. Some formats are embedded and others are sidecar files. Different file containers have different limitations on the subtitle formats they support. Just because a subtitle is ostensibly "text" doesn't automatically make them basic.


I am aware that subtitles aren’t “merely text” and that different container formats constrain the subtitle format and number of tracks and so on. Still, this is simple compared to much of the stuff we use software for. Complexity abounds everywhere and yet lots of software manages to bring order to the chaos. There’s no reason this shouldn’t also apply to subtitles.

A trivial example is to try to convert the subtitles rather than defaulting to no subtitles (Handbrake). Another trivial improvement would be warning that the subtitles can’t be brought over to the container format before the 20 hour transcode rather than letting users find out after that their subtitles weren’t converted.

This isn’t rocket science.


> In particular I'm not sure how to really tell ffmpeg to handle multiple audio/sub streams without programmatic interaction

This is what gets me every time. I'm relatively proficient with ffmpeg (relatively!) but for the life of me I can never remember how to switch audio sub streams or drop some of them, etc.

And yes, one first needs to find out what's where, but there are many UI tools that can do this (in addition to ffprobe).


Something that always frustrated me is how much better avisynth is than ffmpeg on pretty much every axis. Some of this is just because VFW puts any linux video stack look like a bit of a joke, but even something limited to the features internal to ffmpeg using the avs language would be better than this crazy -map -vf -af -filter_complex bag of command line options.


>Some of this is just because VFW puts any linux video stack look like a bit of a joke

What's the joke? I thought using VFW in 2022 was pretty hillarious of a suggestion. Maybe you got the punchline confused? ;P

AVISynth died to me long long ago as it was just no longer pratical. The work arounds to get 10bit video was never stable by the time I dropped it.

I did enjoy the scripting aspect of things like you suggest, but that's meh at this point. Now that my brain has been rewired to think FFMPEG like, the frustration goes away. It's a steep hill to climb without question, but eventually, it just goes "click".


1. I suspect we have very different needs. I've never worked with 10 bit video, for example.

2. The closest equivalent to VFW in linux is not ffmpeg but gstreamer. My experience with the latter is ... not good.

3. ffmpeg is great when it does what you need but VFW lets you draw from a vast ocean of third party plugins that do all sorts of niche things.


I didn't mean for anything to come off as snobby/leetish.

1)yes, if you're not needing 10bit, then AVISynth is fun and does some amazing things. Even it's features of doing technical restoration were useful, but once you step into professional, the 8bit only really holds things back and it was time to move on. FYI, a lot of the AVISynth filters are now available in FFMPEG!

2)gstreamer compared to ffmpeg to me personally is like comparing GIMP to Photoshop (dropping commercial vs FOSS). Yes, GIMP can do nice things, but Photoshop does what I need and I know how to make it do it. No questions asked. Muscle memory. I'm at that point with FFMPEG.

3)I'm long past trying to do creative things CLI that those 3rd party plugins allowed. I'm utilitarian with workflows and need to churn it out, so ffmpeg plugs in the holes as if it were designed for it ;-) If I'm going creative, I'm in a nice UI and doing things. However, I'm not afraid to use CLI to generate some content to messing with later in a more interactive environment.


Yeah, once you get above a basic level of filter complexity, Vapoursynth/Avisynth become much easier to script. The problem is that it's hard to do the initial setup of *synth.


I just use Kden Live for anything at all complicated. It basically just generates an ffmpeg command anyway.


These are the easy ones. What would be amazing is the arcane incantations that mere mortals don't remember.

Another tool that this is nice for is imagemagick. Is there something newer than imagemagick for image generation these days? I'm having trouble with some non English scripts and draw text


Indeed, these are very basic stuff, which may be useful for some people's workflow, but then by the time I started remember this website, I'll probably have already memorized the few flags the website profiles anyways.

In my experience, you're just better off searching for what you need, in my experience you'll always find a bunch of results with the exact ffmpeg incantation you need for your specific rare usecase.


For a long time, I've wanted an interactive Imagemagick interface that allows you to add/tweak flags and shows an immediate preview. The Imagemagick site has something sorta like this[0] but it's not very good.

My current workflow is to open the image in a viewer that automatically reloads on change, like feh or sxiv, and then in my terminal use <M-a> to run the command without clearing the command line.

[0]: https://magickstudio.imagemagick.org/scripts/MagickStudio.cg...


Have you tried/considered trying it in an svg and then converting to a raster format?


ffmpeg is a really powerful tool that's well worth learning. It's become my go to for almost every video, audio, and still image task.

One thing that might help: ffmpeg is, in fact, the Unix philosophy of "do one thing and do it well", it just so happens that all the commands are prefixed by the ffmpeg command, but you can break things down really easily after that. Each codec is independent, mappings are independent, filters, etc.


Something I don't think many talk about, the fact that ffmpeg can input and output images, and does it really quick.

Recently I was working on processing large images (100-200MB per jpg) which needed a crop, some added text and "progress bar" for a timelapse. I started with imagemagick, it was super slow, so tried graphicsmagick, also slow, just somehow I thought, why not try ffmpeg. Man, it's night and day difference. It processed my images super quick (from ~30 seconds down to ~1 second), and had surprisingly good documentation (compared to IM/GM), and allot of support on stackoverflow etc.


I ended up making something similar (except in reverse) for the x264 options you can pass in: http://axxim.net/~clone1018/tools/x264.html


Question: this tool offered start-time and end-time, but no toggle about "accurate seek"? I've always been confused about the `-noaccurate_seek` flag (when cutting clips with `-c copy`).

I use this flag because I don't need accurate seek, but sometimes it works, sometimes it doesn't. When it doesn't work, there will be a few seconds of frozen image at the beginning of the cut. Don't know how to solve it.


Isn't that only relevant because you're using -c copy? Without transcoding, ffmpeg will just copy the stream from that start-time. But because video codecs store data as incremental updates to a keyframe, without transcoding, those first few seconds will be useless data. -noaccurate_seek looks for the keyframe so you do not have that useless data.

Proper terms are i-frame and p-frame. https://en.wikipedia.org/wiki/Video_compression_picture_type...

Though according to the ffmpeg docs on -ss, it should be doing noaccurate_seeks if you're doing stream copy.

Also I'm unsure about this, but I think the audio stream can be cut at a different location than the video stream, leading to the frozen frame, and different video players seem to handle it differently. I've got a clip I've made, with transcoded video stream but copied audio stream, that is 1:06 on Firefox with the extra audio at the beginning, but 1:03 on VLC, MPC, Chrome, and desynced in Edge. Extracting the audio with ffmpeg again gives a time of 1:04.02 compared to a video stream of 1:03.


I think I once read a comment on here that the command-line parsing logic of ffmpeg is Turing-complete. It's probably telling that I can't remember if that was meant as a joke or to be taken seriously. And I say this with nothing but admiration for the tool.


Also made something similar to this, inspired by HandBrake:

https://alfg.github.io/ffmpeg-commander/


That is really nice! Thank you — that will definitely help me learn how to build ffmpeg commands.


What about a decoder, to parse ffmpeg command from my old bash file to tell exactly what it is doing, maybe even suggesting some optimizations?


Pfah, if my wishes were so simple I'd barely need the man page.


I would use this tool if it had these options:

- x264 settings as well as copy video codec

- aac re-encoding settings

- mixing 5.1 to 2.1 audio

- adding multiple subtitles

- rendering hard subtitles

I was just using ffmpeg to convert videos to watch on the TV and I needed all of those.


Neat tool and a fine introduction to doing very basic things with ffmpeg. A tool I'd find interesting and useful is one that lets me graphically do everything with the advanced filter graph that can be done with the commandline, in an easy and intuitive way (spoiler alert: extremely hard to impossible task)


Last time I went down the ffmpeg man page rabbit hole was when I needed to vertically stack (and temporally align) feeds from multiple timelapse cameras to make videos for IG stories.

As soon as the carefully curated string of option configurations went into a script, it also evaporated from my brain. Oh well.. til next time.


Selecting both scale and rotate options results in:

  Multiple -filter, -af or -vf options specified for stream 0, only the last option '-filter:v transpose=1' will be used.
-vn, -an, -ss, and -to are specified as output rather than input options, which are much more efficient.


just from this comment, using -filter_complex seems like a much better option. in fact, on past experience, I couldn't see myself building an FFMPEG command builder and not use filter_complex.


I see that we're sharing our lists of magical FFmpeg incantations – here's mine: https://github.com/doersino/ffmpeg-koraktor


See also

https://github.com/FHPythonUtils/Cli2Gui/

It's 2022, shouldn't CLI to GUI conversion be an automatic and core feature of every OS by now?


This is excellent. Is there something like this for ImageMagick as well?


A nice start, but definitely needs some complex_filter options


Isn't the better solution for most users a GUI tool like Avidemux?[1] The point being that those who want to use the command line are precisely the people who need to understand all its complexity.

---

[1] https://avidemux.org. Avidemux has a "built-in libavcodec library from FFmpeg (i.e. Avidemux contains its own copy of libavcodec, external FFmpeg is not used)"


I wanted to make something like this (minus the gui) for a long time... thank you very much OP, I am bookmarking this.


So if you remove the GUI you'll only have the CLI, so what you want is the ffmpeg CLI?


Yes, often what would happen is by the time I figured out the flags, I'd lost the creative idea of what I wanted to make a gif for. Usually I was using them as replies on Twitter, but they banned me from there and Reddit so I have less need to make GIFs.

I knew how to in Photoshop etc, before they moved to the cloud so they can be paid in perperuity even though a lot of the advanced/useful features like layers or cropping etc are in more basic tools like Preview or GIMP now.

(GIMP needs to get a macOS friendly rewrite similar to how folks did KeePassXC imho, but I'm not a strong enough coder and no large open source friendly companies seems to want to pay me a salary to direct projects like that, so all I can do is halfway troll here on HN, but it comes from a place of love.)


I'm not the parent, but not necessarily. You can have this same exact "GUI" implemented as a TUI, using something like Bubble Tea[0], Textual[1], or by hand. You'd get a similar experience without having to go back and forth between the terminal and a browser.

[0]: https://github.com/charmbracelet/bubbletea

[1]: https://github.com/Textualize/textual


Thank you! Sorry, I have a lot of projects going at once and I'm working on a new system to organize "TODOS" - I'll bookmark your comment to return to, thank you for your thoughts, sincerely.


So a TUI?


A TUI FFMPEG builder would be delicious. Just a terminal powered graphical interface that lets me manipulate options, and feedback validation, would make it so much easier to work with complex graphs.


Make video streamable (start playing when usable bits are available). Recently needed this for an auto-playing video background [1]:

"ffmpeg.exe" -i "in.mp4" -c copy -movflags faststart "out.mp4"

[1]https://beta.gsc.edu.ph



Regarding scaling while maintaining ratio, some codecs will give an error if you try to put a size that isn't a multiple of n, for example if you put -2 you'll actually have it calculate the appropriate multiple of 2.


The first time I heard about ffmpeg was last night when I had to concatenate a few hundred thousand videos. So slick, so quick, but it took a bit to figure out the command structure. Guess I found this 12 hours too late, haha!


A few hundred thousand videos? I'm super curious what your use case was. I really can't imagine the scenario for this :)


I'm guessing security camera motion detection footage for archive.


Very cool. I would love to see something like that with more ffmoeg options


Why is this a webpage? It would be a little more useful as a local program that actually just runs the command for you instead of having to copy-paste everything to your terminal.


A webapp is automatically cross-platform, and also installing a program requires more buy-in from a user. I wouldn't have played around with this if I had to vet whether it was from a trustworthy source and install it to my machine.


> It would be a little more useful as a local program that actually just runs the command for you instead of having to copy-paste everything to your terminal.

That's already available: https://handbrake.fr/


Seems like this would be nice to have an an interactive shell script(or compiled, for cross platform support) that ships alongside ffmpeg...


Can I have magit for ffmpeg and openssl, please?


I love when a website does something simple, practical, and does it with a clean interface. Excellent


I have been looking for something like this for years without realizing it. Top form! Top form!


This is as simple as revolutionary. Thank you so much for putting this together!


This will definitely come in handy!

Something like this for PANDOC would be great as well


Eh, thanks, but I don't want a Web-based solution.


all of these I know by head.

the difficult part is to combine vaapi, codecs, re-encode audio without re-encode video (and vice versa), codec lists, etc


Would also love to see a vlc buddy.



I really wanted that to be a hat.


Oh neat. Thanks!


Looks great, now do the other million available options.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: