Chrome Capture for Channels

I've created a new project which lets you capture the video/audio from a Chrome tab and redirect into a Custom Channel

See the GitHub README for setup instructions

When running, there is a server on port 5589 which you can then use from a Custom Channel:

#EXTM3U

#EXTINF:-1 channel-id="cnbc",CNBC
chrome://x.x.x.x:5589/stream/cbnc

#EXTINF:-1 channel-id="weatherscan",Weatherscan
chrome://x.x.x.x:5589/stream?url=https://weatherscan.net

h/t @babsonnexus DEPRECATED: PC Stream for Channels (DRM Workaround) | No new hardware required!

11 Likes

Wow. Yet another game changer! Can this handle concurrent tabs, for capturing multiple streams?

4 Likes

Yes it should. Note that it can use a bit of CPU to encode the video so you may not be able to run more than a couple tabs concurrently depending on your computer.

2 Likes

Would this take advantage of a GPU for encoding?

3 Likes

I don't think so, but that's not something that's easy to change because it's built into Chrome by google.

9 Likes

What does this mean exactly? Just a media video/audio stream being played, say a YouTube video? Like a Cast to feature?
Or is this full desktop screen capture and stream?

How is latency?

3 Likes

It might have support? I'll have to dig in a bit more. Cannot enable GPU acceleration · Issue #3637 · puppeteer/puppeteer · GitHub

2 Likes

I may be mistaken.

The software encoder build into Chrome has seen a lot of performance improvements:

https://bugs.chromium.org/p/chromium/issues/detail?id=600399

and it seems like they enabled hardware support on macOS as well:

https://bugs.chromium.org/p/webrtc/issues/detail?id=6317

EDIT: Full support list here: mediacapture-record-implementation-status/chromium.md at master · yellowdoge/mediacapture-record-implementation-status · GitHub

3 Likes

Excellent. This might be a far better approach then trying to record a full desktop via Xvfb that I have been toying with. Have a 3060 RTX out for delivery today - I'll play around with this on Linux and MacOS. Thanks again for giving us alternatives for TVE.

3 Likes

It captures the entire visible contents of the tab.

Currently the code will look for a playing video on the page, size it to fit the screen, resize the Chrome window to fit the video so there's no black borders, then minimize the chrome window while it's recording.

But it could easily be adapted to record a dynamic webpage instead.

4 Likes

So could we feasibly make a channel out of any tabbed web page, even ones without video? Status dashboards, weather pages, stock prices, sports scores, headline news, calendars, etc.

Is there any allowance to "auto-refresh" the page?

Just brainstorming ideas here. Gamechangers inspire such direction! Thanks again @tmm1

3 Likes

Yes!

I just added support for weatherscan.net

5 Likes

This needs to be installed on the same machine as channels, eh? I have it installed on a linux box and can see its listening on port 5589 but do not see a request coming in. Guessing chrome:// URL handler is expecting localhost only?

1 Like

That is freaking awesome. Now I have to restart tinkering with the weatherscan project.

1 Like

No, it can be installed on any LAN machine and you can use it's IP.

However you do need DVR prerelease which is still uploading.. :sweat:

2 Likes

AHA! I'll sit tight for a bit.

2 Likes

Fantastic work, @tmm1! :clap:

I've been hoping for a solution like this for a long time and now it's happening! :partying_face:

Very excited to give it a try later. :smiley:

4 Likes

Sorry for jumping the gun

It started to work - Chrome launched, tuned to the channel but then abruptly closed.

Now I am seeing the error:

throw new Error("Could not find START_RECORDING function in the browser context");
exports.getStream = getStream;
function assertExtensionLoaded(ext, opt) {
    return __awaiter(this, void 0, void 0, function* () {
        const wait = (ms) => new Promise(res => setTimeout(res, ms));
        for (let currentTick = 0; currentTick < opt.times; currentTick++) {
            // @ts-ignore
            if (yield ext.evaluate(() => typeof START_RECORDING === "function"))
                return;
            yield wait(Math.pow(opt.each, currentTick));
        }
        throw new Error("Could not find START_RECORDING function in the browser context");
    });
}

Any ideas?

PS: while it WAS working the encoder rate was surprisingly very low in terms of CPU usage!