Merge branch 'master' into master

This commit is contained in:
Terry Geng 2020-04-18 23:28:31 +08:00 committed by GitHub
commit d35e564681
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 50 additions and 25 deletions

View File

@ -105,6 +105,7 @@ password =
[debug] [debug]
# Set ffmpeg to True if you want to display DEBUG level log of ffmpeg. # Set ffmpeg to True if you want to display DEBUG level log of ffmpeg.
ffmpeg = False ffmpeg = False
redirect_ffmpeg_log = True
mumbleConnection = False mumbleConnection = False
# This is a list of default radio stations. # This is a list of default radio stations.

View File

@ -236,6 +236,7 @@ def status():
'play': not var.bot.is_pause, 'play': not var.bot.is_pause,
'mode': var.playlist.mode, 'mode': var.playlist.mode,
'volume': var.bot.volume_set}) 'volume': var.bot.volume_set})
else: else:
return jsonify({'ver': var.playlist.version, return jsonify({'ver': var.playlist.version,
'current_index': var.playlist.current_index, 'current_index': var.playlist.current_index,
@ -412,6 +413,7 @@ def post():
else: else:
# value for new volume is between 0 and 1, round to two decimal digits # value for new volume is between 0 and 1, round to two decimal digits
var.bot.volume_set = round(float(request.form['new_volume']), 2) var.bot.volume_set = round(float(request.form['new_volume']), 2)
var.db.set('bot', 'volume', str(var.bot.volume_set)) var.db.set('bot', 'volume', str(var.bot.volume_set))
log.info("web: volume set to %d" % (var.bot.volume_set * 100)) log.info("web: volume set to %d" % (var.bot.volume_set * 100))

View File

@ -30,7 +30,7 @@ from media.cache import MusicCache
class MumbleBot: class MumbleBot:
version = '6.1.1' version = '6.1.2'
def __init__(self, args): def __init__(self, args):
self.log = logging.getLogger("bot") self.log = logging.getLogger("bot")
@ -162,6 +162,8 @@ class MumbleBot:
self._display_rms = False self._display_rms = False
self._max_rms = 0 self._max_rms = 0
self.redirect_ffmpeg_log = var.config.getboolean('debug', 'redirect_ffmpeg_log', fallback=True)
# Set the CTRL+C shortcut # Set the CTRL+C shortcut
def ctrl_caught(self, signal, frame): def ctrl_caught(self, signal, frame):
@ -375,9 +377,12 @@ class MumbleBot:
# The ffmpeg process is a thread # The ffmpeg process is a thread
# prepare pipe for catching stderr of ffmpeg # prepare pipe for catching stderr of ffmpeg
pipe_rd, pipe_wd = os.pipe() if self.redirect_ffmpeg_log:
util.pipe_no_wait(pipe_rd) # Let the pipe work in non-blocking mode pipe_rd, pipe_wd = util.pipe_no_wait() # Let the pipe work in non-blocking mode
self.thread_stderr = os.fdopen(pipe_rd) self.thread_stderr = os.fdopen(pipe_rd)
else:
pipe_rd, pipe_wd = None, None
self.thread = sp.Popen(command, stdout=sp.PIPE, stderr=pipe_wd, bufsize=480) self.thread = sp.Popen(command, stdout=sp.PIPE, stderr=pipe_wd, bufsize=480)
self.is_pause = False self.is_pause = False
self.read_pcm_size = 0 self.read_pcm_size = 0
@ -449,12 +454,13 @@ class MumbleBot:
raw_music = self.thread.stdout.read(480) raw_music = self.thread.stdout.read(480)
self.read_pcm_size += 480 self.read_pcm_size += 480
try: if self.redirect_ffmpeg_log:
self.last_ffmpeg_err = self.thread_stderr.readline() try:
if self.last_ffmpeg_err: self.last_ffmpeg_err = self.thread_stderr.readline()
self.log.debug("ffmpeg: " + self.last_ffmpeg_err.strip("\n")) if self.last_ffmpeg_err:
except: self.log.debug("ffmpeg: " + self.last_ffmpeg_err.strip("\n"))
pass except:
pass
if raw_music: if raw_music:
# Adjust the volume and send it to mumble # Adjust the volume and send it to mumble
@ -623,9 +629,12 @@ class MumbleBot:
self.log.info("bot: execute ffmpeg command: " + " ".join(command)) self.log.info("bot: execute ffmpeg command: " + " ".join(command))
# The ffmpeg process is a thread # The ffmpeg process is a thread
# prepare pipe for catching stderr of ffmpeg # prepare pipe for catching stderr of ffmpeg
pipe_rd, pipe_wd = os.pipe() if self.redirect_ffmpeg_log:
util.pipe_no_wait(pipe_rd) # Let the pipe work in non-blocking mode pipe_rd, pipe_wd = util.pipe_no_wait() # Let the pipe work in non-blocking mode
self.thread_stderr = os.fdopen(pipe_rd) self.thread_stderr = os.fdopen(pipe_rd)
else:
pipe_rd, pipe_wd = None, None
self.thread = sp.Popen(command, stdout=sp.PIPE, stderr=pipe_wd, bufsize=480) self.thread = sp.Popen(command, stdout=sp.PIPE, stderr=pipe_wd, bufsize=480)
self.last_volume_cycle_time = time.time() self.last_volume_cycle_time = time.time()
self.pause_at_id = "" self.pause_at_id = ""

View File

@ -72,6 +72,7 @@
<input type="range" class="custom-range" id="volume-slider" <input type="range" class="custom-range" id="volume-slider"
min="0" max="1" step="0.01" value="0.5" min="0" max="1" step="0.01" value="0.5"
onchange="setVolumeDelayed(this.value)"> onchange="setVolumeDelayed(this.value)">
</input> </input>
<button type="button" class="btn btn-warning btn-space" <button type="button" class="btn btn-warning btn-space"

36
util.py
View File

@ -163,19 +163,29 @@ def url_unban(url):
return res return res
def pipe_no_wait(pipefd): def pipe_no_wait():
""" Used to fetch the STDERR of ffmpeg. pipefd is the file descriptor returned from os.pipe()""" """ Generate a non-block pipe used to fetch the STDERR of ffmpeg.
"""
if platform == "linux" or platform == "linux2" or platform == "darwin": if platform == "linux" or platform == "linux2" or platform == "darwin":
import fcntl import fcntl
import os import os
try:
fl = fcntl.fcntl(pipefd, fcntl.F_GETFL) pipe_rd = 0
fcntl.fcntl(pipefd, fcntl.F_SETFL, fl | os.O_NONBLOCK) pipe_wd = 0
except:
print(sys.exc_info()[1]) if hasattr(os, "pipe2"):
return False pipe_rd, pipe_wd = os.pipe2(os.O_NONBLOCK)
else: else:
return True pipe_rd, pipe_wd = os.pipe()
try:
fl = fcntl.fcntl(pipe_rd, fcntl.F_GETFL)
fcntl.fcntl(pipe_rd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
except:
print(sys.exc_info()[1])
return None, None
return pipe_rd, pipe_wd
elif platform == "win32": elif platform == "win32":
# https://stackoverflow.com/questions/34504970/non-blocking-read-on-os-pipe-on-windows # https://stackoverflow.com/questions/34504970/non-blocking-read-on-os-pipe-on-windows
@ -185,6 +195,8 @@ def pipe_no_wait(pipefd):
from ctypes import windll, byref, wintypes, WinError, POINTER from ctypes import windll, byref, wintypes, WinError, POINTER
from ctypes.wintypes import HANDLE, DWORD, BOOL from ctypes.wintypes import HANDLE, DWORD, BOOL
pipe_rd, pipe_wd = os.pipe()
LPDWORD = POINTER(DWORD) LPDWORD = POINTER(DWORD)
PIPE_NOWAIT = wintypes.DWORD(0x00000001) PIPE_NOWAIT = wintypes.DWORD(0x00000001)
ERROR_NO_DATA = 232 ERROR_NO_DATA = 232
@ -193,13 +205,13 @@ def pipe_no_wait(pipefd):
SetNamedPipeHandleState.argtypes = [HANDLE, LPDWORD, LPDWORD, LPDWORD] SetNamedPipeHandleState.argtypes = [HANDLE, LPDWORD, LPDWORD, LPDWORD]
SetNamedPipeHandleState.restype = BOOL SetNamedPipeHandleState.restype = BOOL
h = msvcrt.get_osfhandle(pipefd) h = msvcrt.get_osfhandle(pipe_rd)
res = windll.kernel32.SetNamedPipeHandleState(h, byref(PIPE_NOWAIT), None, None) res = windll.kernel32.SetNamedPipeHandleState(h, byref(PIPE_NOWAIT), None, None)
if res == 0: if res == 0:
print(WinError()) print(WinError())
return False return None, None
return True return pipe_rd, pipe_wd
class Dir(object): class Dir(object):