It was hit or miss for me in Ubuntu. It would work fine for a bit then it wouldn’t. It was pretty unreliable. I’ve since moved on. I don’t have the streaming service that I was using with it anymore so I put it on the back burner before ironing out the bugs. I’d probably start with a linkpi.
And now with ESPN proper going DRM - this went from a "nice to have" to "really need this"
@tmm1 Any chance you can dig on the mac front here? This still plagued us, when checked last
I can't change macOS security restrictions unfortunately
Understood - I guess we were under impression that you were testing this on a Mac - guessing not, now. Sorry for the nag.
I want to give an update on my experience with this using Linux and the capture card linked in the first post. I’ve had it running reliably for a couple weeks now and am confident it is a reliable enough alternative to a linkpi. I think a linkpi would be more reliable but for under $40 for the entire setup it may be worth it for some people looking for a single tuner to cover a drm channel.
My initial problems I had running this with Linux was that usb power-managing PCIe USB controller was locking the card up. It would lock up the card and wouldn’t function reliably. After I disabled any power management it’s been fabulous. The other issue I was having was my machine wasn’t always “seeing” the input of the card, to troubleshoot I had a hdmi splitter handy so I plugged the Onn into it and that problem disappeared. At first I thought there must be some dhcp issue but I now believe the EDID communication between the Onn, card, and machine wasn’t working properly. When I added a splitter the EDID issue is corrected by the splitter. Whether you will need an hdmi splitter may depend on the streamer and the usb capture card you buy.
With these tweaks hdmi usb capture with ADBTuner on Linux has been very reliable for me the last couple weeks. If you have an unused android streamer laying around I would definitely buy a $10-$20 usb capture card and give it a try.
I followed your lead here and set this up with Fastchannels. I've been working (for quite some time) to dial in DRM stations with FastChannels. I have a PrismCast bridge right now, but we all know Prism has it's own limitations.
I now have a prototype working with FC and I funnel all the DRM stations through Kodi. The capture card (on Ubuntu) is attached to a Firestick with Kodi installed. I then have custom m3u output from FC - and the m3u includes the kodiprop info (the DRM license server), then when user selects a channel from CDVR, FC hits Kodi and plays the stream on CDVR using Kodi's legal DRM EME.
The tune time is fantastic - and quality seems decent. Agreed with Rice - for a $20 encoder and $25 firestick, I think this is the path forward for a budget DRM bridge tool.
Absolutely, I got a $12 Cenmate box that some people have reported issues with but mine works perfectly with an unused fire stick 4K Max I had laying around. On Windows 11.
Totally worth trying out, the PQ is excellent and I've had no A/V sync issues.
Anyone tried running Channels on a Synology NAS and using an HDMI capture card? If so, I'd be interested in the results.
If you are using the Synology package, i think the linux bersion of the URL would be the closest option.
I've found using a stand alone encoder to provide good results.
@Rice I'm just working on passing a Capture Card through to a Proxmox LXC running Channels DVR. What was the final capture:// command you ended up using?
I found it depends on the actual card and if YUYV or MJPEG is needed. The cheaper cards will advertise they can do 1920x1080@60fps but they don’t mention it can only do that by using MJPEG, if you try to use that card in the mode that channels ffmpeg uses they can top out at 5fps at 1920. Basically you don’t really know what you’re going to get from a card before you buy because they don’t specify supported resolutions for both YUYV or MJPEG. So your card may very for required capture command.
For the card listed in post number one I use the following. This card I had disable power management for it to behave in Linux. This is used for YUYV source type card ffmpeg encode
capture://v4l2/video2/hw:Video,0/?framerate=60&width=1920&height=1080
My other card was $6 and while it behaves nicely in Linux it requires a different command because it needs to use mjpeg to get more than 5fps. This card supports up to 1920x1080@60fps with mjpeg but whatever version of ffmpeg channels uses limits encoding to 720@60fps or 1080@30fps when source stream is mjpeg. This card uses this command for 720@60. This card requires using source as MJPEG instead of YUYV.
capture://v4l2/video0/hw:MS2109,0/?framerate=60&video_size=1280x720&pixel_format=mjpeg
You could also change the above for 1080@30 by changing the resolution and framerate entries.
You can check supported card resolutions by running this substituting you particular /video0, /video2 ect. First running this to see what /video# has been assigned to the card.
v4l2-ctl --list-devices
Then to see supported resolution(substitute/video0 with video/ from above command)
v4l2-ctl -d /dev/video0 --list-formats-ext
I am working on a Linux (Deb) app that will act like a LinkPi for attached HDMI to USB Capture Cards. Here is a list of what it can do now:
- Smart Port Assignment: On its first launch, it scans for an open network port (starting at 8090) and permanently saves it so your stream URLs never change.
- Persistent Hardware Locking: It identifies USB video and audio capture cards by their unique hardware IDs, ensuring sources never get mixed up if the server reboots or devices are unplugged.
- Universal GPU Detection: It automatically scans the system for Intel, NVIDIA, or AMD graphics processors and unlocks the correct hardware acceleration options.
- Built-in Web Dashboard: It hosts its own configuration page where you can pair capture cards, tune encoding settings (like Bitrate, Codec, and Rate Control), and copy stream URLs.
- On-Demand Encoding: It runs silently using almost no resources until a stream is requested. It then instantly launches an optimized FFmpeg process to deliver live video, and kills the process the exact second the viewer disconnects.
-
Appliance-Level Stability: It installs as a native background service (
systemd), meaning it automatically starts up when the server boots and will automatically revive itself if a crash occurs.
Once I get it working better, I will release it and start working on a Windows app. This should simplify using the Capture dongles. Remember, the better the dongle, the better the results. A YUYV422 or NV12 uncompressed stream will provide better quality. The cheap dongles can't produce decent framerates for uncompressed video and have to use MJPEG. These will be configurable in the Dashboard.
If this could be made for docker also it would be amazing 
Just a heads-up, MANY of these devices share serial numbers so you cannot reliably use them for identification. You have to use their location on the bus (which breaks if they get plugged into different ports) or ask users to patch the firmware of the device to give them unique IDs (not reasonable). It's a small annoyance, but something to keep in mind.
I've been working on something like this for MacOS on and off for the past year and 90% of my time has been spent dealing with the fact that these devices are cheap for a reason lol. Most of the effort has gone into automatically recovering from the variety of failure states these devices get themselves into. It's getting there though lol.
They can be a PITA for sure. The cheap ones are not even worth using. None of them that I have seen can produce an uncompressed stream anywhere near 30fps, much less 60. I've had good luck with some in the $20 plus range.
I will probably switch to the physical position on the usb bus to avoid issues. As long as they use the same USB port of that device, it "should" work.
Yeah. Some in the $15-$20 range are decent. I've had good luck with MS2130S based devices. They are often branded as "USB3 PLUS Video". There really are only a few variants of these devices, they are just sold under different brands with different designs.
This worked well for me. It's the only option unfortunately. I have 3 of them that identify as the same exact device lol. I did serial number and then usb bus as a fallback to assign a unique key to each device. That way if someone does buy multiple devices with different serials then they can still switch them around without the app getting confused and assigning them to the wrong stream URL.
So, I have a Guermok 4K USB-HDMI adapter, and was trying to set this up as a source for Channels. I'm getting the same hwupload error that TerryD reported last year, and wondering if there is a fix. Channels is installed on a Windows 11 PC. I read thru this thread, and went back and forth with AI last night trying to find a solution. I tried several pixel formats in my M3U, nv12, yuyv422, and all ended with this hwupload error. AI seemed to think there was an issue with how Channels was passing the USB stream to my nVidia GPU. After trying many M3U iterations, AI directed me to create a script to have ffmpeg process the stream outside of Channels first, and that did work. But, seems like there should be a way to do this within Channels and not have a separate ffmepg script always running on the side.
I also pulled the nVidia GPU and forced Channels to use an Intel GPU, and I was able to get the USB source working entirely within Channels, so this seems to be a nVidia specific issue? I would perfer to keep my nVidia GPU since Prismcast is working very well with it. But, Channels seems coded to use the nVidia GPU no matter what, when it's in the system.
Here's the first custom channel text I tried, and the hwupload error it generated.
Any help would be appreciated, as I'm a bit out of my element with this. I was hoping to try the FastChannels bridge option to control a Firestick thru this USB interface.
#EXTM3U
#EXTINF:-1 channel-id="hdmi-guermok-1080p60" tvg-name="HDMI 1080p60", HDMI NV12 Ingest
capture://dshow/Guermok USB3 Video/Digital Audio Interface (Guermok USB3 Audio)/?video_size=1920x1080&framerate=60&pixel_format=nv12
2026/09/10 20:09:52.813817 [TNR] Opened connection to M3U-GuermokHDMI for ch8000 HDMI NV12 Ingest
2026/09/10 20:09:52.813817 [HLS] Starting live stream for channel 8000 from 127.0.0.1
2026/09/10 20:09:53.462710 [HLS] ffmpeg: capture-hdmi-guermok-1080p60: [aist#0:1/pcm_s16le @ 00000229c5979700] Guessed Channel Layout: stereo
2026/09/10 20:09:53.462710 [HLS] ffmpeg: capture-hdmi-guermok-1080p60: [vost#0:0/h264_nvenc @ 00000229c581c640] -enc_time_base -1 is deprecated, use -enc_timebase demux
2026/09/10 20:09:53.522220 [HLS] ffmpeg: capture-hdmi-guermok-1080p60: [aost#0:1/aac @ 00000229d3bfc8c0] -enc_time_base -1 is deprecated, use -enc_timebase demux
2026/09/10 20:09:53.523762 [HLS] ffmpeg: capture-hdmi-guermok-1080p60: Failed to negotiate pixel format between 'graph 0 input from stream 0:0' and 'auto_scale_0':
2026/09/10 20:09:53.523762 [HLS] ffmpeg: capture-hdmi-guermok-1080p60: graph 0 input from stream 0:0 (buffer)
2026/09/10 20:09:53.523762 [HLS] ffmpeg: capture-hdmi-guermok-1080p60: ↓ nv12
2026/09/10 20:09:53.523762 [HLS] ffmpeg: capture-hdmi-guermok-1080p60: ↑ nv12
2026/09/10 20:09:53.523762 [HLS] ffmpeg: capture-hdmi-guermok-1080p60: auto_scale_0 (scale)
2026/09/10 20:09:53.523762 [HLS] ffmpeg: capture-hdmi-guermok-1080p60: ↓ yuv420p, yuyv422, rgb24 (+183 more)
2026/09/10 20:09:53.523762 [HLS] ffmpeg: capture-hdmi-guermok-1080p60: ⚠️ hwupload needed ⚠️
2026/09/10 20:09:53.523762 [HLS] ffmpeg: capture-hdmi-guermok-1080p60: ↑ cuda
2026/09/10 20:09:53.523762 [HLS] ffmpeg: capture-hdmi-guermok-1080p60: Parsed_scale_cuda_0 (scale_cuda) [requires cuda]
2026/09/10 20:09:53.523762 [HLS] ffmpeg: capture-hdmi-guermok-1080p60: ↓ cuda
2026/09/10 20:09:53.523762 [HLS] ffmpeg: capture-hdmi-guermok-1080p60: ↑ yuv420p, nv12, p010le (+13 more)
2026/09/10 20:09:53.523762 [HLS] ffmpeg: capture-hdmi-guermok-1080p60: format
2026/09/10 20:09:53.523762 [HLS] ffmpeg: capture-hdmi-guermok-1080p60: ↓ yuv420p, nv12, p010le (+13 more)
2026/09/10 20:09:53.523762 [HLS] ffmpeg: capture-hdmi-guermok-1080p60: ↑ yuv420p, yuyv422, rgb24 (+227 more)
2026/09/10 20:09:53.523762 [HLS] ffmpeg: capture-hdmi-guermok-1080p60: out_0_0 (buffersink)
2026/09/10 20:09:53.523762 [HLS] ffmpeg: capture-hdmi-guermok-1080p60: Impossible to convert between the formats supported by the filter 'graph 0 input from stream 0:0' and the filter 'auto_scale_0'
2026/09/10 20:09:53.524285 [HLS] ffmpeg: capture-hdmi-guermok-1080p60: [vf#0:0 @ 00000229c595e400] Error reinitializing filters!
2026/09/10 20:09:53.524285 [HLS] ffmpeg: capture-hdmi-guermok-1080p60: Failed to inject frame into filter network: Function not implemented
2026/09/10 20:09:53.524285 [HLS] ffmpeg: capture-hdmi-guermok-1080p60: Error while filtering: Function not implemented
2026/09/10 20:09:53.525312 [HLS] ffmpeg: capture-hdmi-guermok-1080p60: [out#0/mpegts @ 00000229c52ff6c0] Nothing was written into output file, because at least one of its streams received no packets.
2026/09/10 20:09:53.569951 [ERR] Error during stream M3U-GuermokHDMI ch8000 HDMI NV12 Ingest: exit status 0xffffffd8
2026/09/10 20:09:53.569951 [TNR] Closed connection to M3U-GuermokHDMI for ch8000 HDMI NV12 Ingest
Does it work with transcoding set to software?


