首页 > 解决方案 > vlc player freezes GUI (python thread?)

问题描述

I have this piece of code that works with no issues :

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() 

how ever i would like to itterate through a list, and use normal vlc player to play it.

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

This does almost the same thing, and it suits my needs better, however it freezes my GUi,(qml/pyside2). So now i am cofused, am i supposed to make a new thread for this, or is there some other way to do this in vlc.

Well i did try creating new thread and running the function above in it, however same issue, the moment player goes in to for loop and start play method, the gui freezes.(the vlc works normaly, and plays the playlist, but gui is unresponsive for duration)

so just to expand a bit , this is the part that i have, and it works ok, but i cant get data from my songs during their play time, since all i have is url, and not the metadata .

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() 

what i would want is:

@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

Or more simple, is there a way that i paste "video" in to the media_list and then from there i could access data about current song, as well playing the song ?

I dont know what could help you from qml side, the only thing i do is trigger this function on button click.

标签: pythonpython-3.xlibvlcpyside2

解决方案


好吧,我花了一点时间,我有一个解决方案,它仍然处于“粗糙”状态,但它可以工作并且当我使用它时它不会阻止 gui。我把这个逻辑放在一个新线程中,我从那里调用它,需要做很多调整。我不知道这是否是最“优雅”的方法,所以如果其他人有更好的想法,请不要犹豫说。

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    

推荐阅读