如何在 wxpython 窗口中播放带声音的 youtube 视频?

问题描述 投票:0回答:1

我正在制作一个简单的 youtube 播放器和下载器应用程序,供盲人使用屏幕阅读器访问,但也可供有视力的人使用。 我选择 wxpython 是因为它具有有史以来最好的可访问性。 如何在 wx 窗口中播放 youtube 视频?我是否需要使用

wx.media.MediaCtrl
以及如何正确使用它? 我可以在不直接在 wxpython 窗口中下载的情况下播放 youtube 视频吗?

我尝试使用

wx.media.MediaCtrl
,但我从youtube下载了视频,然后让它显示了视频。 更新: 媒体控制不播放任何内容。我使用了我自己的 pafy 修改版本,它使用 yt_dlp 库,它完美地给了我一个有效的视频流 url,但是当我将它插入 wx 媒体时,它不播放。

import wx
import wx.media
import pafy
from webbrowser import open as wopen
from youtubesearchpython import VideosSearch
from accessible_output2.outputs import auto


class YoutubePlayer(wx.Frame):
    
    def __init__(self):
        wx.Frame.__init__(self, None, title="Youtube Player", size=(640, 480))
        self.panel = wx.Panel(self)
        self.edit_box = wx.TextCtrl(self.panel, style=wx.TE_PROCESS_ENTER, pos=(10, 10), size=(200, 20))
        self.list_box = wx.ListBox(self.panel, pos=(10, 40), size=(200, 400))
        self.media_player = wx.media.MediaCtrl(self.panel)
        self.media_player.Bind(wx.media.EVT_MEDIA_LOADED, self.on_media_loaded)
        self.edit_box.Bind(wx.EVT_TEXT_ENTER, self.on_search)
        self.output = auto.Auto()
        self.results={}

    def on_search(self, event):
        query = self.edit_box.GetValue()
        self.output.output("Searching for " + query)
        search = VideosSearch(query, limit=10)
        items = search.result()["result"]
        video_ids = [item["id"] for item in items]
        video_titles = [item["title"] for item in items]
        self.list_box.SetItems(video_titles)
        self.media_player.Stop()
        self.results={k: v for k, v in zip(video_titles, video_ids)}

    def on_media_loaded(self, event):
        print("loaded")
        self.output.output("Playing")
        self.media_player.Play()

    def play_video(self, video_id):
        url = f"https://www.youtube.com/watch?v={video_id}"
        video = pafy.new(url)
        best = video.getbest()
        play_url = best.url
        # wopen(play_url)
        self.media_player.LoadURI(play_url)

    def on_list_select(self, event):
        self.output.output("loading")
        video_id = self.results[event.GetString()]
        self.play_video(video_id)

    def on_list_double_click(self, event):
        self.on_list_select(event)

    def bind_list_events(self):
        #self.list_box.Bind(wx.EVT_LISTBOX, self.on_list_select)
        self.list_box.Bind(wx.EVT_LISTBOX_DCLICK, self.on_list_double_click)

        
if __name__ == "__main__":
    app = wx.App()
    player = YoutubePlayer()
    player.bind_list_events()
    player.Show()
    app.MainLoop()
python youtube accessibility wxpython
1个回答
0
投票

wx.media
将直接从 URL 播放,虽然我不知道它是否可以直接访问 YouTube url(我不是粉丝)。

这是一个非常简单的播放器,它访问一个 url 而不是一个文件。

我建议您测试媒体链接,看看它是一个 url 还是一个文件,然后根据结果使用

LoadURI
Load

import wx
import wx.media

class TestPanel(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, title='Media Player')
        panel = wx.Panel(self, -1, size=(500, 700))
        self.player = wx.media.MediaCtrl(panel, style=wx.SIMPLE_BORDER)
        self.stop = wx.Button(panel, -1, "Stop")
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.player, 1, flag=wx.ALL, border=5)
        sizer.Add(self.stop, 0, wx.ALL, 5)
        panel.SetSizer(sizer)

        self.media = 'http://clips.vorwaerts-gmbh.de/VfE_html5.mp4'
        self.player.Bind(wx.media.EVT_MEDIA_LOADED, self.play)
        self.player.Bind(wx.media.EVT_MEDIA_FINISHED, self.quit)
        self.Bind(wx.media.EVT_MEDIA_STOP, self.quit)
        self.Bind(wx.EVT_BUTTON, self.quit, self.stop)
        self.Bind(wx.EVT_CLOSE, self.quit)
        self.timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer)
        self.timer.Start(250)
        if self.player.LoadURI(self.media):
            pass
        else:
            print("Media not found")
            self.quit(None)
        self.Show()

    def OnTimer(self, event):
        if self.player.GetState() == wx.media.MEDIASTATE_PLAYING:
            print("Progress:",self.player.Tell())

    def play(self, event):
        self.player.Play()

    def quit(self, event):
        self.timer.Stop()
        if self.player.GetState() == wx.media.MEDIASTATE_PLAYING:
            self.player.Stop()
        self.Destroy()

if __name__ == '__main__':
    app = wx.App()
    Frame = TestPanel()
    app.MainLoop()

值得注意的是,您可能必须通过

szBackend
参数选择您的后端播放器。

可用的选项是:

  • MEDIABACKEND_DIRECTSHOW
  • MEDIABACKEND_QUICKTIME
  • 媒体后台END_GSTREAMER
  • MEDIABACKEND_WMP10

如果你想要比

wx.media
更复杂的东西,你将不得不自己动手。

Gstreamer
Vlc
在 Linux 上都运行良好,在其他操作系统上,我不知道。

编辑:

如果您必须直接从 youtube 流式传输,请使用

pafy
之类的东西来隔离 url。

对于上面的代码:

添加

import pafy

而不是指定 url

self.media
replace

self.media = 'http://clips.vorwaerts-gmbh.de/VfE_html5.mp4'

具有以下内容:

#       youtube url via pafy
        url = "https://www.youtube.com/watch?v=iL-jC7XyLeo"
        video = pafy.new(url)
        best = video.getbest()
        playurl = best.url
        self.media = playurl

然后继续如上

© www.soinside.com 2019 - 2024. All rights reserved.