From ebbacf652e433ea3f7ce5b900b4b4211e484e9a0 Mon Sep 17 00:00:00 2001 From: Terry Geng Date: Thu, 4 Jun 2020 12:02:59 +0800 Subject: [PATCH 1/6] fix: workaround for web interface eat up too much cpu, mentioned in #166 --- static/js/custom.js | 7 ++++--- templates/index.html | 8 ++++---- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/static/js/custom.js b/static/js/custom.js index 6ca98df..dbbbb7b 100644 --- a/static/js/custom.js +++ b/static/js/custom.js @@ -1049,9 +1049,9 @@ function updatePlayerPlayhead(playhead){ setProgressBar(playerBar, player_playhead_position / currentPlayingItem.duration, secondsToStr(player_playhead_position)); if (playing) { playhead_timer = setInterval(function () { - player_playhead_position += 0.1; + player_playhead_position += 0.3; setProgressBar(playerBar, player_playhead_position / currentPlayingItem.duration, secondsToStr(player_playhead_position)); - }, 100); // delay in milliseconds + }, 300); // delay in milliseconds } } else { if (playing) { @@ -1092,9 +1092,10 @@ function isOverflown(element) { } function setProgressBar(bar, progress, text="") { + let prog_pos = (-1 * (1 - progress)*bar.scrollWidth).toString(); let prog_str = (progress*100).toString(); bar.setAttribute("aria-valuenow", prog_str); - bar.style.width = prog_str + "%"; + bar.style.transform = "translateX(" + prog_pos + "px)"; bar.textContent = text; } diff --git a/templates/index.html b/templates/index.html index 8d681eb..18ac0db 100644 --- a/templates/index.html +++ b/templates/index.html @@ -454,8 +454,8 @@ Artist
-
+
@@ -528,8 +528,8 @@
-
+
From 92b3a3c7bebe425b8b55b4b304515d3c788a34aa Mon Sep 17 00:00:00 2001 From: Terry Geng Date: Fri, 5 Jun 2020 14:07:48 +0800 Subject: [PATCH 2/6] fix: wrong play bar behavior when dragging or clicking, #166. --- interface.py | 2 +- static/js/custom.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/interface.py b/interface.py index 964c4e6..230d50a 100644 --- a/interface.py +++ b/interface.py @@ -64,7 +64,7 @@ class ReverseProxied(object): web = Flask(__name__) -web.config['TEMPLATES_AUTO_RELOAD'] = True +#web.config['TEMPLATES_AUTO_RELOAD'] = True log = logging.getLogger("bot") user = 'Remote Control' diff --git a/static/js/custom.js b/static/js/custom.js index dbbbb7b..1c29fd6 100644 --- a/static/js/custom.js +++ b/static/js/custom.js @@ -1072,13 +1072,13 @@ playerBarBox.addEventListener('mousedown', function () { }); playerBarBox.addEventListener('mouseup', function (event) { playerBarBox.removeEventListener('mousemove', playheadDragged); - let percent = event.offsetX / playerBarBox.clientWidth; + let percent = (event.clientX - playerBarBox.getBoundingClientRect().x) / playerBarBox.clientWidth; request('post', {move_playhead: percent * currentPlayingItem.duration}); playhead_dragging = false; }); function playheadDragged(event){ - let percent = event.offsetX / playerBarBox.clientWidth; + let percent = (event.clientX - playerBarBox.getBoundingClientRect().x) / playerBarBox.clientWidth; setProgressBar(playerBar, percent, secondsToStr(percent * currentPlayingItem.duration)); } From 37082a82f3b8c9bf2b01e02d5210bc9d4051b5b8 Mon Sep 17 00:00:00 2001 From: Terry Geng Date: Fri, 5 Jun 2020 15:01:06 +0800 Subject: [PATCH 3/6] feat: stereo support, updated pymumble. --- configuration.default.ini | 1 + configuration.example.ini | 3 +++ mumbleBot.py | 24 ++++++++++++++++-------- requirements.txt | 2 +- 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/configuration.default.ini b/configuration.default.ini index 7d134e3..f4438fa 100644 --- a/configuration.default.ini +++ b/configuration.default.ini @@ -31,6 +31,7 @@ username = botamusique comment = Hi, I'm here to play radio, local music or youtube/soundcloud music. Have fun! # default volume from 0 to 1. volume = 0.1 +stereo = True # playback mode should be one of "one-shot", "repeat", "random", "autoplay" playback_mode = one-shot autoplay_length = 5 diff --git a/configuration.example.ini b/configuration.example.ini index 43176fc..79142e4 100644 --- a/configuration.example.ini +++ b/configuration.example.ini @@ -39,6 +39,9 @@ port = 64738 # 'admin': Users allowed to kill the bot, or ban URLs. Separated by ';' #admin = User1;User2; +# 'stereo': After 1.4.0, mumble starts to support stereo stream. Enable this option for stereo +# stream transmission. Otherwise the bot will down mix stereo sound into mono. +#stereo = True # 'volume' is default volume from 0 to 1. # This option will be overridden by value in the database. diff --git a/mumbleBot.py b/mumbleBot.py index bccc8ef..84eeb11 100644 --- a/mumbleBot.py +++ b/mumbleBot.py @@ -38,12 +38,13 @@ class MumbleBot: self.log.info(f"bot: botamusique version {self.version}, starting...") signal.signal(signal.SIGINT, self.ctrl_caught) self.cmd_handle = {} - self.volume_set = var.config.getfloat('bot', 'volume') + self.volume_set = var.config.getfloat('bot', 'volume', fallback=0.1) if var.db.has_option('bot', 'volume'): self.volume_set = var.db.getfloat('bot', 'volume') - self.volume = self.volume_set + self.stereo = var.config.getboolean('bot', 'stereo', fallback=True) + if args.channel: self.channel = args.channel else: @@ -62,6 +63,7 @@ class MumbleBot: self.song_start_at = -1 self.last_ffmpeg_err = "" self.read_pcm_size = 0 + self.pcm_buffer_size = 0 # self.download_threads = [] self.wait_for_ready = False # flag for the loop are waiting for download to complete in the other thread self.on_killing = threading.Lock() # lock to acquire when killing ffmpeg thread is asked but ffmpeg is not @@ -104,7 +106,9 @@ class MumbleBot: self.username = var.config.get("bot", "username") self.mumble = pymumble.Mumble(host, user=self.username, port=port, password=password, tokens=tokens, - debug=var.config.getboolean('debug', 'mumbleConnection'), certfile=certificate) + stereo=self.stereo, + debug=var.config.getboolean('debug', 'mumbleConnection'), + certfile=certificate) self.mumble.callbacks.set_callback(pymumble.constants.PYMUMBLE_CLBK_TEXTMESSAGERECEIVED, self.message_received) self.mumble.set_codec_profile("audio") @@ -369,8 +373,11 @@ class MumbleBot: else: ffmpeg_debug = "warning" + channels = 2 if self.stereo else 1 + self.pcm_buffer_size = 960*channels + command = ("ffmpeg", '-v', ffmpeg_debug, '-nostdin', '-i', - uri, '-ss', f"{start_from:f}", '-ac', '1', '-f', 's16le', '-ar', '48000', '-') + uri, '-ss', f"{start_from:f}", '-ac', str(channels), '-f', 's16le', '-ar', '48000', '-') self.log.debug("bot: execute ffmpeg command: " + " ".join(command)) # The ffmpeg process is a thread @@ -381,7 +388,7 @@ class MumbleBot: 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=self.pcm_buffer_size) def async_download_next(self): # Function start if the next music isn't ready @@ -452,8 +459,8 @@ class MumbleBot: self.song_start_at = time.time() - self.playhead self.playhead = time.time() - self.song_start_at - raw_music = self.thread.stdout.read(480) - self.read_pcm_size += 480 + raw_music = self.thread.stdout.read(self.pcm_buffer_size) + self.read_pcm_size += self.pcm_buffer_size if self.redirect_ffmpeg_log: try: @@ -476,7 +483,8 @@ class MumbleBot: if not self.is_pause and (self.thread is None or self.thread.poll() is not None): # bot is not paused, but ffmpeg thread has gone. # indicate that last song has finished, or the bot just resumed from pause, or something is wrong. - if self.read_pcm_size < 481 and len(var.playlist) > 0 and var.playlist.current_index != -1 \ + if self.read_pcm_size < self.pcm_buffer_size and len(var.playlist) > 0 \ + and var.playlist.current_index != -1 \ and self.last_ffmpeg_err: current = var.playlist.current_item() self.log.error("bot: cannot play music %s", current.format_debug_string()) diff --git a/requirements.txt b/requirements.txt index 5c93931..b0800bf 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,5 +7,5 @@ Pillow mutagen requests packaging -pymumble +pymumble>=1.2 pyradios \ No newline at end of file From 22b9caa6dd21b46a276ce231d4db67575ad96451 Mon Sep 17 00:00:00 2001 From: Azlux Date: Sun, 7 Jun 2020 01:11:40 +0200 Subject: [PATCH 4/6] remove explicite lib depending of pymumble --- requirements.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index b0800bf..2be02cb 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,3 @@ -opuslib==2.0.0 -protobuf==3.4.0 flask youtube-dl python-magic From e133788ba1f3aec86fe8ff3e19bae90bb4fe1182 Mon Sep 17 00:00:00 2001 From: Terry Geng Date: Tue, 9 Jun 2020 19:58:08 +0800 Subject: [PATCH 5/6] fix: playbar keeps extending when playlist is empty. --- static/js/custom.js | 1 + 1 file changed, 1 insertion(+) diff --git a/static/js/custom.js b/static/js/custom.js index 1c29fd6..710682d 100644 --- a/static/js/custom.js +++ b/static/js/custom.js @@ -989,6 +989,7 @@ function playerSetIdle(){ playerTitle.textContent = '-- IDLE --'; playerArtist.textContent = ''; setProgressBar(playerBar, 0); + clearInterval(playhead_timer); } function updatePlayerInfo(item){ From 3c87c33ddd2838b06756aa07f6fccc32ea62ce6e Mon Sep 17 00:00:00 2001 From: Terry Geng Date: Tue, 9 Jun 2020 21:21:23 +0800 Subject: [PATCH 6/6] fix: typo that renders refresh_cache_on_startup = False useless, #163 --- mumbleBot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mumbleBot.py b/mumbleBot.py index 84eeb11..ab7346a 100644 --- a/mumbleBot.py +++ b/mumbleBot.py @@ -778,7 +778,7 @@ if __name__ == '__main__': var.tmp_folder = util.solve_filepath(var.config.get('bot', 'tmp_folder')) var.cache = MusicCache(var.music_db) - if var.config.get("bot", "refresh_cache_on_startup", fallback=True): + if var.config.getboolean("bot", "refresh_cache_on_startup", fallback=True): var.cache.build_dir_cache() # ======================