Changed VLC again for sound_lib

This commit is contained in:
Manuel Cortez 2021-09-22 17:32:10 -05:00
parent 1cd7d2ad39
commit 226a17b4fe
2 changed files with 41 additions and 73 deletions

View File

@ -1,6 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
""" main controller for MusicDL""" """ main controller for MusicDL"""
from __future__ import unicode_literals # at top of module
import types import types
import webbrowser import webbrowser
import wx import wx
@ -116,15 +115,15 @@ class Controller(object):
elif ev.GetKeyCode() == wx.WXK_SPACE: elif ev.GetKeyCode() == wx.WXK_SPACE:
return self.on_play_pause() return self.on_play_pause()
elif ev.GetKeyCode() == wx.WXK_LEFT and ev.ShiftDown(): elif ev.GetKeyCode() == wx.WXK_LEFT and ev.ShiftDown():
position = player.player.player.get_time() position = player.player.player.get_position()
if position > 5000: if position > 5000:
player.player.player.set_time(position-5000) player.player.player.set_position(position-5000)
else: else:
player.player.player.set_time(0) player.player.player.set_position(0)
return return
elif ev.GetKeyCode() == wx.WXK_RIGHT and ev.ShiftDown(): elif ev.GetKeyCode() == wx.WXK_RIGHT and ev.ShiftDown():
position = player.player.player.get_time() position = player.player.player.get_position()
player.player.player.set_time(position+5000) player.player.player.set_position(position+5000)
return return
elif ev.GetKeyCode() == wx.WXK_UP and ev.ControlDown(): elif ev.GetKeyCode() == wx.WXK_UP and ev.ControlDown():
return self.on_volume_up() return self.on_volume_up()
@ -206,13 +205,15 @@ class Controller(object):
def on_time_change(self, event, *args, **kwargs): def on_time_change(self, event, *args, **kwargs):
p = event.GetPosition() p = event.GetPosition()
player.player.player.set_position(p/100.0) if player.player.player != None:
player.player.player.set_position(p/100.0)
event.Skip() event.Skip()
def on_timer(self, *args, **kwargs): def on_timer(self, *args, **kwargs):
if not self.window.time_slider.HasFocus(): if not self.window.time_slider.HasFocus():
progress = player.player.player.get_position()*100 if player.player.player != None:
self.window.time_slider.SetValue(progress) progress = player.player.player.get_position()*100
self.window.time_slider.SetValue(progress)
def on_close(self, event): def on_close(self, event):
log.debug("Exiting...") log.debug("Exiting...")

View File

@ -1,12 +1,12 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import os import os
import random import random
import vlc
import logging import logging
import config import config
import time import time
from sound_lib import output, stream
from pubsub import pub from pubsub import pub
from utils import call_threaded from utils import call_threaded, RepeatingTimer
player = None player = None
log = logging.getLogger("controller.player") log = logging.getLogger("controller.player")
@ -26,35 +26,25 @@ class audioPlayer(object):
self.stopped = True self.stopped = True
self.queue_pos = 0 self.queue_pos = 0
self.shuffle = False self.shuffle = False
self.instance = vlc.Instance() self.worker = RepeatingTimer(5, self.player_function)
log.debug("Instantiating Media player with the following information: VLC version detected={}. VLC bindings for python version{}".format(vlc.libvlc_get_version(), vlc.__version__)) self.worker.start()
self.player = self.instance.media_player_new() self.output = output.Output()
log.debug("Media player instantiated.")
self.event_manager = self.player.event_manager()
self.event_manager.event_attach(vlc.EventType.MediaPlayerEndReached, self.end_callback)
self.event_manager.event_attach(vlc.EventType.MediaPlayerEncounteredError, self.playback_error)
log.debug("Bound media playback events.")
# configure output device
self.set_output_device(config.app["main"]["output_device"]) self.set_output_device(config.app["main"]["output_device"])
self.player = None
def get_output_devices(self): def get_output_devices(self):
""" Retrieve enabled output devices so we can switch or use those later. """ """ Retrieve enabled output devices so we can switch or use those later. """
log.debug("Retrieving output devices...") devices = output.Output.get_device_names()
devices = []
mods = self.player.audio_output_device_enum()
if mods:
mod = mods
while mod:
mod = mod.contents
devices.append(dict(id=mod.device, name=mod.description))
mod = mod.next
vlc.libvlc_audio_output_device_list_release(mods)
return devices return devices
def set_output_device(self, device_id): def set_output_device(self, device_name):
""" Set Output device to be used in LibVLC""" """ Set Output device to be used in LibVLC"""
log.debug("Setting output audio device to {device}...".format(device=device_id,)) log.debug("Setting output audio device to {device}...".format(device=device_name,))
self.player.audio_output_device_set(None, device_id) try:
self.output.set_device(self.output.find_device_by_name(device_name))
except:
log.error("Error in input or output devices, using defaults...")
config.app["main"]["output_device"] = "Default"
def play(self, item): def play(self, item):
self.stopped = True self.stopped = True
@ -63,8 +53,7 @@ class audioPlayer(object):
if item.download_url == "": if item.download_url == "":
item.get_download_url() item.get_download_url()
log.debug("playing {0}...".format(item.download_url,)) log.debug("playing {0}...".format(item.download_url,))
self.stream_new = self.instance.media_new(item.download_url) self.player = stream.URLStream(item.download_url)
self.player.set_media(self.stream_new)
if self.player.play() == -1: if self.player.play() == -1:
log.debug("Error when playing the file {0}".format(item.title,)) log.debug("Error when playing the file {0}".format(item.title,))
pub.sendMessage("change_status", status=_("Error playing {0}. {1}.").format(item.title, e.description)) pub.sendMessage("change_status", status=_("Error playing {0}. {1}.").format(item.title, e.description))
@ -72,7 +61,7 @@ class audioPlayer(object):
self.is_working = False self.is_working = False
self.next() self.next()
return return
self.player.audio_set_volume(self.vol) self.player.volume = self.vol/100
pub.sendMessage("change_status", status=_("Playing {0}.").format(item.title)) pub.sendMessage("change_status", status=_("Playing {0}.").format(item.title))
self.stopped = False self.stopped = False
self.is_working = False self.is_working = False
@ -119,7 +108,8 @@ class audioPlayer(object):
if vol <= 100 and vol >= 0: if vol <= 100 and vol >= 0:
config.app["main"]["volume"] = vol config.app["main"]["volume"] = vol
self.vol = vol self.vol = vol
self.player.audio_set_volume(self.vol) if self.player != None:
self.player.volume = self.vol/100
def play_all(self, list_of_items, playing=0, shuffle=False): def play_all(self, list_of_items, playing=0, shuffle=False):
if list_of_items != self.queue: if list_of_items != self.queue:
@ -128,42 +118,19 @@ class audioPlayer(object):
self.queue_pos = playing self.queue_pos = playing
self.play(self.queue[self.queue_pos]) self.play(self.queue[self.queue_pos])
def end_callback(self, event, *args, **kwargs): def player_function(self):
#https://github.com/ZeBobo5/Vlc.DotNet/issues/4 """ Check if the stream has reached the end of the file so it will play the next song. """
call_threaded(self.next) if self.player != None and self.player.is_playing == False and self.stopped == False and len(self.player) == self.player.position:
if self.queue_pos >= len(self.queue):
def transcode_audio(self, item, path, _format="mp3", bitrate=320, metadata=dict()): self.stopped = True
""" Converts given item to mp3. This method will be available when needed automatically.""" self.playing_all = False
if item.download_url == "": return
item.get_download_url() elif self.playing_all == False:
log.debug("Download started: filename={0}, url={1}".format(path, item.download_url)) self.stopped = True
temporary_filename = "chunk_{0}".format(random.randint(0,2000000)) return
temporary_path = os.path.join(os.path.dirname(path), temporary_filename) elif self.queue_pos < len(self.queue):
# Let's get a new VLC instance for transcoding this file. self.queue_pos += 1
transcoding_instance = vlc.Instance(*["--sout=#transcode{acodec=%s,ab=%d}:file{mux=raw,dst=\"%s\"}"% (_format, bitrate, temporary_path,)]) self.play(self.queue[self.playing_track])
transcoder = transcoding_instance.media_player_new()
transcoder.set_mrl(item.download_url)
pub.sendMessage("change_status", status=_(u"Downloading {0}.").format(item.title,))
media = transcoder.get_media()
transcoder.play()
while True:
state = media.get_state()
pub.sendMessage("change_status", status=_("Downloading {0} ({1}%).").format(item.title, int(transcoder.get_position()*100)))
pub.sendMessage("update-progress", value=int(transcoder.get_position()*100))
if str(state) == 'State.Ended':
break
elif str(state) == 'state.error':
os.remove(temporary_path)
break
transcoder.release()
os.rename(temporary_path, path)
log.debug("Download finished sucsessfully.")
pub.sendMessage("download_finished", file=os.path.basename(path))
def playback_error(self, event): def playback_error(self, event):
pub.sendMessage("notify", title=_("Error"), message=_("There was an error while trying to access the file you have requested.")) pub.sendMessage("notify", title=_("Error"), message=_("There was an error while trying to access the file you have requested."))
def __del__(self):
self.event_manager.event_detach(vlc.EventType.MediaPlayerEndReached)
if hasattr(self, "event_manager"):
self.event_manager.event_detach(vlc.EventType.MediaPlayerEncounteredError, self.playback_error)