Show HN: FFmpeg-over-IP – Connect to remote FFmpeg servers (github.com)
I’m excited to show case a personal project. It has helped me quite a bit with my home lab, I hope it can help you with yours too! ffmpeg-over-ip has two components, a server and a client. You can run the server in an environment with access to a GPU and a locally installed version of ffmpeg, the client only needs network access to the server and no GPU or ffmpeg locally.
Both and client and the server need a shared filesystem for this to work (so the server can write output to it, and client can read from it). In my usecase, smb works well if your (GPU) server is a windows machine, nfs works really well for linux setups.
This utility can be useful in a number of scenarios:
- You find passing through a (v)GPU to your virtual machines complicated
- You want to use the same GPU for ffmpeg in multiple virtual machines
- Your server has a weak GPU so you want to use the GPU from your gaming machine
- Your GPU drivers in one OS are not as good as another (AMD RX6400 never worked for me in linux, but did so in windows)
I’ve posted some instructions in the Github package README, please let me know if they are unclear in any way and I’ll try to help!
Here's the link: https://github.com/steelbrain/ffmpeg-over-ip
75 comments
[ 3.2 ms ] story [ 152 ms ] threadIf you are wondering why the binaries are so large, it's because they are packaged-up node.js binaries. I tried to learn a compile-to-native language to rewrite this in so you won't have to download such bloated binaries but didn't get far. I learned Swift and still have a WIP branch up for it[2]. I gave up after learning that there's no well maintained windows http server for swift.
I'm currently on my journey to learn Rust. So maybe one day when I do, you'll see the binary sizes drop.
[1]:https://github.com/steelbrain/ffmpeg-over-ip/releases/tag/v3... [2]:https://github.com/steelbrain/ffmpeg-over-ip/tree/swift-lang
Keep up the good work!
[1] https://docs.deno.com/runtime/reference/cli/compiler/ [2] https://bun.sh/docs/bundler/executables
[1]:https://news.ycombinator.com/item?id=41205253
> Note that if hardware acceleration is configured in the calling application, the exact same hardware acceleration modes must be available on all configured hosts, and, for fallback to work, the local host as well, or the ffmpeg commands will fail.
I wanted to mix and match windows and linux, and it was clear rffmpeg wasn't going to work for me.
One plus rffmpeg does have is that it supports multiple target hosts, so it's useful if you want some load balancing action. Although you could do the same with ffmpeg-over-ip, just selecting the servers dynamically but rffmpeg does make it easier out of the box.
[1]:https://github.com/joshuaboniface/rffmpeg
How to use it? Do you have example commands?
How is video data transferred between the client and the server?
Would it be possible to connect with SSH to a Linux server, using SFTP with FUSE or Samba with port forwarding for file sharing? This way the server could be zero-configuration (except that ffmpeg has to be installed, but the executable can also be transferred over SSH).
For different people it's going to solve different problems. For me, most recently, I wanted to use the powerful GPU in my gaming machine for transcoding in my plex server with an integrated GPU.
> How to use it? Do you have example commands?
The Github repository should have instructions on how to use. The client usage (once you setup the configuration) is the same as ffmpeg, so anything ffmpeg ... becomes ffmpeg-over-ip-client ... -- you need a server running on the machine with the GPU and then client anywhere network-accessible.
> How is video data transferred between the client and the server?
The server and client only transfer commands, stdout/err etc. The data of the transcoded files themselves is transferred over the network mount. The README of the repository has more details here but essentially you'll want a shared filesystem between the two.
> Would it be possible to connect with SSH to a Linux server, using SFTP with FUSE or Samba with port forwarding for file sharing? This way the server could be zero-configuration (except that ffmpeg has to be installed, but the executable can also be transferred over SSH).
Configuration should be pretty straight forward but let me know if you try it and find it difficult. A template configuration file is provided and you can edit your way out of it. You can absolutely do this with port forwarding even over the internet, provided the file system mount over the network can keep up.
[1] https://www.exit1.org/dvdrip/
I dont meant to discourage you, but it is possible to replace your entire repo with a simple bash alias:
If your usecase is solved by an alias, that's really good! I am glad you can use an alias. My usecase required a bit more so I wrote this utility and am sharing it with my peers
I looked over your source code and just saw a bash wrapper with webserver, so no significant IP. Any potential innovations: like possible distributed transcoding, sharding/partitioning transcoding pipeline to speed-up are missing.
its just a bash wrapper, thats why I commented about bash alias.
I don't mean to sound like a jerk, but I was honestly looking for some innovation about ffmpeg
There's no significant IP in this utility, it's something I wrote for a usecase and it works well for that usecase. I ran the server side on a windows machine, and I did not want to setup a full blown ssh server and expose it over the network for this usecase.
Another thing was logging. The way logging is currently setup really hits the sweet spot for debugability for me. Lastly it's the rewrites. I've used the config to rewrite incoming codecs to something the machine supports.
This is a purpose built utility that does one job and IMO does it fairly well. It's definitely not as complex as Dropbox but also not as simple as an ssh alias. I appreciate you sharing the alias code (not just the comment) so if some of our peers have usecases that could be solved by it, they are welcome to use that as well!
Can you expand on that?
as for bash-ssh solution, you don't need shared FS, if you don't need intermediate results. you can use SCP to get the final result after transcoding has finished. something like:
my meta point being is, before engineering something with programming language, and handrolling webservers, with auth, and workers - just try to implement your system with bash scripts.Martin Klepmann created an entire database using just bash aliases in his book "Designing Data Intensive Applications"
Submission from 6 months ago, https://news.ycombinator.com/item?id=39929602 https://www.youtube.com/watch?v=0RvosCplkCc
Because if so, the word transcoding does not appear neither in this Show HN nor in the GitHub README.
And I can't think of any other use for this than to perform hardware-assisted transcoding on a remote machine.
Apparently it has nothing to do with OpenGL or CUDA, which are the primary uses for a GPU. And ffmpeg itself has more use cases than just transcoding files.
Solutions like these are the things that just make me tilt my head and make the clueless "huh?" sound.
At least that’s why I built something similar in Go for myself.
Before anyone mentions WSL: it either didn’t support GPU passthrough or was very difficult to configure when I set this up a few years ago, don’t know about current status. And you can’t call Windows executables from WSL when you SSH into it.
[1] https://github.com/PowerShell/Win32-OpenSSH/issues/139
you can use a URI as an input to ffmpeg which allows for not needing access to a C:\. pretty much any decent NAS will allow access via URI instead of drive letter mounts.
if something was learned during the building of the server/client app, then great if that's why it was done. but it's only one of the 99 ways of skinning the cat, and probably not even close to the best one.
Oh oof. I thought removing that requirement would be the whole point of something named "FFmpeg-over-IP". Shared filesystem usually involves full trust between machines, bad network error handling, and setting things up by hand (different config on every distro)
No idea what problem this is trying to solve. Just seems like the user wasn’t familiar enough with how to use a NAS.
There’s a pretty well understood concept of what a NAS is; this isn’t a complicated philosophical problem.
A very common workflow in motion picture production is to use NAS for storage on a fast network, mount the SMB share, have a script/tool/app that monitors the ingest directory and writes to an output dir.
FWIW the key differentiator between a NAS and other types of network storage is the protocols they use.
If files is the main primitive, it’s a NAS; it’s its blocks it’s considered a SAN.
Sometimes SANs have NAS “heads” for clients that want file access or a block level storage device.
It would be helpful to understand your specific use cases in more detail, particularly for batch transcoding (my understanding is that this solution is not about stream transcoding).
If you're talking about how today's open source NAS software has a button for enabling NFS/SMB on a directory:
1. I built my NAS long before software like that was common. Some of my custom stuff (Eg tiered storage, storing the first few seconds of every video on flash, etc) would be a pain to migrate.
2. Some of my Windows machines are untrusted. Unlike the NAS, they have internet access. I can't give them read access to the entire NAS, but I still want to use their GPUs and CPUs to run ffmpeg on arbitrary files on the NAS.
3. I could spend a day writing more code to move files in and out of a shared directory every time I need to run ffmpeg on them. But I was hoping "FFmpeg-over-IP" would let me run a remote ffmpeg on a local file. Like calling an RPC
This has been available in Synology and QNAP devices for that long…
I used to own the tape library that is the Disney Vault. A common pattern for transcoding is to have a watched folder. Drop files you need transcoded in, get files you want in a diff directory when finished.
Neither the OP nor I are talking about offline transcoding.
The same server could also offer a download link for the transcoded video, and also receive URL parameters for the transcoding options. Or the transcoded video itself is returned after the subprocess finishes.
Something along the lines of:
Server
Client This way no shared filesystem is required.As for why the variable number of outputs exist in the first place, it’s because when you’re a media server, you dont want to wait until the full file is converted before serving it to the user. You want to start playing immediately so the output is chunked into multiple files
User space limits potential security impacts, and a restricted VFS could be used to prevent clients from accessing anything that they shouldn't.
(Although I'm not even pretending to know whether or not this is a remotely good idea - my guess is that it isn't, but I'd like to know just how bad an idea it actually is.)
There are ways to intercept writes without root and send them to another machine. Eg you could use LD_PRELOAD. But that's exactly the kind of pain in the ass that I was hoping a project named FFmpeg-over-IP would automate.
Thinking of https://tuxphones.com/howto-linux-as-second-wireless-display... -> https://gitlab.com/tuxphones/side-displays but for those running android or ios
I suppose ssh would be tricky if you're combining multiple input files.
But with single input, single output, you can just do:
Wrote it in C# and it runs both on Windows and Linux. The original need for this actually was to accelerate encodes a system I run on a cloud VM needs when I have either my desktop or laptop available, who then work as encode slaves and pick up jobs, run them and send the output files back. If no slaves are available, the system falls back to local CPU encode. Later I ended up using this using a local Windows server machine as the "client" the slaves also connect to to ask for jobs (actually the system runs inside a Unity project in that case because C# is awesome).
Probably a bit of a rare problem I hit with this is that different NVENC generations generate different enough bitstreams that they can't be concatenated together. From my pool of machines I found out only my RTX 2070 and RTX 3080 Mobile are compatible. GTX 970 and Quadro P5000 that I had laying around both were incompatible with that pool and with each other.
Interestingly I found no similar software to the chunked encoding in my system, but am chalking it up on me not searching hard enough or these being integrated deep in to commercial/private systems. It would make sense that big players like YouTube have something like this in place, as reducing latency for individual upload transcodes finishing is beneficial instead of limiting their speed to a single hardware encoding / software encoding node. It's the same amount of processing that needs to be done in the end anyway, so might as well use 10 nodes to complete single jobs really quickly one after another
I have a VPS on OVH which uses ffmpeg to convert mp3 files from 320kbps to 128kbps, it runs at 32x real speed on the server, but it could run 100x faster on my desktop pc. If there was an easy way to let the VPS "run" ffmpeg from my machine, that'd be great.
What would be great is FFmpeg in the cloud with GUI for easier use.