2020-05-17 02:29:43 +00:00
|
|
|
import math
|
|
|
|
import collections
|
|
|
|
import string
|
|
|
|
|
|
|
|
from ..filters import FFmpegGraph, FFmpegChain, FFmpegFilter
|
|
|
|
from .base import OBSSource
|
|
|
|
|
|
|
|
|
|
|
|
IDENTIFY_MAPPING = collections.defaultdict(lambda: '_', {ord(k): k for k in string.ascii_letters + string.digits})
|
|
|
|
|
|
|
|
def identifiery(n):
|
|
|
|
return n.translate(IDENTIFY_MAPPING)
|
|
|
|
|
|
|
|
def deg2rad(n):
|
|
|
|
return n * (math.pi / 180)
|
|
|
|
|
|
|
|
|
|
|
|
@OBSSource.type('scene')
|
|
|
|
class OBSSceneSource(OBSSource):
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
super().__init__(*args, **kwargs)
|
|
|
|
self.name = None
|
|
|
|
self.items = []
|
|
|
|
|
|
|
|
def load(self, data):
|
|
|
|
self.name = data['name']
|
|
|
|
self.items = data['settings']['items']
|
|
|
|
|
|
|
|
def to_ffmpeg(self, scene):
|
|
|
|
prefix = identifiery(self.name)
|
2020-05-18 16:50:50 +00:00
|
|
|
i = 0
|
2020-05-17 02:29:43 +00:00
|
|
|
graph = [FFmpegChain(
|
2020-05-18 16:50:50 +00:00
|
|
|
FFmpegFilter('color', c='black', s='{}x{}'.format(*scene.dimensions), outs=[prefix + str(0)])
|
2020-05-17 02:29:43 +00:00
|
|
|
)]
|
2020-05-18 16:50:50 +00:00
|
|
|
i += 1
|
2020-05-17 02:29:43 +00:00
|
|
|
|
|
|
|
for item in self.items:
|
|
|
|
if not item['visible']:
|
|
|
|
continue
|
|
|
|
|
2020-05-18 16:50:50 +00:00
|
|
|
chains = scene.sources[item['name']].to_ffmpeg(scene)
|
2020-05-17 02:29:43 +00:00
|
|
|
c = chains[-1]
|
|
|
|
|
|
|
|
if item['scale']['x'] != 1.0 or item['scale']['y'] != 1.0:
|
|
|
|
c.append(FFmpegFilter('scale',
|
|
|
|
w='{} * in_w'.format(item['scale']['x']),
|
|
|
|
h='{} * in_h'.format(item['scale']['y'])
|
|
|
|
))
|
|
|
|
if item['crop_top'] != 0 or item['crop_bottom'] != 0 or item['crop_left'] or item['crop_right'] != 0:
|
|
|
|
c.append(FFmpegFilter('crop',
|
|
|
|
w='in_w - {} - {}'.format(item['crop_left'], item['crop_right']),
|
|
|
|
h='in_h - {} - {}'.format(item['crop_top'], item['crop_bottom']),
|
|
|
|
x=item['crop_left'],
|
|
|
|
y=item['crop_top']
|
|
|
|
))
|
|
|
|
if item['rot'] != 0.0:
|
|
|
|
c.append(FFmpegFilter('rotate',
|
|
|
|
angle=deg2rad(item['rot'])
|
|
|
|
))
|
2020-05-18 16:50:50 +00:00
|
|
|
if not c[-1].outs:
|
|
|
|
c[-1].outs.append(prefix + 'Out' + str(i))
|
|
|
|
chains.append(FFmpegChain(
|
|
|
|
FFmpegFilter('overlay',
|
|
|
|
eval='init',
|
|
|
|
x=item['pos']['x'],
|
|
|
|
y=item['pos']['y'],
|
|
|
|
ins=[prefix + str(i - 1), c[-1].outs[-1]],
|
|
|
|
outs=[prefix + str(i)]
|
|
|
|
)
|
|
|
|
))
|
2020-05-17 02:29:43 +00:00
|
|
|
i += 1
|
|
|
|
|
|
|
|
graph.extend(chains)
|
|
|
|
|
2020-05-18 16:50:50 +00:00
|
|
|
return graph
|