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.

69 lines
2.5 KiB

2 years ago
  1. import twitchio.ext.commands
  2. import collections
  3. import zmq
  4. from .filters import FFmpegChain, FFmpegFilter, filter_escape
  5. def make_twitch_chat(name, nickname, token, channel, x=200, y=25, addr='tcp://localhost:5555', nick_width=160, nick_args={}, chat_width=300, chat_args={}):
  6. nick_id = 'drawtext@twitch-{}-nicks'.format(name)
  7. chat_id = 'drawtext@twitch-{}-messages'.format(name)
  8. runner = TwitchChatUpdater(nickname=nickname, token=token, channel=channel, nick_target=nick_id, chat_target=chat_id)
  9. return [runner.run], [FFmpegChain(
  10. FFmpegFilter(nick_id,
  11. text='Loading',
  12. expansion='none',
  13. x='{} + max(0, {} - text_w)'.format(x, nick_width),
  14. y=y,
  15. **nick_args
  16. ),
  17. FFmpegFilter(chat_id,
  18. text='chat...',
  19. expansion='none',
  20. x='{} + {}'.format(x, nick_width),
  21. y=y,
  22. **chat_args
  23. ),
  24. FFmpegFilter('zmq')
  25. )]
  26. def zmq_escape(v):
  27. return (filter_escape(v)
  28. .replace('\\', '\\\\')
  29. .replace('\n', '\\\n')
  30. .replace(' ', '\\ ')
  31. )
  32. class TwitchChatUpdater(twitchio.ext.commands.Bot):
  33. def __init__(self, nickname, token, channel, nick_target, chat_target, addr='tcp://localhost:5555', maxlen=15):
  34. super().__init__(irc_token=token, nick=nickname, initial_channels=[channel], prefix='kwdakwdwajd')
  35. self.zmq_messages = collections.deque(maxlen=maxlen)
  36. self.zmq = zmq.Context()
  37. self.zmq_sock = self.zmq.socket(zmq.REQ)
  38. self.zmq_sock.connect(addr)
  39. self.zmq_nick_target = nick_target
  40. self.zmq_chat_target = chat_target
  41. def zmq_send_command(self, target, command, **args):
  42. cmd = '{} {} {}'.format(
  43. target, command,
  44. ':'.join(
  45. '{}={}'.format(k, zmq_escape(v)) for k, v in args.items()
  46. )
  47. ).encode('utf-8')
  48. self.zmq_sock.send(cmd)
  49. resp = self.zmq_sock.recv()
  50. def zmq_update(self):
  51. nick_text = '\n'.join('<{}>'.format(m.author.name) for m in self.zmq_messages if m)
  52. self.zmq_send_command(self.zmq_nick_target, 'reinit', text=nick_text)
  53. chat_text = '\n'.join(m.content for m in self.zmq_messages if m)
  54. self.zmq_send_command(self.zmq_chat_target, 'reinit', text=chat_text)
  55. async def event_ready(self):
  56. self.zmq_update()
  57. async def event_message(self, message):
  58. print(message.tags)
  59. self.zmq_messages.append(message)
  60. self.zmq_update()