Форум сайта python.su
0
Решил написать плеер для yotube, для удобства прослушивания треков.
Столкнулся с такой проблемой, что не могу нормально в поток пустить получение ссылки на стрим и начать ее проигрывать, либо фризить все окно, либо вылетает, вот весь главный код:
import sys import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk, GObject, GLib, Gdk import threading import vlc from time import sleep from time import time import helpers.search import json MRL = "" class ApplicationWindow(Gtk.Window): def __init__(self): Gtk.Window.__init__(self, title="YAudio", resizable=False) header = Gtk.HeaderBar(title="YAudio") header.set_subtitle("Youtube audio streaming player") header.props.show_close_button = True self.set_titlebar(header) self.set_border_width(10) self.set_default_size(500, 600) self.set_hexpand(False) self.player_paused=False self.is_player_active = False self.connect("destroy",Gtk.main_quit) self.updateFullTime = True def show(self): self.show_all() def setup_objects_and_events(self): self.test = Gtk.Button("test") self.playback_button = Gtk.Button() self.stop_button = Gtk.Button() self.play_image = Gtk.Image.new_from_icon_name( "gtk-media-play", Gtk.IconSize.MENU ) self.pause_image = Gtk.Image.new_from_icon_name( "gtk-media-pause", Gtk.IconSize.MENU ) self.stop_image = Gtk.Image.new_from_icon_name( "gtk-media-stop", Gtk.IconSize.MENU ) self.playback_button.set_image(self.play_image) self.stop_button.set_image(self.stop_image) self.playback_button.connect("clicked", self.toggle_player_playback) self.stop_button.connect("clicked", self.stop_player) # self.test.connect("clicked", self.tester) # start boxes self.vbox = Gtk.VBox() self.add(self.vbox) # header box self.header = Gtk.HBox() self.header_left = Gtk.HBox() self.header_right = Gtk.VBox() self.header.pack_start(self.header_left, False, True, 0) self.header.pack_start(self.header_right, True, True, 0) self.vbox.pack_start(self.header, False, True, 0) # controls box self.controls = Gtk.HBox(spacing=8) self.controls.set_border_width(8) self.header_right.pack_start(self.controls, False, True, 0) # button play self.controls.pack_start(self.playback_button, False, True, 0) # button stop self.controls.pack_start(self.stop_button, False, True, 0) self.controls.pack_start(Gtk.HSeparator(), False, True, 0) # progress self.slider = Gtk.HScale.new_with_range(0, 100, 1) self.slider_update_signal_id = self.slider.connect( "value-changed", self.on_slider_changed) self.slider.set_draw_value(False) self.slider.set_sensitive(True) self.seek_panel = Gtk.VBox() self.controls.pack_start(self.seek_panel, True, True, 0) self.seek_labels = Gtk.HBox() self.seek_panel.pack_start(self.seek_labels, True, True, 10) self.track_title = Gtk.Label('', halign=Gtk.Align.START, valign=Gtk.Align.END) self.track_title.set_use_markup(True) self.track_title.set_markup('<span font="Roboto 10" weight="300">Idle</span>') self.seek_labels.pack_start(self.track_title, True, True, 0) self.track_time = Gtk.Label('05:00', halign=Gtk.Align.END, valign=Gtk.Align.END) self.track_time.set_use_markup(True) self.track_time.set_markup('<span font="Roboto 24" weight="100">0:00:00</span>') self.seek_labels.pack_start(self.track_time, True, True, 0) self.seek_panel.pack_start(self.slider, True, True, 0) # entry search self.vbox.pack_start(Gtk.HSeparator(), False, False, 0) self.search_panel = Gtk.VBox() self.vbox.pack_start(self.search_panel, False, False, 5) self.search_entry_box = Gtk.HBox() self.search_panel.pack_start(self.search_entry_box, True, True, 0) self.search_entry = Gtk.Entry() self.search_entry.set_text("") self.search_entry.set_placeholder_text("Поиск...") self.search_entry_box.pack_start(self.search_entry, True, True, 0) # search result self.vbox.pack_start(Gtk.HSeparator(), False, False, 0) self.search_result_box = Gtk.VBox() self.vbox.pack_start(self.search_result_box, False, False, 0) self.search_result_text = Gtk.VBox() self.search_result_box.pack_start(self.search_result_text, False, False, 0) self.result_label = Gtk.Label('', halign=Gtk.Align.START, valign=Gtk.Align.END) self.result_label.set_use_markup(True) self.search_result_text.pack_start(self.result_label, False, False, 0) raw_html = helpers.search.get_search_results_html('mops') vids = helpers.search.get_videos(raw_html) self.scrolled = Gtk.ScrolledWindow() self.scrolled.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) for _ in vids: attrs = helpers.search.get_video_attrs(_) self.label_p = Gtk.Label(attrs['title']) self.listhbox = Gtk.HBox() self.vbox.pack_start(self.listhbox, False, False, 5) self.button_p = Gtk.Button() self.play_image = Gtk.Image.new_from_icon_name( "gtk-media-play", Gtk.IconSize.MENU ) self.button_p.set_image(self.play_image) self.button_p.connect("clicked", self.get_url_and_start, attrs['id']) self.listhbox.pack_start(self.button_p, False, True, 2) self.listhbox.pack_start(Gtk.HSeparator(), False, False, 2) self.listhbox.pack_start(self.label_p, False, True, 2) self.scrolled.add_with_viewport(self.listhbox) # self.connect("realize",self._realized) # self.scrolled.show() # self.result_label.set_markup('<span font="Roboto 10">'+res+'</span>') def get_url_and_start(self, widget, id): thread = threading.Thread(target=self._realized, args=(id,)) thread.daemon = True thread.start() def stop_player(self, widget, data=None): self.player.stop() self.is_player_active = False self.playback_button.set_image(self.play_image) self.player.set_position(0.0) def on_slider_changed(self, range): length = self.slider.get_value() self.player.set_position(length / 100.0) def toggle_player_playback(self, widget, data=None): if self.is_player_active == False and self.player_paused == False: self.player.play() self.playback_button.set_image(self.pause_image) self.is_player_active = True elif self.is_player_active == True and self.player_paused == True: self.player.play() self.playback_button.set_image(self.pause_image) self.player_paused = False elif self.is_player_active == True and self.player_paused == False: self.player.pause() self.playback_button.set_image(self.play_image) self.player_paused = True else: pass def _realized(self, id): url = helpers.search.get_youtube_streams(id) self.vlcInstance = vlc.Instance("--no-xlib") self.player = self.vlcInstance.media_player_new() # win_id = widget.get_window().get_xid() # self.player.set_xwindow(win_id) self.player.set_mrl(str(url['audio'])) self.player.play() self.playback_button.set_image(self.pause_image) self.is_player_active = True GObject.timeout_add(1000, self.timing) def timing(self): if self.updateFullTime: self._m, self._s = divmod(int(self.player.get_length() / 1000), 60) self._h, self._m = divmod(self._m, 60) self.full_time_human = "%d:%02d:%02d" % (self._h, self._m, self._s) self.updateFullTime = False m, s = divmod(int(self.player.get_time() / 1000), 60) h, m = divmod(m, 60) self.con_time_human = "%d:%02d:%02d" % (h, m, s) # if stream ended if self.full_time_human == self.con_time_human: self.player.stop() self.is_player_active = False self.playback_button.set_image(self.play_image) self.player.set_position(0.0) length = self.player.get_position() self.track_time.set_markup('<span font="Roboto 24" weight="100">'+self.con_time_human+'</span>') # self.slider.set_digits("%d:%02d:%02d" % (h, m, s)) self.slider.handler_block(self.slider_update_signal_id) self.slider.set_value(length * 100.0) self.slider.handler_unblock(self.slider_update_signal_id) return True if __name__ == '__main__': # MRL = url window = ApplicationWindow() window.setup_objects_and_events() window.show() Gtk.main() window.player.stop() # window.vlcInstance.release()
Отредактировано newbe (Июнь 8, 2017 14:36:38)
Офлайн
4
ссылку под id (около 3х секунд) и должен начинать проигрывать, но сам вижу что данных подход не правильныйЭммм…
import __hello__
Отредактировано delvin-fil (Июнь 9, 2017 03:45:58)
Офлайн
0
delvin-filда, по id получает ссылку вида:
Эммм…
Речь о питоне и засим закономерный вопрос: Вы youtube-dl -F(ибо прога как раз на питоне) на сей плейлист делали?
Предположение, не более - может там не mp3, не ac3, может там что-то совершенно иное. Проверьте на другом плейлисте.
Посмотрите, там наверняка есть “audio-only”
https://r8—sn-bpb5oxu-3c2s.googlevideo.com/videoplayback?keepalive=yes&itag=251&requiressl=yes&ei=3H04WfzrF8WuYK_5iNAC&mn=sn-bpb5oxu-3c2s&gir=yes&mm=31&dur=2930.881&id=o-AFgdCjwDraufG3D9c6fsuf6Rkjf82Frb7asFkxAJfQuQ&source=youtube&ip=31.170.131.52&clen=45959913&mv=m&mt=1496874344&ms=au&expire=1496896060&signature=A7ECF9A90A7BAFE95B1F3A9A5644B2063B3D9914.6A7933DF5201DFE460D6625F75D573783ADB3776&lmt=1494123310691320&mime=audio%2Fwebm&sparams=clen%2Cdur%2Cei%2Cgir%2Cid%2Cinitcwndbps%2Cip%2Cipbits%2Citag%2Ckeepalive%2Clmt%2Cmime%2Cmm%2Cmn%2Cms%2Cmv%2Cpl%2Crequiressl%2Csource%2Cexpire&key=yt6&pl=24&ipbits=0&initcwndbps=4175000&ratebypass=yesВопрос именно в том, как это на отдельный поток грамотно бросить, что бы не фризить gui
Офлайн
4
newbeГУЙ обязателен?
что бы не фризить gui
import __hello__
Офлайн