implement text support

This commit is contained in:
Shiz 2020-05-20 00:21:35 +02:00
parent f926b94c99
commit cb210fcc3e
7 changed files with 37 additions and 24 deletions

View File

@ -50,10 +50,11 @@ class FFmpegFilter:
)
class FFmpegChain:
def __init__(self, *filters, inputs=None, runners=None):
def __init__(self, *filters, inputs=None, runners=None, overlay=True):
self.filters = list(filters)
self.inputs = inputs or []
self.runners = runners or []
self.overlay = overlay
def append(self, f):
self.filters.append(f)

View File

@ -67,7 +67,7 @@ class OBSSource:
def load(self, data):
raise NotImplementedError
def to_ffmpeg(self, scene):
def to_ffmpeg(self, scene, item):
raise NotImplementedError
@classmethod
@ -105,9 +105,9 @@ class OBSScene:
for src in data['sources']:
self.sources[src['name']] = OBSSource.find_and_load(src)
def to_ffmpeg(self, scene=None):
def to_ffmpeg(self, scene=None, item=None):
scene = scene or self.current_scene
chains = self.sources[scene].to_ffmpeg(self)
chains = self.sources[scene].to_ffmpeg(self, item)
r = FFmpegGraph()
r.extend(chains)

View File

@ -107,7 +107,7 @@ class OBSBrowserSource(OBSSource):
self.height = data['settings']['height']
self.audio = data['settings'].get('reroute_audio', False)
def to_ffmpeg(self, scene):
def to_ffmpeg(self, scene, item):
fifo_path = os.path.join(self.tempdir, 'frame.bin')
os.mkfifo(fifo_path)

View File

@ -105,7 +105,7 @@ class OBSBrowserSource(OBSSource):
self.height = data['settings']['height']
self.audio = data['settings'].get('reroute_audio', False)
def to_ffmpeg(self, scene):
def to_ffmpeg(self, scene, item):
fifo_path = os.path.join(self.tempdir, 'frame.bin')
os.mkfifo(fifo_path)

View File

@ -26,7 +26,7 @@ class OBSSceneSource(OBSSource):
self.name = data['name']
self.items = data['settings']['items']
def to_ffmpeg(self, scene):
def to_ffmpeg(self, scene, item):
prefix = identifiery(self.name)
i = 0
graph = [FFmpegChain(
@ -38,7 +38,7 @@ class OBSSceneSource(OBSSource):
if not item['visible']:
continue
chains = scene.sources[item['name']].to_ffmpeg(scene)
chains = scene.sources[item['name']].to_ffmpeg(scene, item)
c = chains[-1]
if item['scale']['x'] != 1.0 or item['scale']['y'] != 1.0:
@ -59,15 +59,18 @@ class OBSSceneSource(OBSSource):
))
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)]
)
))
if c.overlay:
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)]
)
))
else:
c[0].ins.append(prefix + str(i - 1))
i += 1
graph.extend(chains)

View File

@ -12,17 +12,21 @@ class TextSource(OBSSource):
self.shadow = 0
self.shadow_color = '#000000'
def to_ffmpeg(self, scene):
def to_ffmpeg(self, scene, item):
return [FFmpegChain(
FFmpegFilter('drawtext',
expansion='none',
fontcolor=self.color,
fontcolor=hex(self.color),
font=self.font,
fontsize=self.size,
text=self.contents,
shadowcolor=self.shadow_color,
shadowx=self.shadow,
shadowy=self.shadow,
)
x=item['pos']['x'],
y=item['pos']['y'],
),
overlay=False
)]
@OBSSource.type('text_gdiplus')
@ -32,9 +36,14 @@ class GDIPlusSource(TextSource):
self.size = data['settings']['font']['size']
self.color = data['settings']['color']
import struct
def swap32(i):
return struct.unpack("<I", struct.pack(">I", i))[0]
@OBSSource.type('text_ft2_source')
class FreeType2Source(TextSource):
def load(self, data):
self.font = data['settings']['font']['face']
self.font = data['settings']['font']['face'] + ((' ' + data['settings']['font']['style']) if data['settings']['font'].get('style') else '')
self.size = data['settings']['font']['size']
self.color = data['settings']['color0']
self.color = swap32(data['settings']['color1'])
self.contents = data['settings']['text']

View File

@ -11,7 +11,7 @@ class ImageSource(OBSSource):
def load(self, data):
self.infile = data['settings']['file']
def to_ffmpeg(self, scene):
def to_ffmpeg(self, scene, item):
return [FFmpegChain(inputs=[FFmpegInput(self.infile)])]
@OBSSource.type('ffmpeg_source')
@ -25,7 +25,7 @@ class FFmpegSource(OBSSource):
self.infile = data['settings']['local_file']
self.loop = data['settings']['looping']
def to_ffmpeg(self, scene):
def to_ffmpeg(self, scene, item):
return [FFmpegChain(
inputs=[FFmpegInput(self.infile, re=None, stream_loop=-1 if self.loop else 0)]
)]