fix: Avoid truncating last ~100ms of music when playing.
Somehow subprocess.poll() will return before all music stream has been retrieved from stdout of the ffmpeg thread, causing the last bit of the stream being truncated. Fixed #199.
This commit is contained in:
parent
b3fe43cb18
commit
14668bb2b8
18
mumbleBot.py
18
mumbleBot.py
@ -456,15 +456,14 @@ class MumbleBot:
|
|||||||
|
|
||||||
# Main loop of the Bot
|
# Main loop of the Bot
|
||||||
def loop(self):
|
def loop(self):
|
||||||
raw_music = ""
|
|
||||||
while not self.exit and self.mumble.is_alive():
|
while not self.exit and self.mumble.is_alive():
|
||||||
|
|
||||||
while self.is_ffmpeg_running() and self.mumble.sound_output.get_buffer_size() > 0.5 and not self.exit:
|
while self.thread and self.mumble.sound_output.get_buffer_size() > 0.5 and not self.exit:
|
||||||
# If the buffer isn't empty, I cannot send new music part, so I wait
|
# If the buffer isn't empty, I cannot send new music part, so I wait
|
||||||
self._loop_status = f'Wait for buffer {self.mumble.sound_output.get_buffer_size():.3f}'
|
self._loop_status = f'Wait for buffer {self.mumble.sound_output.get_buffer_size():.3f}'
|
||||||
time.sleep(0.01)
|
time.sleep(0.01)
|
||||||
|
|
||||||
if self.is_ffmpeg_running():
|
if self.thread:
|
||||||
# I get raw from ffmpeg thread
|
# I get raw from ffmpeg thread
|
||||||
# move playhead forward
|
# move playhead forward
|
||||||
self._loop_status = 'Reading raw'
|
self._loop_status = 'Reading raw'
|
||||||
@ -487,16 +486,17 @@ class MumbleBot:
|
|||||||
# Adjust the volume and send it to mumble
|
# Adjust the volume and send it to mumble
|
||||||
self.volume_cycle()
|
self.volume_cycle()
|
||||||
|
|
||||||
if not self.on_interrupting and self.read_pcm_size > 0:
|
if not self.on_interrupting and len(raw_music) == self.pcm_buffer_size:
|
||||||
self.mumble.sound_output.add_sound(
|
self.mumble.sound_output.add_sound(
|
||||||
audioop.mul(raw_music, 2, self.volume_helper.real_volume))
|
audioop.mul(raw_music, 2, self.volume_helper.real_volume))
|
||||||
elif self.read_pcm_size == 0:
|
elif self.read_pcm_size == 0:
|
||||||
self.mumble.sound_output.add_sound(
|
self.mumble.sound_output.add_sound(
|
||||||
audioop.mul(self._fadeout(raw_music, self.stereo, fadein=True), 2, self.volume_helper.real_volume))
|
audioop.mul(self._fadeout(raw_music, self.stereo, fadein=True), 2, self.volume_helper.real_volume))
|
||||||
else:
|
elif self.on_interrupting or len(raw_music) < self.pcm_buffer_size:
|
||||||
self.mumble.sound_output.add_sound(
|
self.mumble.sound_output.add_sound(
|
||||||
audioop.mul(self._fadeout(raw_music, self.stereo, fadein=False), 2, self.volume_helper.real_volume))
|
audioop.mul(self._fadeout(raw_music, self.stereo, fadein=False), 2, self.volume_helper.real_volume))
|
||||||
self.thread.kill()
|
self.thread.kill()
|
||||||
|
self.thread = None
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
self.on_interrupting = False
|
self.on_interrupting = False
|
||||||
else:
|
else:
|
||||||
@ -504,7 +504,7 @@ class MumbleBot:
|
|||||||
else:
|
else:
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
|
|
||||||
if not self.is_pause and not self.is_ffmpeg_running():
|
if not self.is_pause and self.thread is None:
|
||||||
# bot is not paused, but ffmpeg thread has gone.
|
# 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.
|
# indicate that last song has finished, or the bot just resumed from pause, or something is wrong.
|
||||||
if self.read_pcm_size < self.pcm_buffer_size and len(var.playlist) > 0 \
|
if self.read_pcm_size < self.pcm_buffer_size and len(var.playlist) > 0 \
|
||||||
@ -628,9 +628,6 @@ class MumbleBot:
|
|||||||
# Play Control
|
# Play Control
|
||||||
# =======================
|
# =======================
|
||||||
|
|
||||||
def is_ffmpeg_running(self):
|
|
||||||
return self.thread and self.thread.poll() is None
|
|
||||||
|
|
||||||
def play(self, index=-1, start_at=0):
|
def play(self, index=-1, start_at=0):
|
||||||
if not self.is_pause:
|
if not self.is_pause:
|
||||||
self.interrupt()
|
self.interrupt()
|
||||||
@ -661,9 +658,10 @@ class MumbleBot:
|
|||||||
|
|
||||||
def interrupt(self):
|
def interrupt(self):
|
||||||
# Kill the ffmpeg thread
|
# Kill the ffmpeg thread
|
||||||
if self.is_ffmpeg_running():
|
if self.thread:
|
||||||
self.on_interrupting = True
|
self.on_interrupting = True
|
||||||
|
|
||||||
|
time.sleep(0.1)
|
||||||
self.song_start_at = -1
|
self.song_start_at = -1
|
||||||
self.read_pcm_size = 0
|
self.read_pcm_size = 0
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user