bot.py 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. import pymumble_py3 as pymumble
  2. from pymumble_py3.constants import *
  3. import subprocess as sp
  4. import time
  5. import sys
  6. import os
  7. import fcntl
  8. import audioop
  9. import argparse
  10. def message_received(message):
  11. global is_streaming
  12. if message == "/start":
  13. is_streaming = True
  14. elif message == "/stop":
  15. is_streaming = False
  16. parser = argparse.ArgumentParser(description='Regia pienamente automatizzata')
  17. parser.add_argument('--channel', help='Set channel')
  18. parser.add_argument('--name', help='Set bot nickname', default="RadioRobbot")
  19. parser.add_argument('--server', help='Set server', default="mumble.esiliati.org")
  20. parser.add_argument('--port', help='Set port', type=int)
  21. parser.add_argument('--stream', action='store_true', help='Ignore commands in chat and stream everything')
  22. sys.argv.pop(0)
  23. args = parser.parse_args(sys.argv)
  24. pwd = "" # password
  25. server = args.server
  26. nick = args.name
  27. channel = args.channel
  28. port = args.port
  29. is_streaming=False
  30. stream_always= args.stream
  31. mumble.callbacks.set_callback(PYMUMBLE_CLBK_TEXTMESSAGERECEIVED, message_received)
  32. # Spin up a client and connect to mumble server
  33. mumble = pymumble.Mumble(server, nick, password=pwd, port=port)
  34. # set up callback called when PCS event occurs
  35. mumble.set_receive_sound(1) # Enable receiving sound from mumble server
  36. mumble.start()
  37. mumble.is_ready() # Wait for client is ready
  38. mumble.channels.find_by_name(channel).move_in()
  39. mumble.users.myself.mute()
  40. BUFFER = 0.1
  41. BITRATE = 48000
  42. RESOLUTION = 10 # in ms
  43. FLOAT_RESOLUTION = float(RESOLUTION) / 1000
  44. MONO_CHUNK_SIZE = BITRATE * 2 * RESOLUTION / 1000
  45. STEREO_CHUNK_SIZE = MONO_CHUNK_SIZE * 2
  46. silent = b"\x00" * int(STEREO_CHUNK_SIZE)
  47. cursor_time = None
  48. cursor_time = time.time() - BUFFER
  49. while mumble.is_alive():
  50. if cursor_time < time.time() - BUFFER:
  51. base_sound = None
  52. try:
  53. for user in mumble.users.values(): # check the audio queue of each user
  54. if user.sound.is_sound():
  55. # available sound is to be treated now and not later
  56. sound = user.sound.get_sound(FLOAT_RESOLUTION)
  57. stereo_pcm = audioop.tostereo(sound.pcm, 2, 1, 1)
  58. if base_sound == None:
  59. base_sound = stereo_pcm
  60. else:
  61. base_sound = audioop.add(base_sound, stereo_pcm, 2)
  62. except RuntimeError:
  63. print("ignored exception in stderr...", file=sys.stderr)
  64. if is_streaming or stream_always:
  65. if base_sound:
  66. sys.stdout.buffer.write(base_sound)
  67. else:
  68. sys.stdout.buffer.write(silent)
  69. cursor_time += FLOAT_RESOLUTION
  70. else:
  71. time.sleep(FLOAT_RESOLUTION)