Python直播新聞台程式製作

很多初學Python的同學因為都在文字介面中處理資料,可能會以為Python這個程式語言是沒有視窗介面可以使用的,其實這是一個錯誤的觀念,因為Python模組什麼都有,什麼都不奇怪。Python有許多好用的視窗介面模組可以使用,但是基於跨平台的特色,因此在介面的設計及規劃上並不像是C#那麼方便,不過在一般的應用上也算是夠用了。大家最常用的應該是PyQt5,不過,在這裡我們使用的是比較精簡的Tkinter。

本篇程式的主要出處是技術型高級中等學校商管群「程式語言與設計(下)」中第8章的範例,書中的程式有一些小小的錯誤,在此篇文章中會加以修正。如果是使用該教科書的老師,還請參考本篇文章的程式內容。先來看看我們的程式介面:

在本程式例子中,我們建立了一個從Youtube上找到的直播新聞影片連結,隨著時間的流逝,這些連結有可能會有所變動,所以同學們在執行程式之前,請先再一次確認連結的正確性,必要時要做一些修正。在上述的介面中,使用者可以按下「播放」按鈕直接播放第一部影片,也可以利用上一台及下一台按鈕在不同電視台之間進行切換,播放時的畫面如下所示:

為了執行以上的功能,在你的環境中需要先安裝以下的模組(建議在Python虛擬環境中執行):

pip install tk
pip install pafy
pip install youtube-dl==2020.12.2
pip install python-vlc

安裝完畢之後,可以利用以下的程式碼進行影片播放的測試,由於本程式會試著把影片播完,所以建議找一個比較短的影片來測試會比較好:

import pafy, vlc, time

url = "https://www.youtube.com/watch?v=kLq_WR-1EEA"
video = pafy.new(url)
best = video.getbest()
media = vlc.MediaPlayer(best.url)
print("現在播放:", video.title)
media.play()
time.sleep(video.length)
media.stop()

測試完畢之後,就可以完成使用以下的程式碼來建立自己的直播新聞台的應用程式了,詳細的教學說明請參考教科書上的解說(修正之處為第8行加上了player=””,以及執行stop之前都會先檢查player是否仍為空字串,如果是空字串就表示目前並沒有影片的播放執行實例,就不要執行stop()函式,以免造成程式的錯誤):

import tkinter as tk
import vlc, pafy
class MyTV(tk.Frame):
    vid = ["_QbRXRnHMVY", "CKjSm5ZeehE", "wM0g8EoUZ_E"]
    channel = 0
    video = ""
    title = ""
    player = ""
    def __init__(self, window):
        super(MyTV, self).__init__(window)
        self.video = pafy.new("https://www.youtube.com/watch?v={}".format(
            self.vid[self.channel]))
        self.title = tk.StringVar()
        self.title.set("電視台名稱")
        self.grid()
        self.label = tk.Label(self, textvariable=self.title)
        self.label.grid(row=0, column=0, columnspan=4)
        
        self.frame = tk.Frame(self, width=640, height=480, bd=5)
        self.frame.configure(bg="black")
        self.frame.grid(row=1, column=0, columnspan=4, padx=8)
        
        self.play_button = tk.Button(self, text = '播放', command = self.play)
        self.play_button.grid(row=2, column=0, columnspan=1, padx=8)
        
        self.prev_button = tk.Button(self, text = '上一台', command = self.prev)
        self.prev_button.grid(row=2, column=1, columnspan=1, padx=8)
        
        self.next_button = tk.Button(self, text = '下一台', command = self.next)
        self.next_button.grid(row=2, column=2, columnspan=1, padx=8)        
        
        self.stop_button = tk.Button(self, text = '停止', command = self.stop)
        self.stop_button.grid(row=2, column=3, columnspan=1, padx=8)

    def play(self):
        self.title.set(self.video.title)
        best = self.video.getbest()
        instance = vlc.Instance('--no-xlib --quiet')
        self.player = instance.media_player_new()
        self.player.set_hwnd(self.frame.winfo_id())
        self.player.set_mrl(best.url)
        xid = self.frame.winfo_id()
        self.player.set_xwindow(xid)
        self.player.play()

    def stop(self):
        if self.player!="":
            self.player.stop()

    def next(self):
        if self.player!="":
            self.stop()
        self.channel += 1
        if self.channel >= len(self.vid):
            self.channel = 0
        self.video = pafy.new("https://www.youtube.com/watch?v={}".format(self.vid[self.channel]))
        self.play()
    def prev(self):
        if self.player!="":
            self.stop()
        self.channel -= 1
        if self.channel < 0:
            self.channel = len(self.vid) - 1
        self.video = pafy.new("https://www.youtube.com/watch?v={}".format(self.vid[self.channel]))
        self.play()
        

window = tk.Tk()
window.title("我的電視台")
app = MyTV(window)
window.mainloop()

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *