DEPRECATED: PC Stream for Channels (DRM Workaround) | No new hardware required!

UPDATE 2023-06-20: While this solution can and does still work, it is unnecessary to do so because this now exists:

Please follow along there as I will no longer be updating this workaround.


Inspired by the HDMI for Channels project, this solution attempts to do the same thing. Namely, this project allows the user to stream any station, including ones protected by DRM, in Channels--so long as there is a web source to get the content from that the user has legal access to. However, this solution focuses on doing so without using a separate (expensive) HDMI capture device and setup, eliminating multiple potential physical hardware fail points, and using an existing always-on Channels DVR Server.


Important Information

Version History (Current: v1.2023.06.16)
  • v1.2023.06.16 - Modified Task Scheduler directions, issue tracker update
  • v1.2023.06.15 - Beta Release
  • v0.2023.06.14 - Alpha Testing Complete

Please Note: This guide has been written for Windows as that is what I am most comfortable with. There is no reason that all of this could not be accomplished on a Mac or Linux with the appropriate scripting language edits and comparable add-on tools. Additionally, this could be run on a machine separate from the Channels server, but I prefer to limit complications like multiple PCs.

Prerequisites

(1) Download and install VLC

Files: Official download of VLC media player, the best Open Source player - VideoLAN

(2) Download and install the Go Programming Language

Files: Download and install - The Go Programming Language

(3) Download FFmpeg

Files: Download FFmpeg

OPTIONAL - Install FFmpeg by these directions: Installing FFmpeg on Windows {Step-by-Step}

(4) Download, install, and update Screen Capture Recorder

Files: GitHub - rdp/screen-capture-recorder-to-video-windows-free: a free open source windows "screen capture" device and recorder (also allows VLC/ffmpeg and others to capture/stream desktop/audio)

In Windows Explorer, navigate to C:\Program Files (x86)\Screen Capturer Recorder\configuration_setup_utility\vendor\ffmpeg\bin

Copy and paste the FFmpeg files from Step #3 into this directory and replace the out-of-date ones that are included with the installation files.

(5) Download and Unzip Android HDMI for Channels

FILES: GitHub - tmm1/androidhdmi-for-channels: androidhdmi-for-channels

  1. Under Code, select Download Zip.

image

  1. Save the file.

  2. Create a directory where you will want the solution to run from. For instance, mine are in C:\Users\{USERNAME}\OneDrive\04 Media\Channels Backups\~Programs\Computer Stream for Channels

  3. Unzip all the files to that directory.

Preparation

(6) Change Chrome Settings | Log in to Providers | Install Extensions
  1. Open up Chrome or your preferred browser (we'll be using Chrome for the base example).

  2. In your Settings, go to On Startup, and change the setting to Open the New Tab page.

image

This will make Chrome forget its prior sessions, which will be important as we'll only want one Chrome ever running to capture the stream.

The solution will just capture whatever is on the screen; it currently does not do any automatic logging in or anything like that in the background. Therefore, you should go to the website of whatever provider you want to use and make sure you are connected and that it can play. For instance, if you want to capture NFL Network, you should...

  1. Make sure anything that would stop a stream from auto-playing is turned off or disabled.

  2. Go to the website where the live feed streams (https://www.nfl.com/network/watch/nfl-network-live).

  3. Click to Authenticate and follow the directions on screen to do so

  1. Confirm the live stream(s) is(are) playing correctly.

  2. Go to Fullscreen Anything - Chrome Web Store and install the extension.

  3. Go to Auto Hide Cursor - Chrome Web Store and install the extension. Change settings to 1 second.

(7) Change VLC Settings

VLC is used to make the stream, but it does some odd things visually that need to be corrected first.

  1. Open up VLC
  2. On the menu, go to Tools and select Effects and Filters.

image

  1. Select the tab named Visual Effects and under that select Geometry.

image

  1. Here, check Transform and under the menu select Flip Vertically. Make sure nothing else is selected.

image

NOTE: This will make anything you play in VLC be flipped upside down. You can turn it off temporarily if you are using VLC for real, but remember to turn it back otherwise things are not going to go well for you!

(8) Modify Android HDMI for Channels
  1. Edit main.go and replace it with this code:
package main

import (
	"fmt"
	"io"
	"log"
	"net"
	"net/http"
	"os"
	"os/exec"
	"strconv"
	"sync"
	"time"

	"github.com/gin-gonic/gin"
)

var (
	tunerLock sync.Mutex

	tuners = []tuner{
		{
			url:   "http://{IP_ADDRESS_OF_YOUR_SERVER}:7653/stream/",
			pre:   "C:\\Users\\{USERNAME}\\OneDrive\\04 Media\\Channels Backups\\~Programs\\Computer Stream for Channels\\prebmitune.bat",
			start: "C:\\Users\\{USERNAME}\\OneDrive\\04 Media\\Channels Backups\\~Programs\\Computer Stream for Channels\\bmitune.bat",
			stop:  "C:\\Users\\{USERNAME}\\OneDrive\\04 Media\\Channels Backups\\~Programs\\Computer Stream for Channels\\stopbmitune.bat",
		},
	}
)

type tuner struct {
	url              string
	pre, start, stop string
	active           bool
}

type reader struct {
	io.ReadCloser
	t       *tuner
	channel string
	started bool
}

func init() {
	transport := http.DefaultTransport.(*http.Transport).Clone()
	transport.ResponseHeaderTimeout = 5 * time.Second
	transport.DialContext = (&net.Dialer{
		Timeout: 5 * time.Second,
	}).DialContext
	http.DefaultClient.Transport = transport
}

func (r *reader) Read(p []byte) (int, error) {
	if !r.started {
		r.started = true
		go func() {
			if err := execute(r.t.start, r.channel); err != nil {
				log.Printf("[ERR] Failed to run start script: %v", err)
				return
			}
		}()
	}
	return r.ReadCloser.Read(p)
}

func (r *reader) Close() error {
	if err := execute(r.t.stop); err != nil {
		log.Printf("[ERR] Failed to run stop script: %v", err)
	}
	tunerLock.Lock()
	r.t.active = false
	tunerLock.Unlock()
	return r.ReadCloser.Close()
}

func execute(args ...string) error {
	t0 := time.Now()
	log.Printf("Running %v", args)
	cmd := exec.Command(args[0], args[1:]...)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	err := cmd.Run()
	log.Printf("Finished running %v in %v", args[0], time.Since(t0))
	return err
}

func tune(idx, channel string) (io.ReadCloser, error) {
	tunerLock.Lock()
	defer tunerLock.Unlock()

	var t *tuner
	log.Printf("tune for %v %v", idx, channel)
	if idx == "" || idx == "auto" {
		for i, ti := range tuners {
			if ti.active {
				continue
			}
			t = &tuners[i]
			break
		}
	} else {
		i, _ := strconv.Atoi(idx)
		if i < len(tuners) && i >= 0 {
			t = &tuners[i]
		}
	}
	if t == nil {
		return nil, fmt.Errorf("tuner not available")
	}

	execute(t.pre)

	resp, err := http.Get(t.url)
	if err != nil {
		log.Printf("[ERR] Failed to fetch source: %v", err)
		return nil, err
	} else if resp.StatusCode != 200 {
		log.Printf("[ERR] Failed to fetch source: %v", resp.Status)
		return nil, fmt.Errorf("invalid response: %v", resp.Status)
	}

	t.active = true
	return &reader{
		ReadCloser: resp.Body,
		channel:    channel,
		t:          t,
	}, nil
}

func run() error {
	r := gin.Default()
	r.SetTrustedProxies(nil)
	r.GET("/play/tuner:tuner/:channel", func(c *gin.Context) {
		tuner := c.Param("tuner")
		channel := c.Param("channel")

		c.Header("Transfer-Encoding", "identity")
		c.Header("Content-Type", "video/mp2t")
		c.Writer.WriteHeaderNow()
		c.Writer.Flush()

		reader, err := tune(tuner, channel)
		if err != nil {
			c.JSON(500, gin.H{"error": err.Error()})
			return
		}

		defer func() {
			reader.Close()
		}()

		io.Copy(c.Writer, reader)
	})
	return r.Run(":7654")
}

func main() {
	err := run()
	if err != nil {
		panic(err)
	}
}

Basically, what has been modified is the removal of an error handler for the "pre" step and the "pre" step being forced to run before an attempt to tune into a station. Additionally, the original program was looking for an exterior connection, while this one is focused inward.

  1. Be sure to update the fields like for the IP Address of your server and the directory path of where the files are. When dealing with Windows machines, your directory paths must have two slashes!

  2. Rename prebmitune.sh to prebmitune.bat and edit it to have this code:

@ECHO OFF

REM ***** Start local stream *****

REM *** Send the Escape key to make sure the monitor and audio is on correctly, otherwise there are issues ***
ECHO >script.vbs set shell = CreateObject("WScript.Shell"):shell.SendKeys "{ESC}" & script.vbs

REM *** Wait 5 seconds to make sure everything is up ***
ping 127.0.0.1 -n 5

REM *** Start the stream in VLC with a number of options ***
CALL start vlc.exe dshow:// :dshow-vdev=screen-capture-recorder :dshow-adev=virtual-audio-capturer  :dshow-aspect-ratio=16:9 :dshow-chroma= :dshow-fps=0 :no-dshow-config :no-dshow-tuner :dshow-tuner-channel=0 :dshow-tuner-frequency=0 :dshow-tuner-country=0 :dshow-tuner-standard=0 :dshow-tuner-input=0 :dshow-video-input=-1 :dshow-video-output=-1 :dshow-audio-input=-1 :dshow-audio-output=-1 :dshow-amtuner-mode=1 :dshow-audio-channels=0 :dshow-audio-samplerate=0 :dshow-audio-bitspersample=0 :live-caching=300 :sout=#transcode{vcodec=mp1v,vfilter=transform,fps=60,scale=Auto,width=1920,height=1080,acodec=mpga,ab=128,channels=2,samplerate=44100,afilter=remap,scodec=none}:http{mux=ts,dst=:7653/stream/} :no-sout-all :sout-keep

This changes the original function to now start the stream through VLC using the Screen Capture Recorder. This is very resource intensive, which is why we only want it running when we are actively using a station.

  1. Rename stopbmitune.sh to stopbmitune.bat and edit it to have this code:
@ECHO OFF

REM ***** End local stream *****

taskkill /IM vlc.exe /T /F
taskkill /IM chrome.exe /T /F

Here, when a station is closed, we forcefully kill the stream in VLC and the Chrome session. VLC and Chrome must be fully dedicated to this solution in order for this to work.

  1. Rename bmitune.sh to bmitune.bat and edit it to have this code:
@ECHO OFF

REM ***** Actions to run before selecting Station *****
SET ScriptLog=bmitune.log
SET "StationID=%1"
SET StationLink=""
SET HelpPlay="Y"

ECHO %DATE% - %TIME% - STARTING TUNE TO STATION >> %ScriptLog%
ECHO %DATE% - %TIME% - TUNING TO STATION WITH THE ID %StationID% >> %ScriptLog%


REM ***** Set the Link to the Station *****
IF "%StationID%"=="nfl" ( 
	SET StationLink="https://www.nfl.com/network/watch/nfl-network-live"
	SET HelpPlay=""
	)
IF "%StationID%"=="nbcnewsnow" ( SET StationLink="https://www.nbc.com/live?brand=nbc-news&callsign=nbcnews" )
IF "%StationID%"=="nbclocal" ( SET StationLink="https://www.nbc.com/live?brand=nbc&callsign=nbc" )
IF "%StationID%"=="bravoe" ( SET StationLink="https://www.nbc.com/live?brand=bravo&callsign=bravo_east" )
IF "%StationID%"=="bravow" ( SET StationLink="https://www.nbc.com/live?brand=bravo&callsign=bravo_west" )
IF "%StationID%"=="cnbc" ( SET StationLink="https://www.nbc.com/live?brand=cnbc&callsign=cnbc" )
IF "%StationID%"=="ee" ( SET StationLink="https://www.nbc.com/live?brand=e&callsign=e_east" )
IF "%StationID%"=="ew" ( SET StationLink="https://www.nbc.com/live?brand=e&callsign=e_west" )
IF "%StationID%"=="golf" ( SET StationLink="https://www.nbc.com/live?brand=golf&callsign=golf" )
IF "%StationID%"=="msnbc" ( SET StationLink="https://www.nbc.com/live?brand=msnbc&callsign=msnbc" )
IF "%StationID%"=="oxygene" ( SET StationLink="https://www.nbc.com/live?brand=oxygen&callsign=oxygen_east" )
IF "%StationID%"=="oxygenw" ( SET StationLink="https://www.nbc.com/live?brand=oxygen&callsign=oxygen_west" )
IF "%StationID%"=="syfye" ( SET StationLink="https://www.nbc.com/live?brand=syfy&callsign=syfy_east" )
IF "%StationID%"=="syfyw" ( SET StationLink="https://www.nbc.com/live?brand=syfy&callsign=syfy_west" )
IF "%StationID%"=="telemundolocal" ( SET StationLink="https://www.nbc.com/live?brand=telemundo&callsign=telemundo" )
IF "%StationID%"=="usae" ( SET StationLink="https://www.nbc.com/live?brand=usa&callsign=usa_east" )
IF "%StationID%"=="usaw" ( SET StationLink="https://www.nbc.com/live?brand=usa&callsign=usa_west" )


REM ***** Error Checking *****
REM *** Station is Missing ***
IF "%StationID%"=="" (
	ECHO %DATE% - %TIME% - ERROR - NO STATION ID RECEIVED >> %ScriptLog%
	GOTO END
 	)

REM *** Link not Set ***
IF %StationLink%=="" (
	ECHO %DATE% - %TIME% - ERROR - NO LINK SET >> %ScriptLog%
	GOTO END
 	)


REM ***** Station Launch *****
ECHO %DATE% - %TIME% - SET THE LINK TO %StationLink% >> %ScriptLog%

REM *** Launch Chrome with the options: Disable Autoplay Settings | Hide Crash Report Bubble from last forced close | Full Screen | In a New Window | To this link ***
START chrome --autoplay-policy=no-user-gesture-required --hide-crash-restore-bubble --kiosk /new-window %StationLink%

REM *** Wait 30 seconds to make sure Chrome is loaded and the video has started ***
ping 127.0.0.1 -n 30

REM *** Send the keys Ctrl+Space to make fullscreen ***
ECHO >script.vbs set shell = CreateObject("WScript.Shell"):shell.SendKeys "^ " & script.vbs

REM *** Some stations do not want to autoplay and need help getting going ***
IF %HelpPlay%=="" ( GOTO SKIPHELPPLAY )
ping 127.0.0.1 -n 5
ECHO >script.vbs set shell = CreateObject("WScript.Shell"):shell.SendKeys " " & script.vbs
ECHO %DATE% - %TIME% - HELP PLAY EXECUTED >> %ScriptLog%
:SKIPHELPPLAY

ECHO %DATE% - %TIME% - SUCCESSFULLY LAUNCHED THE STATION WITH THE ID %StationID% AT THE LINK %StationLink%  >> %ScriptLog%


REM ***** Exit and Finish *****
:END
ECHO %DATE% - %TIME% - FINISHED >> %ScriptLog%
EXIT /B

You can have as many stations as you have access to, or even create your own. If there is a webpage for it, then it can become a station! See Future Plans below for some other considerations and possibilities.

(9) Create an audio silencer

Once a station launches, the audio will be coming out of the PC's default speakers. The computer cannot be muted as the capture method just records whatever audio the computer is playing, too. As such, you should do something like plug in speakers or headphones and physically turn off their volume. Even just a stereo connector/convertor not connected to anything would work. I have my computer connected by a HDMI cable to a TV and have the audio play only on that TV. Therefore, so long as the TV is off, no audio is playing where I don't want it.

Of course, if you do not care, and your PC is in some part of your house that cannot be heard, then this step can be skipped entirely.

Setup

(10) Create androidhdmi-for-channels.exe
  1. Open up a Command Prompt (in Administrative Mode)

2, Navigate to the directory containing all of the "Android HDMI for Channels" files from above.

  1. Once there, type "go build".

image

  1. You will now have a file called androidhdmi-for-channels.exe, which is the actual program you need to do anything. If there were errors during the build, then something is wrong in the main.go code. The first time you run this it might take several minutes, but it will be much faster every subsequent time after that (if you need to fix it).

For an additional example of this process, see .strmlnk generator - #2 by babsonnexus.

(11) Schedule androidhdmi-for-channels.exe to run on startup
  1. In the same directory, create a new file called androidhdmi-for-channels.ps1

  2. Edit the file and add this code:

Start-Process -WindowStyle hidden "C:\Users\{USERNAME}\OneDrive\04 Media\Channels Backups\~Programs\Computer Stream for Channels\androidhdmi-for-channels.exe"
  1. Be sure to edit the path to your directory!

  2. Open Task Scheduler:

image

  1. Create a new task and follow the directions from the link below on how to setup a PowerShell task:

https://community.spiceworks.com/how_to/17736-run-powershell-scripts-from-task-scheduler

  1. Make sure you set it to:
  • Run only if the user is logged in (critical for now in order to not hide windows)
  • Run with the highest privileges
  • Triggered When user logs on and make sure it is the account you will run this under
  • Start the program powershell with these arguments: -ExecutionPolicy Bypass -File "C:\Users{USERNAME}\OneDrive\04 Media\Channels Backups~Programs\Computer Stream for Channels\androidhdmi-for-channels.ps1", but replacing the directory path with your own.
  1. Right click on the newly created task and click Run to execute it immediately and confirm it is working. If it is, you'll see it in Task Manager:

image

(12) Create stations in Channels
  1. Add a Custom Channels:

Channels Support - Add Custom Channels with M3U Playlists

  1. Begin by...
  • Giving this a name you will love forever
  • Change the Stream Format to MPEG-TS
  • Prefer Channel logos from Guide Data
  • Limit to 1 Stream
  • Your preference for Channel Numbers (You can even put them in the m3u in the next step with a tvg-chno="###" flag. For instance, if you want to use the original TVE numbers that Channels has, you can do so!)

  1. Now, change the Source to Text and put this in:
#EXTM3U

#EXTINF:-1 channel-id="NFL Network",NFL Network
http://10.255.1.144:7654/play/tuner/nfl

#EXTINF:-1 channel-id="NBC News Now",NBC News Now
http://10.255.1.144:7654/play/tuner/nbcnewsnow

#EXTINF:-1 channel-id="NBC Local",NBC Local (WJAR)
http://10.255.1.144:7654/play/tuner/nbclocal

#EXTINF:-1 channel-id="Bravo (East)",Bravo (East)
http://10.255.1.144:7654/play/tuner/bravoe

#EXTINF:-1 channel-id="Bravo (West)",Bravo (West)
http://10.255.1.144:7654/play/tuner/bravow

#EXTINF:-1 channel-id="CNBC",CNBC
http://10.255.1.144:7654/play/tuner/cnbc

#EXTINF:-1 channel-id="E! (East)",E! (East)
http://10.255.1.144:7654/play/tuner/ee

#EXTINF:-1 channel-id="E! (West)",E! (West)
http://10.255.1.144:7654/play/tuner/ew

#EXTINF:-1 channel-id="Golf",Golf
http://10.255.1.144:7654/play/tuner/golf

#EXTINF:-1 channel-id="MSNBC",MSNBC
http://10.255.1.144:7654/play/tuner/msnbc

#EXTINF:-1 channel-id="Oxygen (East)",Oxygen (East)
http://10.255.1.144:7654/play/tuner/oxygene

#EXTINF:-1 channel-id="Oxygen (West)",Oxygen (West)
http://10.255.1.144:7654/play/tuner/oxygenw

#EXTINF:-1 channel-id="SyFy (East)",SyFy (East)
http://10.255.1.144:7654/play/tuner/syfye

#EXTINF:-1 channel-id="SyFy (West)",SyFy (West)
http://10.255.1.144:7654/play/tuner/syfyw

#EXTINF:-1 channel-id="Telemundo Local",Telemundo Local (WNEU)
http://10.255.1.144:7654/play/tuner/telemundolocal

#EXTINF:-1 channel-id="USA (East)",USA (East)
http://10.255.1.144:7654/play/tuner/usae

#EXTINF:-1 channel-id="USA (West)",USA (West)
http://10.255.1.144:7654/play/tuner/usaw

You can add, remove, or modify (especially local IDs) these stations to your heart's content. Most importantly is that the name/case after tuner must match what we put in the bmitune.bat above.

  1. Click save and you will now have the stations. However, they are not mapped to their guide data. For that, click the gear icon next to it and select Manage Lineup.

image

  1. For each station, click the + icon the right and in the dropdown change the search to Search All Lineups.

image

  1. Search for what you are looking for and select the most appropriate one. This can be tricky with some stations, so don't worry if you have to try a few different options to get it right.

image

  1. You will now end up with something like this:

  1. Close out with X and either let the guide data update naturally or force an update.
(13) Testing and Warnings
  1. If you go to the Guide and select your new source, you will see all these stations and guide data now available:

  1. DO NOT UNDER ANY CIRCUMSTANCES launch the station on the same machine it will be broadcasting from. Go to another machine or a client. If you do this, you will be in a terrible loop that will blow out your eardrums and you will be forced to manually close everything.

  2. Due to the various coded wait periods and the general lag, you will need a buffer on any recording. I would recommend a couple of minutes on each end.

  3. Trying to quick tune between these stations is not a good idea as you may kick off multiple processes at once. I have also seen that sometimes Channels takes 10-15 seconds to disconnect, which is required to close out everything that is playing.

  4. Otherwise, you should be good to go and get expected results:

  1. I am finding that on the client side I have to set the decoding to "Software" in order to see the stations and recordings. I would prefer that this was unnecessary and am investigating.

  2. Now, you can do the usual Favorite/Hide and add to Channel Collections to get these stations wherever you like.

Channels Support - Channel Collections

Other Details

(i) Known Issues, Bugs, Requests, and Future Plans
  1. Batch script logging appears to be broken while running in the background. This is not mission critical, so will launch without a solution.

  2. See if something can done with the encoding so that the stations and recordings can play back with the "Hardware" setting instead of the "Software" setting.

  3. Look for ways to make the quality of the stream higher with tweaking settings. UPDATE 2023-06-15: Looking into using OBS or other similar tools for better quality, faster streaming, etc...

  4. Code efficiencies and brute force / hardcoded workarounds in general, especially when dealing with the "prebmitune" step in the main.go file.

  5. Finding a way for all of this to happen in the background so a machine is not completely taken over when it is running. During alpha testing, I had been able to make it run in the background by changing Task Scheduler options to run whether the user is logged in or not. However, although I got the audio, the video was just a blank screen. I believe this is a limitation of the third party screen capture tool, though.

  6. Finding a way to have multiple instances on one machine so that it is not limited to one tuner at a time.

  7. Add a way to launch other programs instead of a web browser. For instance, if it launched the HDHomeRun desktop app and tuned to a specific ATSC 3.0 station with DRM, that image on screen could be captured.

  8. In a similar vein, I am considering a Windows 11 with Android Apps version of this instead of using a browser. This would also make things much more similar to the original project that this based on.

  9. ADDED 2023-06-15: If you use a headless or RDP session, solution does not appear to work. See: DEPRECATED: PC Stream for Channels (DRM Workaround) | No new hardware required! - #8 by jaidenc UPDATE 2023-06-16: See workaround for headless here: DEPRECATED: PC Stream for Channels (DRM Workaround) | No new hardware required! - #24 by marcuscthomas

  10. Other bugs / issues / suggestions from the below thread to be added here...

(ii) Special Thanks and Credits
  1. @tmm1 for developing HDMI for Channels

  2. Everyone who helped with the same and made it possible for me to figure out how this could work, especially @Fofer, @JT-DFW, and @Absenm

  3. @marcuscthomas for creating and maintaining the Screen Capture Recorder and explaining how to get it working with Channels.

  4. @miibeez for developing a workaround for the DRM feeds of PBS, which inspired me to believe that capturing a stream and redirecting it must be possible. The solution they used is far superior to this one, and if I can figure out how they did it, then I believe it should be able to be applied here instead of what I have put together.

(iii) Further Reading (Not Previously Mentioned)

Proof of Concept Demonstration Videos

3 Likes

Interesting. I could see this being run on a virtualized server such as ESXi, Proxmox, etc. How is the audio quality and I am guessing no surround support?

1 Like

Impressive creativity putting all of this together. That said, the issues I see going forward:

• Only one stream can be recorded simultaneously per PC
• The PC hosting this solution would be unusable during recordings/live TV
• Possible poor quality due to recompression?

Might these issues be overcome going forward?

4 Likes

Thanks for taking the time to look into this, writing documentation, and sharing with the community!

A couple of questions:

  1. Have you tested this with sources that require HDCP such as YouTube TV?
  2. The documentation for "screen-capture-recorder-to-video-windows-free" mentions high CPU usage. Have you seen that in your testing?

The sound is crisp, but overall flat. You might be able to tell in the videos above. Currently, I have VLC exporting 2 channels, but technically it could be increased to 5 or 6. However, I don't think there is a point in doing so because the originating sound would no longer be mixed. It's basically a tape recorder playing back what is in front of it.

Strangely, I find the sound to be much better quality than the video. But yes, there is definitely some blockiness problems, frame skipping, compression, etc.... I've already captured in section (i) a desire to find ways to increase the quality. I'm very out of my wheelhouse here, so hope someone can make some suggestions that can help!

Also noted in section (i), these are real issues. However...

This is an interesting idea, maybe with a bunch of virtual desktops to set up and do the heavy lifting? Then, for each "tuner" you want, there could a bunch of virtual desktops ready to go. Or maybe some intermediary to see which one is free? Sounds complicated, but not impossible by any stretch. It could work with some type of repurposed load handler software.

Making things have unintended uses is my specialty. :grin: That is also why I'm thinking that virtualization and software switches could be put to work here.

Yes, this is mentioned in section (8), step 3. This is why I only let it run when a station is tuned to, otherwise it would whir things to death. VLC has its own built-in desktop streamer which uses less resources, but it cannot capture sound. The developer of screen capture is actively working on it, so there is always hope for better resource management in the future.

Not specifically, but I cannot see it being an issue (aside from quality control and resource usage). If it can appear on your screen, then it can transmit!

You're welcome, and I've certainly benefited from the hard work of others to be able to put this together!

I found it useful to document as I was going, thus I was literally doing that in this thread so that the solution would be ready for presentation when I was! Also, I'm a big believer in documenting in-line with code to understand what the heck is going on.

I'm looking forward to other people implementing this and providing feedback / suggestions / code fixes / etc..

Wonder how one would go about doing this on Synology? Sounds like a neat idea.

This is really cool and when I saw the HDMI thread I immediately thought that there has to be a way to do this with some sort of screen capture method, I'm guessing you already looked at OBS to do the capture and couldn't get it to work? Specifically wondering if OBS outputs a stream that can be read by channels with or without FFmpeg.

Great work on figuring out how to set up all the other components like Chrome/VLC launching etc. Like you said this is all basically a big hack to work around the DRM issue, the real way to do this is IMO figuring out how @miibeez got the PBS channels to work (with widevine libraries or whatever) and have that run in a container.

1 Like

Pretty neat stuff. I don't have a use for it, but here is one thing that I found when testing it.

The windows machine running the program must have a display attached or else it will not work. If the display (or in my case, Remote Desktop Connection) is disconnected while a stream is running it will cease to work.

1 Like

You could output OBS to nginx-rtmp and then channels could subscribe to that feed.

Interesting... It hadn't occurred to me to use OBS; I really went with something readily available. I'll give it a try later and see if I can get it to work. Seemingly, it would just replace everything in the prebmitune step and a mild modification to the stopbmitune.

OBS is also cross-platform which would be a big plus.

1 Like

RE needing a display attached.
Did you try a dummy USB fob plugged in? I use these to RDP into machines here and be able to change display settings since it fakes the PC into thinking a display is attached.

This company offers something similar with a lot more cost. They have a patent I belive.

It seems like this only DVRs "cable or antenna" whereas the functionality "we" need to replace is TVE capture. I don't think Modulus does TVE, right?

It records OTA, cable, and streaming. TVE is streaming. So it can record that content as well as other streaming services such as Netflix,...etc. It used to be limited to specific services. It covered most. It doesn't not appear to be limited anymore.

3 Likes

Interesting. This is the first I've heard of it. Thanks for mentioning it.

1 Like

lol Starting at a measly $ 9k... Ummm I don't think we are the target customer. At least I'm not.. :grin:

Oh yes. Way too expensive. But that wasn’t my point. My point is, this is what we need. This device has been around for years.

1 Like

Holy crap. This tool is amazing!! Might be useful if I want to record these channels. Not too sure if it'll work on my Mac. I might put windows on that to try tho...

1 Like

Good recommendation! I used an OBS to nginx-rtmp Windows setup during NFL season to stream "Games" :innocent: to channels. Worked out quite well. I tried to set it up in a Windows VM that had GPU access and it was unusable.. Super slow. Honestly did not put any effort into tweaking it though. I'm guessing it could be made to work more efficiently in a Linux VM. Maybe a docker container with everything included. Actually bought an HDMI Encoder to connect to my Channels Server to do this without the additional load and then saw the HDMI Encoder Project and thought it could be adapted to use OBS and nginx-rtmp. @babsonnexus Great Work!!

1 Like