72 lines
2.4 KiB
Python
72 lines
2.4 KiB
Python
import sys
|
|
import os
|
|
import tempfile
|
|
import shutil
|
|
import base64
|
|
|
|
import trio
|
|
from trio_cdp import page, emulation, dom
|
|
|
|
from ..chromium import Chromium
|
|
from ..filters import FFmpegChain, FFmpegFilter
|
|
from .base import OBSSource
|
|
|
|
|
|
async def do_screencast(url, outfile, dims):
|
|
c = Chromium()
|
|
async with await c.connect() as conn, await c.select(conn) as sess, sess.page_enable():
|
|
# Set viewport size and transparency.
|
|
await emulation.set_device_metrics_override(
|
|
width=dims[0], height=dims[1],
|
|
device_scale_factor=1.0, mobile=False
|
|
)
|
|
await emulation.set_default_background_color_override(dom.RGBA(0, 0, 0, 0))
|
|
|
|
# Navigate to the website.
|
|
async with sess.wait_for(page.LoadEventFired):
|
|
await page.navigate(url)
|
|
|
|
# Start capture.
|
|
await page.start_screencast(format_='jpeg', quality=60)
|
|
async for frame in sess.listen(page.ScreencastFrame):
|
|
outfile.write(base64.b64decode(frame.data))
|
|
await page.screencast_frame_ack(frame.session_id)
|
|
|
|
def capture_page(url, outfile, dims=(1280, 720)):
|
|
trio.run(do_screencast, url, outfile, dims, restrict_keyboard_interrupt_to_checkpoints=True)
|
|
|
|
|
|
@OBSSource.type('browser')
|
|
class OBSBrowserSource(OBSSource):
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
self.local = False
|
|
self.url = None
|
|
self.width = 1280
|
|
self.height = 720
|
|
self.audio = False
|
|
self.tempdir = tempfile.mkdtemp()
|
|
|
|
def __del__(self):
|
|
shutil.rmtree(self.tempdir, ignore_errors=True)
|
|
|
|
def load(self, data):
|
|
self.name = data['name']
|
|
self.local = data['settings']['is_local_file']
|
|
if self.local:
|
|
self.url = data['settings']['local_file']
|
|
else:
|
|
self.url = data['settings']['url']
|
|
self.width = data['settings']['width']
|
|
self.height = data['settings']['height']
|
|
self.audio = data['settings']['reroute_audio']
|
|
|
|
def to_ffmpeg(self, scene):
|
|
fifo_path = os.path.join(self.tempdir, 'frame.bin')
|
|
fifo = os.mkfifo(fifo_path)
|
|
runner = functools.partial(capture_page, url=self.url, outfile=fifo_path, dims=(self.width, self.height))
|
|
return [FFmpegChain(
|
|
inputs=[FFmpegInput(fifo_path, f='image2pipe', framerate=runner.rate, follow=1, probesize=8192)],
|
|
runners=[runner]
|
|
)]
|