0

我正在用 pafy、vlc、PySimpleGUI 制作一个程序,它需要一个 youtube url 并将其作为 mp3 播放。当我第一次尝试控制台模式时遇到的问题是 mp3 会在一段时间后停止,我用 time.sleep 修复了它(秒),现在在控制台版本中一切正常。当我尝试使用 PySimpleGUI 使其成为 GUI 时出现问题,当我使用 time.sleep(seconds) GUI 冻结直到 mp3 结束时,我搜索并发现 window.read() 可以解决问题并且它确实解决了问题,但我暂停后无法继续播放 mp3(如控制台模式),当我按下播放时它播放,当我按下暂停时它暂停,当我再次按下播放时它从头开始但我希望它从它开始暂停是因为 window.read() 吗?抱歉,如果我不能清楚地解释它。控制台模式:

import pafy
import vlc
player = vlc.Instance()
media_player = player.media_player_new()    
def readurl():
    url=input("URL : ")
    vid=pafy.new(url)
    l=vid.length
    aud=vid.getbestaudio()
    media = player.media_new(aud.url)
    media.get_mrl()
    media_player.set_media(media)
def ans(a):
    if(a.upper()=="S"):
        media_player.pause()
    elif(a.upper()=="P"):
        media_player.play()
    elif(a.upper()=="R"):
        media_player.pause()
        readurl()
        ans("P")
    else:
        exit()
readurl()
while True:
    a=input("Choose from options P to play, S to stop(pause), Q to quit, R to get another video. ")
    ans(a)
    

图形用户界面模式:

import PySimpleGUI as sg
import vlc
import pafy
import time
player = vlc.Instance()
media_player = player.media_player_new()    
sg.theme('DarkBlue')
def btn(name):  
    return sg.Button(name, size=(6, 1), pad=(1, 1))
layout = [[sg.Button(button_text='Get video from youtube url : ', size=(20,1), key='geturl'),sg.Input(default_text='', size=(50, 10), key='-VIDEO_LOCATION-')],
          [btn('play'), btn('pause')]]
window = sg.Window('Youtube Radio Mode', layout, element_justification='center', finalize=True, resizable=True)              
#------------ Media Player Setup ---------#
"""
    """
def ans(a,q):
    if(a.upper()=="S"):
        media_player.pause()
        #window.read(q)
    elif(a.upper()=="P"):# or (a.upper()=="R")):
        media_player.play()
        window.read(q)
    else:
        exit()
#------------ The Event Loop ------------#
#def vi()
while True:
    event, values = window.read(timeout=1000)      
    url=values['-VIDEO_LOCATION-']
    z=''
    if event == sg.WIN_CLOSED:
        break
    if (url!='' or event == 'geturl'):
        vid=pafy.new(url)
        #l=vid.length
        aud=vid.getbestaudio()
        media = player.media_new(aud.url)
        media.get_mrl()
        media_player.set_media(media)
        z='l'
        q=vid.length*1000
    if event == 'play':
        if(z!='l'):
            sg.popup_error('PLEASE GET A URL FIRST')    
            continue
        ans("P",q)
        #window.refresh()
        z=''
    if event == 'pause':
        ans("S",q)
window.close()
4

1 回答 1

0

定义你的 GUI,然后进入你的事件循环,并确保你的 GUI 中会发生什么事件,那么下一步该做什么。

这里,修改后的代码供大家参考,不对代码进行测试。

import PySimpleGUI as sg
import vlc
import pafy
import time

def vlc_player():
    player = vlc.Instance()
    media_player = player.media_player_new()
    return media_player

def Button(button_text):
    return sg.Button(button_text, size=(6, 1), pad=(1, 1))

media_player = vlc_player()

sg.theme('DarkBlue')
sg.set_options(font=("Courier New", 16))

layout = [
    [sg.Button(button_text='Get video from youtube url : ', size=(20,1), key='-GET_URL-'),
     sg.Input(default_text='', size=(50, 10), key='URL')],
    [Button('PLAY'), BUTTON('PAUSE'), Button('QUIT')],
    [sg.Text("", size=(0, 1), key='-STATUS-')],
]

window = sg.Window('Youtube Radio Mode', layout, element_justification='center',
    finalize=True, resizable=True)

status = window['-STATUS-']
mp3_load = False

#------------ The Event Loop ------------#

while True:

    event, values = window.read()

    if event in (sg.WIN_CLOSED, 'QUIT'):
        break

    status.update(value='')

    if event == '-GET_URL-':
        """
        if player.is_playing():
            player.stop()
        """
        url = values['-URL-'].strip()

        try:
            vid     = pafy.new(url)
            aud     = vid.getbestaudio()
            media   = player.media_new(aud.url)
            media.get_mrl()
            media_player.set_media(media)
            mp3_load = True
            continue
        except:
            pass
        status.update('URL load failed !')
        mp3_load = False

    elif event == 'PLAY' and mp3_load:
        media_player.play()

    elif event == 'PAUSE' and mp3_load:
        media_player.pause()

if player.is_playing():
    media_player.stop()
window.close()

如果需要很长时间,您可以使用多线程从 Youtube 加载 mp3,并设置一些标志以确认是否正在下载或下载完成,或者禁用按钮 '-GET_URL-' 或其他按钮。

不要在另一个线程中直接更新 GUI,您可以调用window.write_event_value生成新事件,然后在事件循环中更新 GUI。

参考https://github.com/PySimpleGUI/PySimpleGUI/blob/master/DemoPrograms/Demo_Media_Player_VLC_Based.py

于 2021-07-27T01:56:45.357 回答