added feature for playing sounds backwards
This commit is contained in:
		
							parent
							
								
									5c9de31835
								
							
						
					
					
						commit
						fad8daf05d
					
				@ -303,8 +303,9 @@ class AudioClip():
 | 
				
			|||||||
	def __del__(self):
 | 
						def __del__(self):
 | 
				
			||||||
		self.Logger.info("~AudioClip()")
 | 
							self.Logger.info("~AudioClip()")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def Play(self, seconds = None, rubberband = None, dec_params = None, *args):
 | 
						def Play(self, seconds = None, rubberband = None, dec_params = None, bitrate = None, backwards = None, *args):
 | 
				
			||||||
        return self.AudioPlayer.PlayURI(self.URI, position = seconds, rubberband = rubberband, dec_params = dec_params, *args)
 | 
							return self.AudioPlayer.PlayURI(self.URI, position = seconds, rubberband = rubberband, dec_params = dec_params, bitrate = bitrate, 
 | 
				
			||||||
 | 
					            backwards = backwards, *args)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	def Stop(self):
 | 
						def Stop(self):
 | 
				
			||||||
		return self.AudioPlayer.Stop()
 | 
							return self.AudioPlayer.Stop()
 | 
				
			||||||
 | 
				
			|||||||
@ -8,6 +8,33 @@ import math
 | 
				
			|||||||
from .Utils import Utils, DataHolder
 | 
					from .Utils import Utils, DataHolder
 | 
				
			||||||
import traceback
 | 
					import traceback
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def get_birtate(message):
 | 
				
			||||||
 | 
					    bitrate = []
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        for msg in message[1].split(" "): #checking if
 | 
				
			||||||
 | 
					            if "bitrate=" in msg:
 | 
				
			||||||
 | 
					                bitrate = int(msg.split("bitrate=",1)[1])
 | 
				
			||||||
 | 
					                if bitrate < 0.0:
 | 
				
			||||||
 | 
					                    bitrate = 0.01
 | 
				
			||||||
 | 
					                if bitrate > 2000:
 | 
				
			||||||
 | 
					                    bitrate = 20
 | 
				
			||||||
 | 
					                bitrate.append(f"bitrate=tempo={bitrate}")
 | 
				
			||||||
 | 
					    except Exception:
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					    return bitrate 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def get_backwards(message):
 | 
				
			||||||
 | 
					    backwards = None
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        for msg in message[1].split(" "): #checking if pitch= or tempo= is specified
 | 
				
			||||||
 | 
					            if "backward=" in msg.lower():
 | 
				
			||||||
 | 
					                backwards = True
 | 
				
			||||||
 | 
					            elif "backwards=" in msg.lower():
 | 
				
			||||||
 | 
					                backwards = True
 | 
				
			||||||
 | 
					    except Exception:
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					    return backwards
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def get_rubberBand(message):
 | 
					def get_rubberBand(message):
 | 
				
			||||||
    rubberband = []
 | 
					    rubberband = []
 | 
				
			||||||
    try:
 | 
					    try:
 | 
				
			||||||
@ -548,6 +575,8 @@ class VoiceCommands(BaseCommand):
 | 
				
			|||||||
            return 0
 | 
					            return 0
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        rubberband = get_rubberBand(message)
 | 
					        rubberband = get_rubberBand(message)
 | 
				
			||||||
 | 
					        backwards = get_backwards(message)
 | 
				
			||||||
 | 
					        bitrate = get_birtate(message)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if message[0] == "!random":
 | 
					        if message[0] == "!random":
 | 
				
			||||||
            Trigger = self.random.choice(list(self.VoiceTriggers.values()))
 | 
					            Trigger = self.random.choice(list(self.VoiceTriggers.values()))
 | 
				
			||||||
@ -614,7 +643,7 @@ class VoiceCommands(BaseCommand):
 | 
				
			|||||||
        if not AudioClip:
 | 
					        if not AudioClip:
 | 
				
			||||||
            return 1
 | 
					            return 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return AudioClip.Play(rubberband = rubberband)
 | 
					        return AudioClip.Play(rubberband = rubberband, bitrate = bitrate, backwards = backwards)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class YouTube(BaseCommand):
 | 
					class YouTube(BaseCommand):
 | 
				
			||||||
@ -647,7 +676,9 @@ class YouTube(BaseCommand):
 | 
				
			|||||||
        #turning the string into a list where get_rubberband just picks the second element to search in
 | 
					        #turning the string into a list where get_rubberband just picks the second element to search in
 | 
				
			||||||
        dline = ['', line.split(" ", 1)[1]]
 | 
					        dline = ['', line.split(" ", 1)[1]]
 | 
				
			||||||
        rubberband = get_rubberBand(dline)
 | 
					        rubberband = get_rubberBand(dline)
 | 
				
			||||||
        return AudioClip.Play(Time, rubberband = rubberband)
 | 
					        backwards = get_backwards(dline)
 | 
				
			||||||
 | 
					        bitrate = get_birtate(dline)
 | 
				
			||||||
 | 
					        return AudioClip.Play(Time, rubberband = rubberband, bitrate = bitrate, backwards = backwards)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class YouTubeSearch(BaseCommand):
 | 
					class YouTubeSearch(BaseCommand):
 | 
				
			||||||
    import json
 | 
					    import json
 | 
				
			||||||
@ -693,7 +724,9 @@ class YouTubeSearch(BaseCommand):
 | 
				
			|||||||
        #turning the string into a list where get_rubberband just picks the second element to search in
 | 
					        #turning the string into a list where get_rubberband just picks the second element to search in
 | 
				
			||||||
        dline = ['', line.split(" ", 1)[1]]
 | 
					        dline = ['', line.split(" ", 1)[1]]
 | 
				
			||||||
        rubberband = get_rubberBand(dline)
 | 
					        rubberband = get_rubberBand(dline)
 | 
				
			||||||
        return AudioClip.Play(Time, rubberband = rubberband)
 | 
					        backwards = get_backwards(dline)
 | 
				
			||||||
 | 
					        bitrate = get_birtate(dline)
 | 
				
			||||||
 | 
					        return AudioClip.Play(Time, rubberband = rubberband, bitrate = bitrate, backwards = backwards)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Say(BaseCommand):
 | 
					class Say(BaseCommand):
 | 
				
			||||||
@ -721,9 +754,17 @@ class Say(BaseCommand):
 | 
				
			|||||||
        try:
 | 
					        try:
 | 
				
			||||||
            dline = ['', message.split(" ", 1)[1]]
 | 
					            dline = ['', message.split(" ", 1)[1]]
 | 
				
			||||||
            rubberband = get_rubberBand(dline)
 | 
					            rubberband = get_rubberBand(dline)
 | 
				
			||||||
 | 
					            backwards = get_backwards(dline)
 | 
				
			||||||
        except Exception:
 | 
					        except Exception:
 | 
				
			||||||
            rubberband = None
 | 
					            rubberband = None
 | 
				
			||||||
        if AudioClip.Play(rubberband = rubberband):
 | 
					            backwards = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            dline = ['', message.split(" ", 1)[1]]
 | 
				
			||||||
 | 
					            bitrate = get_birtate(dline)
 | 
				
			||||||
 | 
					        except Exception:
 | 
				
			||||||
 | 
					            bitrate = None
 | 
				
			||||||
 | 
					        if AudioClip.Play(rubberband = rubberband, bitrate = bitrate, backwards = backwards):
 | 
				
			||||||
            AudioClip.AudioPlayer.AddCallback("Stop", lambda: os.unlink(TempFile.name))
 | 
					            AudioClip.AudioPlayer.AddCallback("Stop", lambda: os.unlink(TempFile.name))
 | 
				
			||||||
            return 0
 | 
					            return 0
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
 | 
				
			|||||||
@ -12,52 +12,53 @@ import sys
 | 
				
			|||||||
SAMPLEBYTES = 2
 | 
					SAMPLEBYTES = 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class FFmpegAudioPlayerFactory():
 | 
					class FFmpegAudioPlayerFactory():
 | 
				
			||||||
	VALID_CALLBACKS = ["Play", "Stop", "Update"]
 | 
					    VALID_CALLBACKS = ["Play", "Stop", "Update"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	def __init__(self, master):
 | 
					    def __init__(self, master):
 | 
				
			||||||
		self.Logger = logging.getLogger(__class__.__name__)
 | 
					        self.Logger = logging.getLogger(__class__.__name__)
 | 
				
			||||||
		self.Master = master
 | 
					        self.Master = master
 | 
				
			||||||
		self.Torchlight = self.Master.Torchlight
 | 
					        self.Torchlight = self.Master.Torchlight
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	def __del__(self):
 | 
					    def __del__(self):
 | 
				
			||||||
		self.Master.Logger.info("~FFmpegAudioPlayerFactory()")
 | 
					        self.Master.Logger.info("~FFmpegAudioPlayerFactory()")
 | 
				
			||||||
		self.Quit()
 | 
					        self.Quit()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	def NewPlayer(self):
 | 
					    def NewPlayer(self):
 | 
				
			||||||
		self.Logger.debug(sys._getframe().f_code.co_name)
 | 
					        self.Logger.debug(sys._getframe().f_code.co_name)
 | 
				
			||||||
		Player = FFmpegAudioPlayer(self)
 | 
					        Player = FFmpegAudioPlayer(self)
 | 
				
			||||||
		return Player
 | 
					        return Player
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	def Quit(self):
 | 
					    def Quit(self):
 | 
				
			||||||
		self.Master.Logger.info("FFmpegAudioPlayerFactory->Quit()")
 | 
					        self.Master.Logger.info("FFmpegAudioPlayerFactory->Quit()")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class FFmpegAudioPlayer():
 | 
					class FFmpegAudioPlayer():
 | 
				
			||||||
	def __init__(self, master):
 | 
					    def __init__(self, master):
 | 
				
			||||||
		self.Master = master
 | 
					        self.Master = master
 | 
				
			||||||
		self.Torchlight = self.Master.Torchlight
 | 
					        self.Torchlight = self.Master.Torchlight
 | 
				
			||||||
		self.Playing = False
 | 
					        self.Playing = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		self.Host = (
 | 
					        self.Host = (
 | 
				
			||||||
			self.Torchlight().Config["VoiceServer"]["Host"],
 | 
					            self.Torchlight().Config["VoiceServer"]["Host"],
 | 
				
			||||||
			self.Torchlight().Config["VoiceServer"]["Port"]
 | 
					            self.Torchlight().Config["VoiceServer"]["Port"]
 | 
				
			||||||
		)
 | 
					        )
 | 
				
			||||||
		self.SampleRate = float(self.Torchlight().Config["VoiceServer"]["SampleRate"])
 | 
					        self.SampleRate = float(self.Torchlight().Config["VoiceServer"]["SampleRate"])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		self.StartedPlaying = None
 | 
					        self.StartedPlaying = None
 | 
				
			||||||
		self.StoppedPlaying = None
 | 
					        self.StoppedPlaying = None
 | 
				
			||||||
		self.Seconds = 0.0
 | 
					        self.Seconds = 0.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		self.Writer = None
 | 
					        self.Writer = None
 | 
				
			||||||
		self.Process = None
 | 
					        self.Process = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		self.Callbacks = []
 | 
					        self.Callbacks = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	def __del__(self):
 | 
					    def __del__(self):
 | 
				
			||||||
		self.Master.Logger.debug("~FFmpegAudioPlayer()")
 | 
					        self.Master.Logger.debug("~FFmpegAudioPlayer()")
 | 
				
			||||||
		self.Stop()
 | 
					        self.Stop()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def PlayURI(self, uri, position, rubberband = None, dec_params = None, *args):
 | 
					    def PlayURI(self, uri, position, rubberband = None, dec_params = None, bitrate = None, 
 | 
				
			||||||
 | 
					            backwards = None, *args):
 | 
				
			||||||
        if position:
 | 
					        if position:
 | 
				
			||||||
            PosStr = str(datetime.timedelta(seconds = position))
 | 
					            PosStr = str(datetime.timedelta(seconds = position))
 | 
				
			||||||
            Command = ["/usr/bin/ffmpeg", "-ss", PosStr, "-i", uri, "-acodec", "pcm_s16le", "-ac", "1", "-ar", str(int(self.SampleRate)), "-f", "s16le", "-vn", *args]
 | 
					            Command = ["/usr/bin/ffmpeg", "-ss", PosStr, "-i", uri, "-acodec", "pcm_s16le", "-ac", "1", "-ar", str(int(self.SampleRate)), "-f", "s16le", "-vn", *args]
 | 
				
			||||||
@ -68,122 +69,137 @@ class FFmpegAudioPlayer():
 | 
				
			|||||||
        if dec_params:
 | 
					        if dec_params:
 | 
				
			||||||
            Command += dec_params
 | 
					            Command += dec_params
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if rubberband:
 | 
					        if rubberband and backwards:
 | 
				
			||||||
            Command += ["-filter:a"]
 | 
					            Command += ["-filter:a"]
 | 
				
			||||||
            rubberCommand = ""
 | 
					            rubberCommand = ""
 | 
				
			||||||
            for rubber in rubberband:
 | 
					            for rubber in rubberband:
 | 
				
			||||||
                rubberCommand += rubber + ", "
 | 
					                rubberCommand += rubber + ", "
 | 
				
			||||||
            rubberCommand = rubberCommand[:-2]
 | 
					            rubberCommand = rubberCommand[:-2]
 | 
				
			||||||
            Command += [rubberCommand]
 | 
					            Command += [rubberCommand + "[reversed];[reversed]areverse"] #[reversed] is intermediate stream label so reverse knows what stream label to reverse
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            if rubberband:
 | 
				
			||||||
 | 
					                Command += ["-filter:a"]
 | 
				
			||||||
 | 
					                rubberCommand = ""
 | 
				
			||||||
 | 
					                for rubber in rubberband:
 | 
				
			||||||
 | 
					                    rubberCommand += rubber + ", "
 | 
				
			||||||
 | 
					                rubberCommand = rubberCommand[:-2]
 | 
				
			||||||
 | 
					                Command += [rubberCommand]
 | 
				
			||||||
 | 
					            if backwards:
 | 
				
			||||||
 | 
					                Command += ["-af"]
 | 
				
			||||||
 | 
					                Command += ["areverse"]
 | 
				
			||||||
 | 
					        if bitrate:
 | 
				
			||||||
 | 
					            Command += ["-ab ", str(bitrate), "k"]
 | 
				
			||||||
 | 
					            self.Master.Logger.debug(f"command: {Command}")
 | 
				
			||||||
        Command += ["-"]
 | 
					        Command += ["-"]
 | 
				
			||||||
 | 
					        #self.Master.Logger.debug(f"command: {Command}")
 | 
				
			||||||
        asyncio.ensure_future(self._stream_subprocess(Command))
 | 
					        asyncio.ensure_future(self._stream_subprocess(Command))
 | 
				
			||||||
        return True
 | 
					        return True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	def Stop(self, force = True):
 | 
					    def Stop(self, force = True):
 | 
				
			||||||
		if not self.Playing:
 | 
					        if not self.Playing:
 | 
				
			||||||
			return False
 | 
					            return False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if self.Process:
 | 
					        if self.Process:
 | 
				
			||||||
			try:
 | 
					            try:
 | 
				
			||||||
				self.Process.terminate()
 | 
					                self.Process.terminate()
 | 
				
			||||||
				self.Process.kill()
 | 
					                self.Process.kill()
 | 
				
			||||||
				self.Process = None
 | 
					                self.Process = None
 | 
				
			||||||
			except ProcessLookupError:
 | 
					            except ProcessLookupError:
 | 
				
			||||||
				pass
 | 
					                pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if self.Writer:
 | 
					        if self.Writer:
 | 
				
			||||||
			if force:
 | 
					            if force:
 | 
				
			||||||
				Socket = self.Writer.transport.get_extra_info("socket")
 | 
					                Socket = self.Writer.transport.get_extra_info("socket")
 | 
				
			||||||
				if Socket:
 | 
					                if Socket:
 | 
				
			||||||
					Socket.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER,
 | 
					                    Socket.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER,
 | 
				
			||||||
						struct.pack("ii", 1, 0))
 | 
					                        struct.pack("ii", 1, 0))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				self.Writer.transport.abort()
 | 
					                self.Writer.transport.abort()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			self.Writer.close()
 | 
					            self.Writer.close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		self.Playing = False
 | 
					        self.Playing = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		self.Callback("Stop")
 | 
					        self.Callback("Stop")
 | 
				
			||||||
		del self.Callbacks
 | 
					        del self.Callbacks
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return True
 | 
					        return True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	def AddCallback(self, cbtype, cbfunc):
 | 
					    def AddCallback(self, cbtype, cbfunc):
 | 
				
			||||||
		if not cbtype in FFmpegAudioPlayerFactory.VALID_CALLBACKS:
 | 
					        if not cbtype in FFmpegAudioPlayerFactory.VALID_CALLBACKS:
 | 
				
			||||||
			return False
 | 
					            return False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		self.Callbacks.append((cbtype, cbfunc))
 | 
					        self.Callbacks.append((cbtype, cbfunc))
 | 
				
			||||||
		return True
 | 
					        return True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	def Callback(self, cbtype, *args, **kwargs):
 | 
					    def Callback(self, cbtype, *args, **kwargs):
 | 
				
			||||||
		for Callback in self.Callbacks:
 | 
					        for Callback in self.Callbacks:
 | 
				
			||||||
			if Callback[0] == cbtype:
 | 
					            if Callback[0] == cbtype:
 | 
				
			||||||
				try:
 | 
					                try:
 | 
				
			||||||
					Callback[1](*args, **kwargs)
 | 
					                    Callback[1](*args, **kwargs)
 | 
				
			||||||
				except Exception as e:
 | 
					                except Exception as e:
 | 
				
			||||||
					self.Master.Logger.error(traceback.format_exc())
 | 
					                    self.Master.Logger.error(traceback.format_exc())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	async def _updater(self):
 | 
					    async def _updater(self):
 | 
				
			||||||
		LastSecondsElapsed = 0.0
 | 
					        LastSecondsElapsed = 0.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		while self.Playing:
 | 
					        while self.Playing:
 | 
				
			||||||
			SecondsElapsed = time.time() - self.StartedPlaying
 | 
					            SecondsElapsed = time.time() - self.StartedPlaying
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if SecondsElapsed > self.Seconds:
 | 
					            if SecondsElapsed > self.Seconds:
 | 
				
			||||||
				SecondsElapsed = self.Seconds
 | 
					                SecondsElapsed = self.Seconds
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			self.Callback("Update", LastSecondsElapsed, SecondsElapsed)
 | 
					            self.Callback("Update", LastSecondsElapsed, SecondsElapsed)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if SecondsElapsed >= self.Seconds:
 | 
					            if SecondsElapsed >= self.Seconds:
 | 
				
			||||||
				if not self.StoppedPlaying:
 | 
					                if not self.StoppedPlaying:
 | 
				
			||||||
					print("BUFFER UNDERRUN!")
 | 
					                    print("BUFFER UNDERRUN!")
 | 
				
			||||||
				self.Stop(False)
 | 
					                self.Stop(False)
 | 
				
			||||||
				return
 | 
					                return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			LastSecondsElapsed = SecondsElapsed
 | 
					            LastSecondsElapsed = SecondsElapsed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			await asyncio.sleep(0.1)
 | 
					            await asyncio.sleep(0.1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	async def _read_stream(self, stream, writer):
 | 
					    async def _read_stream(self, stream, writer):
 | 
				
			||||||
		Started = False
 | 
					        Started = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		while stream and self.Playing:
 | 
					        while stream and self.Playing:
 | 
				
			||||||
			Data = await stream.read(65536)
 | 
					            Data = await stream.read(65536)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if Data:
 | 
					            if Data:
 | 
				
			||||||
				writer.write(Data)
 | 
					                writer.write(Data)
 | 
				
			||||||
				await writer.drain()
 | 
					                await writer.drain()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				Bytes = len(Data)
 | 
					                Bytes = len(Data)
 | 
				
			||||||
				Samples = Bytes / SAMPLEBYTES
 | 
					                Samples = Bytes / SAMPLEBYTES
 | 
				
			||||||
				Seconds = Samples / self.SampleRate
 | 
					                Seconds = Samples / self.SampleRate
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				self.Seconds += Seconds
 | 
					                self.Seconds += Seconds
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if not Started:
 | 
					                if not Started:
 | 
				
			||||||
					Started = True
 | 
					                    Started = True
 | 
				
			||||||
					self.Callback("Play")
 | 
					                    self.Callback("Play")
 | 
				
			||||||
					self.StartedPlaying = time.time()
 | 
					                    self.StartedPlaying = time.time()
 | 
				
			||||||
					asyncio.ensure_future(self._updater())
 | 
					                    asyncio.ensure_future(self._updater())
 | 
				
			||||||
			else:
 | 
					            else:
 | 
				
			||||||
				self.Process = None
 | 
					                self.Process = None
 | 
				
			||||||
				break
 | 
					                break
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		self.StoppedPlaying = time.time()
 | 
					        self.StoppedPlaying = time.time()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	async def _stream_subprocess(self, cmd):
 | 
					    async def _stream_subprocess(self, cmd):
 | 
				
			||||||
		if not self.Playing:
 | 
					        if not self.Playing:
 | 
				
			||||||
			return
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		_, self.Writer = await asyncio.open_connection(self.Host[0], self.Host[1])
 | 
					        _, self.Writer = await asyncio.open_connection(self.Host[0], self.Host[1])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Process = await asyncio.create_subprocess_exec(*cmd,
 | 
					        Process = await asyncio.create_subprocess_exec(*cmd,
 | 
				
			||||||
				stdout = asyncio.subprocess.PIPE, stderr = asyncio.subprocess.DEVNULL)
 | 
					                stdout = asyncio.subprocess.PIPE, stderr = asyncio.subprocess.DEVNULL)
 | 
				
			||||||
		self.Process = Process
 | 
					        self.Process = Process
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		await self._read_stream(Process.stdout, self.Writer)
 | 
					        await self._read_stream(Process.stdout, self.Writer)
 | 
				
			||||||
		await Process.wait()
 | 
					        await Process.wait()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if self.Seconds == 0.0:
 | 
					        if self.Seconds == 0.0:
 | 
				
			||||||
			self.Stop()
 | 
					            self.Stop()
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user