Contents

Jak zbudować odtwarzacz multimediów wideo w Pythonie

Tworzenie odtwarzacza wideo może pomóc cieszyć się ulubionymi filmami w dostosowanym motywie i stylu. Możesz sprawić, że odtwarzanie wideo będzie płynniejsze, zaprojektować przyciski i menu aplikacji oraz dodać dowolną funkcjonalność.

Niniejsze przedsięwzięcie zapewni praktyczną znajomość tworzenia wieloplatformowych aplikacji desktopowych, a także biegłość w przetwarzaniu treści multimedialnych i zarządzaniu interakcjami użytkownika poprzez obsługę zdarzeń. Wykorzystując Tkinter, VLC i moduł datetime, projekt ten oferuje możliwość stworzenia funkcjonalnego odtwarzacza multimediów wideo.

Moduł Tkinter, VLC i Datetime

Tkinter to zintegrowane środowisko programistyczne (IDE) do tworzenia graficznych interfejsów użytkownika (GUI) w Pythonie. Dzięki szerokiej gamie wbudowanych widżetów, takich jak przyciski, etykiety i pola tekstowe, programiści mogą łatwo tworzyć złożone aplikacje, w tym między innymi podstawowy interfejs kalendarza, kalkulator, a nawet system zarządzania zadaniami. Aby skonfigurować Tkinter na swoim komputerze, wystarczy uruchomić wiersz poleceń i wprowadzić polecenie instalacji.

 pip install tkinter 

Moduł python-vlc jest interfejsem ułatwiającym komunikację między aplikacjami Pythona a biblioteką odtwarzacza multimedialnego VLC. Pozwala to programistom na wykorzystanie pełnego potencjału bogatego zestawu funkcji VLC w swoich projektach poprzez zintegrowanie go z ich bazą kodu. Aby uzyskać pakiet python-vlc , wykonaj następujące polecenie:

 pip install python-vlc 

Moduł datetime w Pythonie oferuje szereg klas i funkcji, które umożliwiają użytkownikom pracę z różnymi formatami daty i czasu, a także wykonywanie operacji obejmujących strefy czasowe. Funkcja ta pozwala na wydajne manipulowanie i obliczanie danych czasowych w programach Pythona.

Budowanie struktury odtwarzacza multimediów wideo

Kod źródłowy tego projektu jest dostępny w repozytorium GitHub, do którego można uzyskać dostęp, przechodząc pod odpowiedni adres URL.

Rzeczywiście, aby zrealizować naszą wizję intuicyjnego i atrakcyjnego wizualnie odtwarzacza multimedialnego, musimy najpierw zaimportować niezbędne moduły, które umożliwią nam stworzenie takiego doświadczenia. W szczególności zdefiniujemy nową klasę o nazwie MediaPlayerApp , która posłuży jako podstawa interfejsu użytkownika naszej aplikacji. Po jej zdefiniowaniu wywołamy jej metodę konstruktora, aby skonfigurować początkowy stan głównego okna aplikacji, w tym ustawić tytuł, zdefiniować wymiary i określić kolor tła odtwarzacza multimediów wideo. Na koniec wywołamy metodę initialize_player , aby upewnić się, że wszystkie komponenty zostały poprawnie zainicjowane przed jakąkolwiek interakcją.

 import tkinter as tk
import vlc
from tkinter import filedialog
from datetime import timedelta

class MediaPlayerApp(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("Media Player")
        self.geometry("800x600")
        self.configure(bg="#f0f0f0")
        self.initialize_player()

Funkcja initializer\_player() jest odpowiedzialna za konfigurację odtwarzacza multimedialnego poprzez utworzenie instancji biblioteki odtwarzacza multimedialnego VLC, która zapewnia różne funkcje zarządzania odtwarzaniem audio i wideo. Funkcja ta tworzy również nowy obiekt QMediaPlayer, który służy jako element interfejsu użytkownika do sterowania odtwarzaniem multimediów. Aby zachować zapis aktualnie odtwarzanego pliku wideo, wprowadzana jest zmienna o nazwie current\_file. Zmienna ta będzie używana w kolejnych krokach, aby zapewnić płynne przechodzenie między różnymi filmami podczas rozgrywki. Dodatkowo, funkcja ustawia początkowo stan odtwarzania na “zatrzymany”, umożliwiając użytkownikom rozpoczęcie gry od zera w razie potrzeby. Na koniec wywoływana jest metoda create\_widgets() w celu skonfigurowania elementów graficznego interfejsu użytkownika, które odpowiadają każdemu przyciskowi na pilocie zdalnego sterowania.

     def initialize_player(self):
        self.instance = vlc.Instance()
        self.media_player = self.instance.media_player_new()
        self.current_file = None
        self.playing_video = False
        self.video_paused = False
        self.create_widgets() 

generuje widżet canvas, pobierając określony element nadrzędny i ustawiając jego właściwości, takie jak pozycjonowanie na ekranie za pomocą place , określając jego wymiary, takie jak szerokość i wysokość, wraz z zastosowaniem unikalnego identyfikatora do celów referencyjnych. Dodatkowo, skonstruuj przycisk wyboru pliku poprzez instancję, ustaw jego atrybuty, w tym element nadrzędny, etykietę tekstową, którą wyświetli, parametry stylizacji wyglądu i wyznaczoną akcję, która zostanie wykonana po interakcji użytkownika, czyli kliknięciu przycisku.

Upewnij się, że generowana jest odpowiednia etykieta do wyświetlania zarówno bieżącego czasu, jak i całkowitego czasu trwania wideo, jednocześnie ustawiając element nadrzędny, dostosowując styl tekstu, definiując kolory czcionek i określając odcień tła. Dodatkowo należy utworzyć obramowany obszar z określonym odcieniem tła, aby regulować postęp odtwarzania wideo.

     def create_widgets(self):
        self.media_canvas = tk.Canvas(self, bg="black", width=800, height=400)
        self.media_canvas.pack(pady=10, fill=tk.BOTH, expand=True)
        self.select_file_button = tk.Button(
            self,
            text="Select File",
            font=("Arial", 12, "bold"),
            command=self.select_file,
        )
        self.select_file_button.pack(pady=5)
        self.time_label = tk.Label(
            self,
            text="00:00:00 / 00:00:00",
            font=("Arial", 12, "bold"),
            fg="#555555",
            bg="#f0f0f0",
        )
        self.time_label.pack(pady=5)
        self.control_buttons_frame = tk.Frame(self, bg="#f0f0f0")
        self.control_buttons_frame.pack(pady=5) 

Włączenie funkcji definiowania przycisków odtwarzania, pauzy, zatrzymania, szybkiego przewijania do przodu i do tyłu wraz z utworzeniem widżetu paska postępu wideo w aplikacji odtwarzacza wideo HTML5 canvas. Dodatkowo należy określić pożądany kontener nadrzędny do umieszczenia tych elementów, a także wyznaczoną metodę aktualizacji pozycji odtwarzania wideo, preferowany kolor tła dla paska postępu i jego odpowiednią grubość.

Upewnij się, że wszystkie te elementy są rozmieszczone harmonijnie, z odpowiednimi odstępami po obu stronach.

         self.play_button = tk.Button(
            self.control_buttons_frame,
            text="Play",
            font=("Arial", 12, "bold"),
            bg="#4CAF50",
            fg="white",
            command=self.play_video,
        )
        self.play_button.pack(side=tk.LEFT, padx=5, pady=5)
        self.pause_button = tk.Button(
            self.control_buttons_frame,
            text="Pause",
            font=("Arial", 12, "bold"),
            bg="#FF9800",
            fg="white",
            command=self.pause_video,
        )
        self.pause_button.pack(side=tk.LEFT, padx=10, pady=5)
        self.stop_button = tk.Button(
            self.control_buttons_frame,
            text="Stop",
            font=("Arial", 12, "bold"),
            bg="#F44336",
            fg="white",
            command=self.stop,
        )
        self.stop_button.pack(side=tk.LEFT, pady=5)
        self.fast_forward_button = tk.Button(
            self.control_buttons_frame,
            text="Fast Forward",
            font=("Arial", 12, "bold"),
            bg="#2196F3",
            fg="white",
            command=self.fast_forward,
        )
        self.fast_forward_button.pack(side=tk.LEFT, padx=10, pady=5)
        self.rewind_button = tk.Button(
            self.control_buttons_frame,
            text="Rewind",
            font=("Arial", 12, "bold"),
            bg="#2196F3",
            fg="white",
            command=self.rewind,
        )
        self.rewind_button.pack(side=tk.LEFT, pady=5)
        self.progress_bar = VideoProgressBar(
            self, self.set_video_position, bg="#e0e0e0", highlightthickness=0
        )
        self.progress_bar.pack(fill=tk.X, padx=10, pady=5) 

Tworzenie funkcjonalności odtwarzacza multimediów wideo

Włącz dostarczony fragment kodu poniżej, aby zdefiniować metodę select_file , która otwiera okno dialogowe pliku, aby umożliwić użytkownikom wybór pliku wideo MP4 lub AVI. Metoda będzie następnie wykorzystywać czas trwania wybranego pliku do aktualizacji wyświetlania osi czasu i rozpoczęcia odtwarzania wybranego nośnika.

     def select_file(self):
        file_path = filedialog.askopenfilename(
            filetypes=[("Media Files", "*.mp4 *.avi")]
        )
        if file_path:
            self.current_file = file_path
            self.time_label.config(text="00:00:00 / " \\+ self.get_duration_str())
            self.play_video() 

Aby określić całkowity czas trwania wideo, proponuję zaimplementowanie nowej funkcji o nazwie get_duration_str , która oblicza tę wartość na podstawie tego, czy aplikacja aktualnie odtwarza wideo. Jeśli aplikacja rzeczywiście odtwarza wideo, możemy pobrać jego czas trwania w milisekundach, a następnie przekonwertować go na standardowy format czasu składający się z godzin, minut i sekund (HH:MM:SS). Z drugiej strony, jeśli nie jest odtwarzane żadne wideo, powinniśmy ustawić domyślną wartość dla get_duration_str na 00:00:00 .

     def get_duration_str(self):
        if self.playing_video:
            total_duration = self.media_player.get_length()
            total_duration_str = str(timedelta(milliseconds=total_duration))[:-3]
            return total_duration_str
        return "00:00:00" 

Zdefiniuj metodę o nazwie “play\_video”, która sprawdza, czy wideo jest aktualnie odtwarzane na kanwie. Jeśli żaden film nie jest aktualnie odtwarzany, utwórz nowy obiekt multimedialny, określając ścieżkę do jego pliku w zmiennej “selected\_file\_path”. Następnie skojarz ten obiekt multimedialny z wcześniej utworzoną instancją kanwy i rozpocznij odtwarzanie wideo. Na koniec zaktualizuj wartość stanu “playing\_video”, aby wskazać, że rozpoczęło się odtwarzanie wideo.

     def play_video(self):
        if not self.playing_video:
            media = self.instance.media_new(self.current_file)
            self.media_player.set_media(media)
            self.media_player.set_hwnd(self.media_canvas.winfo_id())
            self.media_player.play()
            self.playing_video = True 

Aby zaimplementować funkcję szybkiego przewijania do przodu dla odtwarzacza wideo w Pythonie, możemy utworzyć dwie metody - fast_forward i rewind . Pierwsza z nich zwiększy bieżący czas odtwarzania, dodając do niego 10 000 milisekund, podczas gdy druga zmniejszy czas odtwarzania, odejmując od niego równoważną ilość.

     def fast_forward(self):
        if self.playing_video:
            current_time = self.media_player.get_time() \\+ 10000
            self.media_player.set_time(current_time)

    def rewind(self):
        if self.playing_video:
            current_time = self.media_player.get_time() - 10000
            self.media_player.set_time(current_time) 

Włącz funkcję wstrzymywania i odtwarzania filmów w interfejsie aplikacji, implementując metodę o nazwie “pause\_video”. Metoda ta będzie odpowiedzialna za obsługę interakcji użytkownika związanych z odtwarzaniem wideo. Pierwszym krokiem jest określenie, czy wideo zostało wcześniej wstrzymane. Jeśli wideo było już w toku i zostało tymczasowo zatrzymane, należy wywołać metodę “play”, aby kontynuować od miejsca, w którym zostało przerwane. I odwrotnie, jeśli wideo nigdy wcześniej nie zostało zainicjowane lub zatrzymane, należy wywołać metodę “pause” z odpowiednimi aktualizacjami interfejsu użytkownika odzwierciedlającymi to działanie.

     def pause_video(self):
        if self.playing_video:
            if self.video_paused:
                self.media_player.play()
                self.video_paused = False
                self.pause_button.config(text="Pause")
            else:
                self.media_player.pause()
                self.video_paused = True
                self.pause_button.config(text="Resume") 

Aby skutecznie przekazać podany tekst w bardziej wyrafinowany sposób, sugerowałbym przeformułowanie go w następujący sposób:> “Aby efektywnie zarządzać odtwarzaniem wideo, zaimplementuj dwie metody w swoim kodzie. Pierwsza, “stop”, zatrzyma trwające odtwarzanie wideo i zresetuje powiązany z nim znacznik czasu. Druga, “set\_video\_position”, określi, czy wideo jest aktualnie odtwarzane. W takim przypadku oblicza żądaną pozycję w milisekundach na podstawie całkowitego czasu trwania wideo i odpowiednio ustawia czas odtwarzania.

     def stop(self):
        if self.playing_video:
            self.media_player.stop()
            self.playing_video = False
        self.time_label.config(text="00:00:00 / " \\+ self.get_duration_str())

    def set_video_position(self, value):
        if self.playing_video:
            total_duration = self.media_player.get_length()
            position = int((float(value) / 100) * total_duration)
            self.media_player.set_time(position) 

Aby skutecznie przekazać pożądane informacje przy jednoczesnym zachowaniu profesjonalnego tonu, sugerowałbym przeformułowanie podanego tekstu w następujący sposób: javascriptfunction updateVideoProgress() {// Sprawdź, czy wideo jest aktualnie odtwarzaneif (isPlaying) {// Pobierz całkowity czas trwania wideo w sekundachconst totalDuration = getTotalDuration();// Oblicz procent postępu na podstawie pobranych wartościlet progressPercentage = ((getCurrentTime() / totalDuration) * 100). toFixed(2);// Zaktualizuj pasek postępu o obliczoną wartośćupdateProgressBar(progressPercentage \+ “%”);// Sformatuj bieżący czas i całkowity czas trwania do celów wyświetlaniaconst formattedCurrentTime =

Aby wielokrotnie wykonywać tę metodę co 1000 milisekund, tworząc w ten sposób nieskończoną pętlę, która kontynuuje aktualizację postępu wideo i etykiet czasu podczas odtwarzania, zaplanuj tę operację w następujący sposób:

     def update_video_progress(self):
        if self.playing_video:
            total_duration = self.media_player.get_length()
            current_time = self.media_player.get_time()
            progress_percentage = (current_time / total_duration) * 100
            self.progress_bar.set(progress_percentage)
            current_time_str = str(timedelta(milliseconds=current_time))[:-3]
            total_duration_str = str(timedelta(milliseconds=total_duration))[:-3]
            self.time_label.config(text=f"{current_time_str}/{total_duration_str}")
        self.after(1000, self.update_video_progress) 

Jasne! Oto moja próba sparafrazowania instrukcji w bardziej formalnym języku:pythonclass VideoProgressBar(tk.Scale):def init (self, master=None, **kwargs):super(). init (master, **kwargs)# ustaw początkowy stan i zachowanie pasków postępuself[‘orient’] = ‘horizontal’self[’tickinterval’] = - 1self[‘command’] = Noneself[‘showgrid’] = Falseself[‘showlabel’] = Trueself[‘sliderrelief’] = ‘groove’self[‘start’] = 0self[’end’] = 100# ustaw opcję showvalue na False, aby uniknąć wyświetlania wartości

Rozpocznij inicjalizację paska postępu, określając zakres od 0 do 100, ustawić jego orientację, określić jego długość i zastosować dostosowania do paska postępu. Dodatkowo należy powiązać detektor zdarzeń z paskiem postępu, aby po interakcji użytkownika wywoływał określoną metodę on_click do obsługi dalszego przetwarzania.

 class VideoProgressBar(tk.Scale):
    def __init__(self, master, command, **kwargs):
        kwargs["showvalue"] = False
        super().__init__(
            master,
            from_=0,
            to=100,
            orient=tk.HORIZONTAL,
            length=800,
            command=command,
            **kwargs,
        )
        self.bind("<Button-1>", self.on_click) 

Włącz funkcjonalność obsługi zdarzenia “on\_click”, implementując ją w bazie kodu. Celem jest określenie, czy pasek postępu został włączony dla interakcji, a następnie obliczenie zaktualizowanej wartości paska postępu na podstawie pozycji, w której użytkownik kliknął. Na koniec należy zaktualizować wyświetlaną wartość paska postępu o tę nowo obliczoną wartość.

     def on_click(self, event):
        if self.cget("state") == tk.NORMAL:
            value = (event.x / self.winfo_width()) * 100
            self.set(value) 

Utwórz nową instancję klasy MediaPlayerApp i wywołaj jej metodę update_video_progress() w kontekście interfejsu graficznego Tkinter. Dodatkowo upewnij się, że funkcja mainloop() jest wywoływana tak, aby zainicjować pętlę zdarzeń i pozostać aktywną do momentu zamknięcia okna przez użytkownika.

 if __name__ == "__main__":
    app = MediaPlayerApp()
    app.update_video_progress()
    app.mainloop() 

Testowanie różnych funkcji odtwarzacza multimediów wideo

Po uruchomieniu aplikacji pojawia się interfejs multimediów wideo z wbudowaną opcją “Wybierz plik”, której towarzyszy szereg przyjaznych dla użytkownika elementów sterujących, takich jak wskaźniki czasu, narzędzia do zarządzania odtwarzaniem i wizualna reprezentacja postępu wideo, a wszystko to zamknięte w atrakcyjnej wizualnie strukturze.

/pl/images/start-screen-of-video-media-player.jpg

Po wybraniu filmu wideo rozpoczyna odtwarzanie od samego początku, jednocześnie dostosowując zarówno początkowy znacznik czasu, jak i etykietę czasu trwania, aby odzwierciedlić upływający czas.

/pl/images/video-playing-on-video-media-player.jpg

Po naciśnięciu przycisku “Pauza” odtwarzanie multimediów wizualnych zostaje zawieszone i następuje przejście do opcji “Wznów”. Po wybraniu funkcji “Przewijanie do przodu” prezentacja audiowizualna zostanie przyspieszona o dziesięć sekund.

W podobny sposób, po naciśnięciu przycisku “Przewijanie do tyłu”, wideo zostanie przewinięte do tyłu o dziesięć sekund. Przycisk “Stop” całkowicie kończy odtwarzanie wideo. Użytkownicy mają możliwość manipulowania paskiem postępu w celu nawigacji do określonych punktów w filmie. Gdy pasek postępu przesuwa się wzdłuż swojej długości, wyświetlany czas odzwierciedla czas, który upłynął od początku filmu.

/pl/images/pause-buttons-turns-to-resume-button-if-video-is-paused.jpg

Ulepszanie aplikacji odtwarzacza multimediów wideo

Aby poprawić funkcjonalność tego odtwarzacza multimediów wideo, możesz dołączyć funkcję, która umożliwia użytkownikom dostęp do opcji napisów i ich wyświetlanie. Ponadto inne potencjalne ulepszenia mogą obejmować dostosowanie wymiarów ekranu, regulację poziomów dźwięku i powtarzanie określonych segmentów wideo.

Aby włączyć te możliwości, można zagłębić się w świat biblioteki Pygame. Pygame to wysoce adaptowalne, przyjazne dla użytkownika narzędzie, które płynnie łączy się z Tkinterem. Ten przydatny pakiet oferuje możliwość spersonalizowanej konfiguracji, prezentuje szereg interaktywnych elementów i działa bezbłędnie na wszystkich platformach.