Compare commits
3 commits
master
...
mumble-bot
Author | SHA1 | Date | |
---|---|---|---|
7f0b6309ab | |||
e4854e9548 | |||
fe23d233a0 |
6 changed files with 178 additions and 1 deletions
|
@ -2,6 +2,7 @@ mumble-bot
|
|||
==========
|
||||
|
||||
prende l'audio del canale, ne fa stdout.
|
||||
prende l'audio da stdin, lo manda nel canale.
|
||||
|
||||
Install
|
||||
--------
|
||||
|
@ -58,3 +59,10 @@ samplerate: 48000,
|
|||
```
|
||||
|
||||
Poi entri in chat e fai il comando `/start` per iniziare la diretta, `/stop` per fermarla.
|
||||
|
||||
Client headless
|
||||
===============
|
||||
|
||||
```
|
||||
parecord --channels=1 --rate=48000 --format=s16le --raw | python3 bot.py --transmit --stream | paplay --raw --rate 48000 --format=s16le --channels=2
|
||||
```
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
import argparse
|
||||
import audioop
|
||||
import logging
|
||||
import math
|
||||
import sys
|
||||
import struct
|
||||
import time
|
||||
import threading
|
||||
from functools import partial
|
||||
|
||||
import pymumble_py3 as pymumble
|
||||
|
@ -11,6 +14,32 @@ from pymumble_py3.constants import PYMUMBLE_CLBK_TEXTMESSAGERECEIVED
|
|||
is_streaming = False
|
||||
silence_time = 0
|
||||
|
||||
SHORT_NORMALIZE = (1.0/32768.0)
|
||||
|
||||
## peak detection
|
||||
|
||||
def get_rms( block ):
|
||||
# RMS amplitude is defined as the square root of the
|
||||
# mean over time of the square of the amplitude.
|
||||
# so we need to convert this string of bytes into
|
||||
# a string of 16-bit samples...
|
||||
|
||||
# we will get one short out for each
|
||||
# two chars in the string.
|
||||
count = len(block)/2
|
||||
format = "%dh"%(count)
|
||||
shorts = struct.unpack( format, block )
|
||||
|
||||
# iterate over the block.
|
||||
sum_squares = 0.0
|
||||
for sample in shorts:
|
||||
# sample is a signed short in +/- 32768.
|
||||
# normalize it to 1.0
|
||||
n = sample * SHORT_NORMALIZE
|
||||
sum_squares += n*n
|
||||
|
||||
return math.sqrt( sum_squares / count )
|
||||
|
||||
|
||||
def message_received(mumble, message):
|
||||
global is_streaming
|
||||
|
@ -41,6 +70,11 @@ def get_parser():
|
|||
action="store_true",
|
||||
help="Ignore commands in chat and stream everything",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--transmit",
|
||||
action="store_true",
|
||||
help="Transmit from your stdin",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--auto-suspend-stream",
|
||||
action="store_true",
|
||||
|
@ -63,6 +97,22 @@ def get_parser():
|
|||
return parser
|
||||
|
||||
|
||||
def transmit(name, mumble, chunk_size):
|
||||
buffer = 0
|
||||
while True:
|
||||
try:
|
||||
data = sys.stdin.buffer.read(int(chunk_size))
|
||||
if(get_rms(data) > 0.09):
|
||||
mumble.sound_output.add_sound(data)
|
||||
buffer = 1000
|
||||
else:
|
||||
# keep the audio open for one second
|
||||
if(buffer >= 0):
|
||||
mumble.sound_output.add_sound(data)
|
||||
buffer -= 10
|
||||
except IOError as e:
|
||||
print( " Error recording: %s"3%e 0)
|
||||
|
||||
def main():
|
||||
global is_streaming
|
||||
global silence_time
|
||||
|
@ -89,7 +139,8 @@ def main():
|
|||
mumble.start()
|
||||
mumble.is_ready() # Wait for client is ready
|
||||
mumble.channels.find_by_tree(channel.split('/')).move_in()
|
||||
mumble.users.myself.mute()
|
||||
if not args.transmit:
|
||||
mumble.users.myself.mute()
|
||||
|
||||
if is_streaming:
|
||||
mumble.users.myself.recording()
|
||||
|
@ -103,6 +154,10 @@ def main():
|
|||
silent = b"\x00" * int(STEREO_CHUNK_SIZE)
|
||||
cursor_time = time.time() - BUFFER
|
||||
|
||||
if args.transmit:
|
||||
transmit_thread = threading.Thread(target=transmit, args=(1,mumble, MONO_CHUNK_SIZE))
|
||||
transmit_thread.start()
|
||||
|
||||
while mumble.is_alive():
|
||||
if cursor_time < time.time() - BUFFER:
|
||||
base_sound = None
|
||||
|
|
0
mumble-bot/bot.pya
Normal file
0
mumble-bot/bot.pya
Normal file
57
mumble-bot/bot2.py
Normal file
57
mumble-bot/bot2.py
Normal file
|
@ -0,0 +1,57 @@
|
|||
import pymumble_py3 as pymumble
|
||||
import subprocess as sp
|
||||
import time
|
||||
import sys
|
||||
import os
|
||||
import fcntl
|
||||
import audioop
|
||||
|
||||
pwd = "" # password
|
||||
server = "mumble.esiliati.org" # server address
|
||||
nick = "TubiaBot2"
|
||||
channel = "radiospore"
|
||||
port = 64738 # port number
|
||||
|
||||
# Spin up a client and connect to mumble server
|
||||
mumble = pymumble.Mumble(server, nick, password=pwd, port=port)
|
||||
# set up callback called when PCS event occurs
|
||||
mumble.set_receive_sound(1) # Enable receiving sound from mumble server
|
||||
mumble.start()
|
||||
mumble.is_ready() # Wait for client is ready
|
||||
mumble.channels.find_by_name(channel).move_in()
|
||||
mumble.users.myself.mute()
|
||||
|
||||
BUFFER = 0.2
|
||||
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
|
||||
|
||||
while mumble.is_alive():
|
||||
|
||||
if cursor_time < time.time() - BUFFER: # it's time to check audio
|
||||
base_sound = None
|
||||
|
||||
try:
|
||||
for user in mumble.users.values(): # check the audio queue of each user
|
||||
if(user.sound.is_sound()):
|
||||
print(user["name"])
|
||||
while ( user.sound.is_sound() and int(user.sound.first_sound().time) < int(cursor_time)):
|
||||
print("perdona e dimentica"+str(user.sound.first_sound().timestamp)+" "+str(cursor_time))
|
||||
user.sound.get_sound(FLOAT_RESOLUTION) # forget about too old sounds
|
||||
|
||||
if user.sound.is_sound():
|
||||
print(user["name"]+" estraggo")
|
||||
sound = user.sound.get_sound(FLOAT_RESOLUTION)
|
||||
|
||||
except RuntimeError:
|
||||
eprint("ignored exception in stderr...")
|
||||
|
||||
cursor_time += FLOAT_RESOLUTION
|
||||
else:
|
||||
time.sleep(FLOAT_RESOLUTION)
|
||||
|
34
mumble-bot/silent-bot.py
Normal file
34
mumble-bot/silent-bot.py
Normal file
|
@ -0,0 +1,34 @@
|
|||
import pymumble_py3 as pymumble
|
||||
import subprocess as sp
|
||||
from time import sleep
|
||||
import sys
|
||||
import os
|
||||
import fcntl
|
||||
import pyaudio
|
||||
|
||||
pwd = "" # password
|
||||
server = "mumble.esiliati.org" # server address
|
||||
nick = "TubiaBotSilente"
|
||||
channel = "radiospore_onair"
|
||||
port = 64738 # port number
|
||||
|
||||
# pyaudio set up
|
||||
CHUNK = 1024
|
||||
FORMAT = pyaudio.paInt16 # pymumble soundchunk.pcm is 16 bits
|
||||
CHANNELS = 1
|
||||
RATE = 48000 # pymumble soundchunk.pcm is 48000Hz
|
||||
|
||||
# Spin up a client and connect to mumble server
|
||||
mumble = pymumble.Mumble(server, nick, password=pwd, port=port)
|
||||
# set up callback called when PCS event occurs
|
||||
mumble.set_receive_sound(0) # Enable receiving sound from mumble server
|
||||
mumble.start()
|
||||
mumble.is_ready() # Wait for client is ready
|
||||
mumble.channels.find_by_name(channel).move_in()
|
||||
#mumble.users.myself.mute()
|
||||
|
||||
# constant capturing sound and sending it to mumble server
|
||||
|
||||
while True:
|
||||
mumble.sound_output.add_sound(bytes([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]))
|
||||
|
23
mumble-bot/testparams.py
Normal file
23
mumble-bot/testparams.py
Normal file
|
@ -0,0 +1,23 @@
|
|||
import argparse
|
||||
import sys
|
||||
pwd=""
|
||||
server = "mumble.esiliati.org" # server address
|
||||
nick = "TubiaBot"
|
||||
channel = "radiospore"
|
||||
port = 64738 # port number
|
||||
is_streaming=False
|
||||
stream_always=False
|
||||
|
||||
|
||||
parser = argparse.ArgumentParser(description='Regia pienamente automatizzata')
|
||||
parser.add_argument('--channel', help='Set channel')
|
||||
parser.add_argument('--name', help='Set bot nickname', default="RadioRobbot")
|
||||
parser.add_argument('--server', help='Set server', default="mumble.esiliati.org")
|
||||
parser.add_argument('--port', help='Set port', type=int)
|
||||
parser.add_argument('--stream', action='store_true', help='Ignore commands in chat and stream everything')
|
||||
|
||||
sys.argv.pop(0)
|
||||
|
||||
args = parser.parse_args(sys.argv)
|
||||
|
||||
print(args.name)
|
Loading…
Reference in a new issue