Multi-DJ livestream toolkit
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

75 lines
2.4 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. import math
  2. import collections
  3. import string
  4. from ..filters import FFmpegGraph, FFmpegChain, FFmpegFilter
  5. from .base import OBSSource
  6. IDENTIFY_MAPPING = collections.defaultdict(lambda: '_', {ord(k): k for k in string.ascii_letters + string.digits})
  7. def identifiery(n):
  8. return n.translate(IDENTIFY_MAPPING)
  9. def deg2rad(n):
  10. return n * (math.pi / 180)
  11. @OBSSource.type('scene')
  12. class OBSSceneSource(OBSSource):
  13. def __init__(self, *args, **kwargs):
  14. super().__init__(*args, **kwargs)
  15. self.name = None
  16. self.items = []
  17. def load(self, data):
  18. self.name = data['name']
  19. self.items = data['settings']['items']
  20. def to_ffmpeg(self, scene):
  21. prefix = identifiery(self.name)
  22. i = 0
  23. graph = [FFmpegChain(
  24. FFmpegFilter('color', c='black', s='{}x{}'.format(*scene.dimensions), outs=[prefix + str(0)])
  25. )]
  26. i += 1
  27. for item in self.items:
  28. if not item['visible']:
  29. continue
  30. chains = scene.sources[item['name']].to_ffmpeg(scene)
  31. c = chains[-1]
  32. if item['scale']['x'] != 1.0 or item['scale']['y'] != 1.0:
  33. c.append(FFmpegFilter('scale',
  34. w='{} * in_w'.format(item['scale']['x']),
  35. h='{} * in_h'.format(item['scale']['y'])
  36. ))
  37. if item['crop_top'] != 0 or item['crop_bottom'] != 0 or item['crop_left'] or item['crop_right'] != 0:
  38. c.append(FFmpegFilter('crop',
  39. w='in_w - {} - {}'.format(item['crop_left'], item['crop_right']),
  40. h='in_h - {} - {}'.format(item['crop_top'], item['crop_bottom']),
  41. x=item['crop_left'],
  42. y=item['crop_top']
  43. ))
  44. if item['rot'] != 0.0:
  45. c.append(FFmpegFilter('rotate',
  46. angle=deg2rad(item['rot'])
  47. ))
  48. if not c[-1].outs:
  49. c[-1].outs.append(prefix + 'Out' + str(i))
  50. chains.append(FFmpegChain(
  51. FFmpegFilter('overlay',
  52. eval='init',
  53. x=item['pos']['x'],
  54. y=item['pos']['y'],
  55. ins=[prefix + str(i - 1), c[-1].outs[-1]],
  56. outs=[prefix + str(i)]
  57. )
  58. ))
  59. i += 1
  60. graph.extend(chains)
  61. return graph