properly parse OBS profile for canvas and output dimensions and rescale

This commit is contained in:
Shiz 2020-05-18 19:39:19 +02:00
parent ed535b0bd2
commit 71ad68ba4a
5 changed files with 65 additions and 11 deletions

View File

@ -3,12 +3,13 @@ import subprocess
import shlex
import threading
from .obs import OBSScene
from .obs import OBSProfile, OBSScene
from .twitch_chat import make_twitch_chat
parser = argparse.ArgumentParser()
parser.add_argument('infile', type=argparse.FileType('r'), help='scene description file')
parser.add_argument('profile', type=argparse.FileType('r'), help='profile description file')
parser.add_argument('scene', type=argparse.FileType('r'), help='scene description file')
parser.add_argument('--nick-font', default='/Users/partynorge/down/Montserrat/Montserrat-Bold.ttf')
parser.add_argument('--chat-font', default='/Users/partynorge/down/Montserrat/Montserrat-Light.ttf')
parser.add_argument('-n', '--nickname', help='Twitch chat nickname', default='shizacular')
@ -19,9 +20,11 @@ parser.add_argument('channel', help='Twitch channel')
args = parser.parse_args()
# Load scene
scene = OBSScene()
scene.load(args.infile)
# Load profile and scene
profile = OBSProfile()
profile.load(args.profile)
scene = OBSScene(profile)
scene.load(args.scene)
# Convert scene graph
graph = scene.to_ffmpeg()

View File

@ -1,2 +1,2 @@
from .base import OBSSource, OBSScene
from .base import OBSProfile, OBSSource, OBSScene
from . import browser, scene, text, video

View File

@ -1,8 +1,51 @@
import json
import configparser
from ..filters import FFmpegGraph
class configproperty:
def __init__(self, name, type=None):
parts = name.split('.')
self.sections = parts[:-1]
self.name = parts[-1]
self.type = type
def get_section(self, section):
for s in self.sections:
section = section.setdefault(s, {})
return section
def __get__(self, instance, owner):
v = self.get_section(instance.data).get(self.name)
if v is not None and self.type:
v = self.type(v)
return v
def __set__(self, instance, value):
self.get_section(instance.data)[self.name] = value
class OBSProfile:
def __init__(self, name='Untitled'):
self.data = configparser.ConfigParser()
self.data['General'] = {'Name': name}
def load(self, fd):
self.data.read_file(fd)
name = configproperty('General.Name')
canvas_width = configproperty('Video.BaseCX', int)
canvas_height = configproperty('Video.BaseCY', int)
output_width = configproperty('Video.OutputCX', int)
output_height = configproperty('Video.OutputCY', int)
video_encoder = configproperty('SimpleOutput.StreamEncoder')
video_bitrate = configproperty('SimpleOutput.VBitRate', int)
audio_bitrate = configproperty('SimpleOutput.ABitRate', int)
class OBSSource:
TYPES = {}
@ -38,11 +81,10 @@ class OBSSource:
return s
class OBSScene:
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
def __init__(self, profile):
self.profile = profile
self.sources = {}
self.current_scene = None
self.dimensions = (1280, 720)
def load(self, infile):
data = json.load(infile)

View File

@ -14,7 +14,7 @@ from .base import OBSSource
class BrowserCapturer:
def __init__(self, url, outfile, dimensions, rate=25):
def __init__(self, url, outfile, dimensions, rate=10):
self.chromium = Chromium()
self.url = url
self.frame = b''

View File

@ -30,7 +30,7 @@ class OBSSceneSource(OBSSource):
prefix = identifiery(self.name)
i = 0
graph = [FFmpegChain(
FFmpegFilter('color', c='black', s='{}x{}'.format(*scene.dimensions), outs=[prefix + str(0)])
FFmpegFilter('color', c='black', s='{}x{}'.format(scene.profile.canvas_width, scene.profile.canvas_height), outs=[prefix + str(0)])
)]
i += 1
@ -72,4 +72,13 @@ class OBSSceneSource(OBSSource):
graph.extend(chains)
if scene.profile.canvas_width != scene.profile.output_width or scene.profile.canvas_height != scene.profile.output_height:
graph.append(FFmpegChain(
FFmpegFilter('scale',
w=scene.profile.output_width,
h=scene.profile.output_height,
ins=[prefix + str(i - 1)]
)
))
return graph