random/mumble-bot/bot.py

108 lines
3.7 KiB
Python
Raw Normal View History

2020-04-06 13:29:25 +02:00
import pymumble_py3 as pymumble
2020-04-15 21:31:24 +02:00
from pymumble_py3.constants import *
2020-04-06 13:29:25 +02:00
import subprocess as sp
2020-04-10 23:58:21 +02:00
import time
2020-04-06 13:29:25 +02:00
import sys
import os
import fcntl
2020-04-10 23:58:21 +02:00
import audioop
2020-04-15 21:31:24 +02:00
import argparse
2020-04-06 13:29:25 +02:00
2020-04-15 21:31:24 +02:00
def message_received(message):
global is_streaming
2020-04-16 21:05:51 +02:00
global silence_time
command=message.message
if command == "/start":
2020-04-15 21:31:24 +02:00
is_streaming = True
2020-04-16 21:05:51 +02:00
silence_time = 0
2020-04-16 21:47:39 +02:00
mumble.my_channel().send_text_message("Diretta iniziata")
2020-04-16 21:05:51 +02:00
mumble.users.myself.recording()
elif command == "/stop":
2020-04-15 21:31:24 +02:00
is_streaming = False
2020-04-16 21:47:39 +02:00
mumble.my_channel().send_text_message("Diretta terminata")
2020-04-16 21:05:51 +02:00
mumble.users.myself.unrecording()
2020-04-15 21:31:24 +02:00
parser = argparse.ArgumentParser(description='Regia pienamente automatizzata')
2020-04-16 21:05:51 +02:00
parser.add_argument('--channel', help='Set channel', default="")
2020-04-15 21:31:24 +02:00
parser.add_argument('--name', help='Set bot nickname', default="RadioRobbot")
parser.add_argument('--server', help='Set server', default="mumble.esiliati.org")
2020-04-16 21:05:51 +02:00
parser.add_argument('--port', help='Set port', type=int, default=64738)
2020-04-15 21:31:24 +02:00
parser.add_argument('--stream', action='store_true', help='Ignore commands in chat and stream everything')
2020-04-16 21:05:51 +02:00
parser.add_argument('--auto-suspend-stream', action='store_true', help='Ignore commands in chat and stream everything')
parser.add_argument('--max-silence-time', type=int, help='max silence time in seconds', default=30)
2020-04-15 21:31:24 +02:00
sys.argv.pop(0)
args = parser.parse_args(sys.argv)
2020-04-06 13:29:25 +02:00
pwd = "" # password
2020-04-15 21:31:24 +02:00
server = args.server
nick = args.name
channel = args.channel
port = args.port
is_streaming=False
stream_always= args.stream
2020-04-16 21:05:51 +02:00
auto_suspend_stream = args.auto_suspend_stream
silence_limit = 30
2020-04-15 21:31:24 +02:00
2020-04-06 13:29:25 +02:00
# Spin up a client and connect to mumble server
mumble = pymumble.Mumble(server, nick, password=pwd, port=port)
2020-04-16 21:05:51 +02:00
mumble.callbacks.set_callback(PYMUMBLE_CLBK_TEXTMESSAGERECEIVED, message_received)
2020-04-06 13:29:25 +02:00
mumble.set_receive_sound(1) # Enable receiving sound from mumble server
mumble.start()
mumble.is_ready() # Wait for client is ready
2020-04-06 13:34:07 +02:00
mumble.channels.find_by_name(channel).move_in()
2020-04-06 13:29:25 +02:00
mumble.users.myself.mute()
2020-04-16 21:05:51 +02:00
if is_streaming:
mumble.users.myself.recording()
2020-04-10 23:58:21 +02:00
BUFFER = 0.1
BITRATE = 48000
RESOLUTION = 10 # in ms
FLOAT_RESOLUTION = float(RESOLUTION) / 1000
MONO_CHUNK_SIZE = BITRATE * 2 * RESOLUTION / 1000
STEREO_CHUNK_SIZE = MONO_CHUNK_SIZE * 2
silent = b"\x00" * int(STEREO_CHUNK_SIZE)
cursor_time = None
cursor_time = time.time() - BUFFER
2020-04-16 21:05:51 +02:00
silence_time = 0
silence_limit_ms = silence_limit * 1000
2020-04-10 23:58:21 +02:00
while mumble.is_alive():
2020-04-15 20:17:43 +02:00
if cursor_time < time.time() - BUFFER:
2020-04-10 23:58:21 +02:00
base_sound = None
2020-04-06 13:29:25 +02:00
2020-04-10 23:58:21 +02:00
try:
2020-04-15 20:17:43 +02:00
for user in mumble.users.values(): # check the audio queue of each user
2020-04-10 23:58:21 +02:00
if user.sound.is_sound():
2020-04-15 20:17:43 +02:00
# available sound is to be treated now and not later
sound = user.sound.get_sound(FLOAT_RESOLUTION)
stereo_pcm = audioop.tostereo(sound.pcm, 2, 1, 1)
if base_sound == None:
base_sound = stereo_pcm
else:
base_sound = audioop.add(base_sound, stereo_pcm, 2)
2020-04-10 23:58:21 +02:00
except RuntimeError:
2020-04-15 21:31:24 +02:00
print("ignored exception in stderr...", file=sys.stderr)
if is_streaming or stream_always:
if base_sound:
2020-04-16 21:05:51 +02:00
silence_time = 0
2020-04-15 21:31:24 +02:00
sys.stdout.buffer.write(base_sound)
else:
2020-04-16 21:05:51 +02:00
silence_time += RESOLUTION
sys.stdout.buffer.write(silent)
2020-04-16 21:47:39 +02:00
if auto_suspend_stream and (silence_time >= silence_limit_ms) and is_streaming:
2020-04-16 21:05:51 +02:00
is_streaming = False
2020-04-16 21:47:39 +02:00
mumble.my_channel().send_text_message("Diretta terminata in automatico dopo "+str(silence_limit)+" secondi circa di silenzio")
2020-04-16 21:05:51 +02:00
mumble.users.myself.unrecording()
2020-04-15 20:17:43 +02:00
2020-04-10 23:58:21 +02:00
cursor_time += FLOAT_RESOLUTION
else:
time.sleep(FLOAT_RESOLUTION)