vlc player зависает в графическом интерфейсе (поток Python?)

У меня есть этот фрагмент кода, который работает без проблем:

Media_list = instance.media_list_new(song_list)
list_player = instance.media_list_player_new()
list_player.set_media_list(Media_list)
list_player.play() 

Как бы то ни было, я бы хотел перебирать список и использовать обычный проигрыватель vlc для его воспроизведения.

playing = set([1,2,3,4])
for i in song_list:
player.set_mrl(i)
player.play()
play=True
while play == True:
    time.sleep(1)
    play_state = player.get_state()
    if play_state in playing:
        continue
    else:
        play = False

Это почти то же самое, и это лучше соответствует моим потребностям, однако он замораживает мой графический интерфейс (qml / pyside2). Итак, теперь я соединился, я должен создать для этого новый поток, или есть другой способ сделать это в vlc.

Что ж, я попытался создать новый поток и запустить в нем функцию, указанную выше, однако та же проблема, когда игрок переходит к циклу for и запускает метод воспроизведения, графический интерфейс зависает. (Vlc работает нормально и воспроизводит список воспроизведения, но графический интерфейс не отвечает на время)

Так что, просто чтобы немного расширить, это та часть, которая у меня есть, и она работает нормально, но я не могу получить данные из моих песен во время их воспроизведения, поскольку все, что у меня есть, - это URL-адрес, а не метаданные.

song_list=[]
r = requests.get('https://www.youtube.com/playlist?list=PLD6s0l-FZhjkc-TYwXO5GbwyxFqTd5Y9J')
page = r.text
soup=bs(page,'html.parser')
res=soup.find_all('a',{'class':'pl-video-title-link'})
for l in res:
    #print (l.get("href"))
    #print("https://www.youtube.com"+l.get("href"))
    yt ='https://www.youtube.com'
    temp =l.get("href")
    url =yt+temp
    video = pafy.new(url)
    bestaudio = video.getbestaudio()
    song = bestaudio.url
    #print(video.getbestaudio().url)
    song_list.append(song)

Media_list = instance.media_list_new(song_list)
list_player = instance.media_list_player_new()
list_player.set_media_list(Media_list)
list_player.play() 

я бы хотел:

@Slot()
def print_yt_playlist(self):
song_list=[]
r = requests.get('https://www.youtube.com/playlist?list=PLD6s0l-FZhjkc-TYwXO5GbwyxFqTd5Y9J')
page = r.text
soup=bs(page,'html.parser')
res=soup.find_all('a',{'class':'pl-video-title-link'})
for l in res:
    #print (l.get("href"))
    #print("https://www.youtube.com"+l.get("href"))
    yt ='https://www.youtube.com'
    temp =l.get("href")
    url =yt+temp
    video = pafy.new(url)
    bestaudio = video.getbestaudio()
    song = bestaudio.url
    #print(video.getbestaudio().url)
    song_list.append(video)
 playing = set([1,2,3,4])
 for i in song_list:
     media = instance.media_new(i.getbestaudio().url)
     print(i.Artist) #THIS is what i want, i want to be able to acces that data for the song that is playing
     print(i.Duration) #and this and so on, that is why i want to loop through list, since i dont think i can do it with media_list
     player.set_media(media)
     player.play()
     play=True
 while play == True:
    time.sleep(1)
    play_state = player.get_state()
    if play_state in playing:
        continue
    else:
        play = False

Или, что проще, есть ли способ вставить «видео» в media_list, а затем оттуда я мог бы получить доступ к данным о текущей песне, а также воспроизвести песню?

Я не знаю, что могло бы вам помочь со стороны qml, единственное, что я делаю, это запускаю эту функцию при нажатии кнопки.


person ImRaphael    schedule 31.05.2018    source источник
comment
Почему вы хотите использовать второй метод? Какое у вас преимущество по сравнению с первым?   -  person eyllanesc    schedule 31.05.2018
comment
ну, я использую beautifullsoup и pafy для получения ссылок из плейлистов YouTube, затем я получаю лучший звук, сохраняю его в моем списке мультимедиа и воспроизводю его с помощью media_list_player. Я бы хотел сохранить свой видеофайл, video = pafy.new (url). Так как из этого я могу получить как аудио, так и URL-адрес аудио, эскизы, продолжительность и так далее. Что я не могу из media_list, так как я могу сохранить в нем только фактический URL-адрес песни.   -  person ImRaphael    schedule 01.06.2018
comment
Почему вы говорите, что Media_list может сохранять только URL?   -  person eyllanesc    schedule 01.06.2018
comment
Я расширил свой первоначальный вопрос: мне нужен список моих видеофайлов, которые я мог бы воспроизвести, и в то же время получить доступ к таким данным, как исполнитель, миниатюра, продолжительность и так далее. и я думаю, что не могу сделать это с помощью media_list   -  person ImRaphael    schedule 01.06.2018
comment
Перед каким мероприятием вы хотите это сделать. Почему вы не играете, а через мгновение получаете доступ к данным? Я все еще вас не понимаю, думаю, вы опускаете дополнительную информацию. Какова ваша конечная цель? В соответствии с показываемым кодом вы получаете список URL-адресов: song_list, что вы играете, и в какой момент вы хотите получить доступ к другим данным и как вы это делаете, также если вы указываете связь с графическим интерфейсом, это было бы здорово.   -  person eyllanesc    schedule 01.06.2018
comment
там я обновил код еще раз, если вам нужен qml, я могу вставить его, но я только запускаю функцию, больше ничего. Спасибо за ваше терпение.   -  person ImRaphael    schedule 01.06.2018
comment
Я не использовал Qt (и вы не упоминаете об этом конкретно), но подозреваю, что вы наткнулись на старую проблему Gui Loop. Вы передаете управление vlc без возможности вернуться к основному циклу Gui, пока он не завершится. Предлагаю взглянуть на функцию Timer. rkblog.rk.edu.pl/w/p / qtimer-Making-timers-pyqt4   -  person Rolf of Saxony    schedule 01.06.2018
comment
@ImRaphael Хорошо, мы улучшаемся, я так понимаю, что кнопкой из QML вы вызываете метод print_yt_playlist. Я не понимаю, где вы используете такие атрибуты, как Artist, Duration и т. Д., Я вижу только то, что вы это печатаете. С другой стороны, вы хотите воспроизвести список воспроизведения, и каждый раз, когда вы меняете изменения, QML будет обновлять информацию, такую ​​как исполнитель, продолжительность и т. Д. Я прав?   -  person eyllanesc    schedule 01.06.2018
comment
@eyllanesc Привет, я нашел ответ на данный момент, все, что мне нужно, это чтобы мой графический интерфейс не блокировался, когда я выполняю это, и когда песня начинается, у меня есть доступ к метаданным, я все еще не знаю, что и как я буду использовать метаданные, но блокировка графического интерфейса больше не отображается. Большое спасибо за помощь. - Рольф Саксонский, ты тоже дружище, спасибо! Я посмотрел на таймер, но я все еще выбрал поток, не знаю, что в этом случае лучше.   -  person ImRaphael    schedule 01.06.2018
comment
@ImRaphael Я думаю, что это худший вариант, в нем не было необходимости, если эти метаданные будут использоваться в QML, у вас могут возникнуть проблемы, поскольку QML не может напрямую взаимодействовать с другим потоком, я думаю, что есть другое лучшее решение, но я не люблю думать о краткосрочной перспективе, согласно тому, что я вижу, вы собираетесь использовать эти метаданные в QML и, возможно, у вас возникнут проблемы. Собираетесь ли вы использовать метаданные в графическом интерфейсе?   -  person eyllanesc    schedule 01.06.2018
comment
@eyllanesc, конечно, я буду использовать его в qml, так как я, возможно, собираюсь представить некоторые данные визуально. Скажем так, у меня есть метка в моем qml, на которой я покажу исполнителя, когда начнется песня. код работает атм, а не нить, что бы вы посоветовали?   -  person ImRaphael    schedule 01.06.2018


Ответы (1)


Ну, мне потребовалось немного времени, и у меня есть решение, оно все еще в "грубом" состоянии, но оно работает и не блокирует графический интерфейс, когда я его использую. Я поместил эту логику в новый поток, и я вызываю ее оттуда, нужно сделать много настроек. Я не знаю, является ли это наиболее «элегантным» подходом, поэтому, если у кого-то есть идея получше, не стесняйтесь сказать.

class Threaddy(QThread):

def __init__(self):
    QThread.__init__(self)

def __del__(self):
    self.wait()

def run(self):

    song_list=[]
    r = requests.get('https://www.youtube.com/playlist?list=PLD6s0l-FZhjkc-TYwXO5GbwyxFqTd5Y9J')
    page = r.text
    soup=bs(page,'html.parser')
    res=soup.find_all('a',{'class':'pl-video-title-link'})
    for l in res:
        #print (l.get("href"))
        #print("https://www.youtube.com"+l.get("href"))
        yt ='https://www.youtube.com'
        temp =l.get("href")
        url =yt+temp
        video = pafy.new(url)
        bestaudio = video.getbestaudio()
        song = bestaudio.url
        #print(video.getbestaudio().url)
        song_list.append(video)

    for song in song_list:

        media=instance.media_new(song.getbestaudio().url) #THIS WORKS NOW

        media.get_mrl()
        player.set_media(media)
        player.play()
        print(song.title) #SO DOES THIS
        playing = set([1,2,3,4])
        time.sleep(1)
        duration = player.get_length() / 1000
        mm, ss = divmod(duration, 60)

        while True:
            state = player.get_state()
            if state not in playing:
                break
            continue    
person ImRaphael    schedule 01.06.2018
comment
где вы используете такие атрибуты, как Artist, Duration и т. д.? - person eyllanesc; 01.06.2018
comment
@eyllanesc Что бы вы посоветовали мне сделать, чтобы избежать создания нового потока, а также избежать цикла графического интерфейса пользователя? поскольку я действительно хочу иметь доступ к данным Artist, Duration в QML. Я хотел бы показать данные об исполнителе в виде ярлыка qml (наиболее тривиально). и вы сказали, что qml не может работать с большим количеством потоков. Ty - person ImRaphael; 02.06.2018