Een videomediaspeler maken met Python
Door een videospeler te bouwen kun je genieten van je favoriete video’s in een aangepast thema en stijl. Je kunt het afspelen van video’s vloeiender maken, de knoppen en menu’s van je app ontwerpen en de functionaliteit toevoegen die je maar wilt.
Dit project zal praktische kennis opleveren over de ontwikkeling van cross-platform desktopapplicaties, evenals vaardigheid in het verwerken van multimedia-inhoud en het beheren van gebruikersinteracties door middel van event handling. Door gebruik te maken van Tkinter, VLC en de datetime module, biedt dit project de mogelijkheid om een functionele video mediaspeler te maken.
De Tkinter, VLC en Datetime Module
Tkinter is een geïntegreerde ontwikkelomgeving (IDE) voor het maken van grafische gebruikersinterfaces (GUI’s) in Python. Met zijn uitgebreide reeks ingebouwde widgets zoals knoppen, labels en tekstvakken, kunnen ontwikkelaars gemakkelijk complexe toepassingen bouwen, inclusief maar niet beperkt tot een basis kalenderinterface, een rekenmachine of zelfs een taakbeheersysteem. Om Tkinter op je computer te installeren, start je gewoon een opdrachtprompt en voer je het installatiecommando in.
pip install tkinter
De python-vlc
module is een interface die de communicatie tussen Python toepassingen en de VLC mediaspeler bibliotheek vergemakkelijkt. Hierdoor kunnen ontwikkelaars het volledige potentieel van de uitgebreide functieset van VLC in hun projecten benutten door deze in hun codebase te integreren. Voer het volgende commando uit om het pakket python-vlc
te verkrijgen:
pip install python-vlc
De datetime module in Python biedt een reeks klassen en functies waarmee gebruikers kunnen werken met verschillende datum- en tijdformaten en bewerkingen kunnen uitvoeren met tijdzones. Deze functie maakt efficiënte manipulatie en berekening van temporele gegevens binnen Python-programma’s mogelijk.
De structuur van de videomediaspeler bouwen
De broncode voor dit project is beschikbaar op de GitHub repository, die toegankelijk is door te navigeren naar de betreffende URL.
Om onze visie voor een intuïtieve en visueel boeiende mediaspeler te implementeren, moeten we eerst de noodzakelijke modules importeren die ons in staat stellen om zo’n ervaring te creëren. In het bijzonder zullen we een nieuwe klasse definiëren met de naam MediaPlayerApp
, die zal dienen als basis voor de gebruikersinterface van onze applicatie. Eenmaal gedefinieerd, zullen we de constructormethode aanroepen om de initiële status van het hoofdvenster van de toepassing in te stellen, inclusief het instellen van de titel, het definiëren van de afmetingen en het specificeren van de achtergrondkleur van de videomediaspeler. Tenslotte zullen we de methode initialize_player
aanroepen om ervoor te zorgen dat alle componenten correct zijn geïnitialiseerd voordat er interactie plaatsvindt.
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()
De initialiseer_player() functie is verantwoordelijk voor het instellen van de mediaspeler door het creëren van een instantie van de VLC mediaspeler bibliotheek, die verschillende functionaliteiten biedt voor het beheren van audio en video afspelen. De functie maakt ook een nieuw QMediaPlayer-object aan, dat dient als gebruikersinterface-element voor het bedienen van het afspelen van media. Om bij te houden welk videobestand momenteel wordt afgespeeld, wordt een variabele met de naam current\file geïntroduceerd. Deze variabele wordt in volgende stappen gebruikt om een naadloze overgang tussen verschillende video’s tijdens het spelen te garanderen. Daarnaast zet de functie de afspeelstatus aanvankelijk op ‘gestopt’, zodat gebruikers desgewenst opnieuw kunnen beginnen met spelen. Tot slot wordt de methode create\_widgets() aangeroepen om de grafische gebruikersinterface-elementen in te stellen die overeenkomen met elke knop op de afstandsbediening.
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()
genereert een canvas widget door het gespecificeerde parent element te nemen en de eigenschappen ervan in te stellen, zoals de positionering op het scherm met behulp van plaats
, het bepalen van de afmetingen zoals breedte en hoogte, samen met het toepassen van een unieke identifier voor referentiedoeleinden. Daarnaast maak je een knop voor het selecteren van een bestand door deze te instantiëren en de attributen ervan in te stellen, waaronder het bovenliggende element, het tekstlabel dat wordt weergegeven, stylingparameters voor het uiterlijk en de aangewezen actie die wordt uitgevoerd bij interactie met de gebruiker, namelijk klikken op de knop.
Zorg ervoor dat een geschikt label wordt gegenereerd voor het weergeven van zowel de huidige tijd als de totale duur van de video, terwijl u het bovenliggende element instelt, de tekststijl aanpast, de letterkleuren definieert en de achtergrondkleur bepaalt. Maak bovendien een omrand gebied met een specifieke achtergrondtint om het afspeelverloop van de video te regelen.
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)
Integreer de functionaliteit van het definiëren van de knoppen afspelen, pauzeren, stoppen, snel vooruitspoelen en terugspoelen, samen met het maken van een widget voor een videovoortgangsbalk binnen een HTML5 canvas videospelertoepassing. Geef daarnaast de gewenste bovenliggende container op voor het plaatsen van deze elementen, evenals de aangewezen methode voor het bijwerken van de afspeelpositie van de video, de gewenste achtergrondkleur voor de voortgangsbalk en de bijbehorende dikte.
Zorg ervoor dat al deze onderdelen harmonieus zijn gerangschikt, met voldoende ruimte aan weerszijden.
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)
De functionaliteit van de videomediaspeler bouwen
Integreer het onderstaande codefragment om een methode select_file
te definiëren die een dialoogvenster met bestanden opent zodat gebruikers een MP4- of AVI-videobestand kunnen kiezen. De methode gebruikt dan de duur van het geselecteerde bestand om de tijdlijnweergave bij te werken en het afspelen van de gekozen media te starten.
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()
Om de totale duur van een video te bepalen, stel ik voor om een nieuwe functie genaamd get_duration_str
te implementeren die deze waarde berekent op basis van het feit of een toepassing momenteel een video afspeelt of niet. Als de toepassing inderdaad een video afspeelt, kunnen we de duur in milliseconden ophalen en deze vervolgens omzetten naar de standaard tijdsindeling bestaande uit uren, minuten en seconden (HH:MM:SS). Aan de andere kant, als er geen video wordt afgespeeld, moeten we de standaardwaarde voor get_duration_str
instellen op 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"
Definieer een methode genaamd “play\_video” die controleert of er momenteel een video wordt afgespeeld op het canvas. Als er momenteel geen video wordt afgespeeld, maak dan een nieuw mediaobject aan door het bestandspad op te geven in de variabele “selected_file_path”. Koppel dit mediaobject vervolgens aan de eerder gemaakte canvasinstantie en begin de video af te spelen. Werk ten slotte de waarde van de status “afspelen_video” bij om aan te geven dat het afspelen van de video is begonnen.
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
Om een functie voor snel vooruitspoelen voor een videospeler in Python te implementeren, kunnen we twee methoden maken - fast_forward
en rewind
. De eerste zal de huidige afspeeltijd verhogen door er 10.000 milliseconden aan toe te voegen, terwijl de tweede de afspeeltijd zal verlagen door er een gelijkwaardige hoeveelheid van af te trekken.
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)
Integreer de functionaliteit voor het pauzeren en afspelen van video’s in de interface van je toepassing door een methode genaamd “pause\_video” te implementeren. Deze methode is verantwoordelijk voor het afhandelen van gebruikersinteracties met betrekking tot het afspelen van video. De eerste stap is om te bepalen of de video al eerder gepauzeerd is. Als de video al bezig was en tijdelijk gestopt is, roep dan de “play” methode aan om verder te gaan waar hij gebleven was. Omgekeerd, als de video nooit eerder is gestart of gestopt, moet de “pauze”-methode worden aangeroepen met de juiste updates van de gebruikersinterface om deze actie weer te geven.
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")
Om de gegeven tekst op een meer verfijnde manier over te brengen, stel ik voor deze als volgt te herformuleren:> “Om het afspelen van video’s efficiënt te beheren, implementeer je twee methoden in je code. De eerste, ‘stop’, zal elk lopend videoweergave stoppen en de bijbehorende tijdstempel resetten. De tweede, ‘set\_video\_position’, bepaalt of een video momenteel wordt afgespeeld. In dat geval wordt de gewenste positie in milliseconden berekend op basis van de totale duur van de video en wordt de afspeeltijd overeenkomstig ingesteld.
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)
Om de gewenste informatie effectief over te brengen en toch een professionele toon te behouden, stel ik voor om de gegeven tekst als volgt te herformuleren: javascriptfunction updateVideoProgress() {// Controleer of een video momenteel wordt afgespeeldif (isPlaying) {//Verhaal de totale duur van de video in secondenconst totalDuration = getTotalDuration();//Bereken het voortgangspercentage op basis van de opgehaalde waardenlet progressPercentage = ((getCurrentTime() / totalDuration) * 100). toFixed(2);// Werk de voortgangsbalk bij met de berekende waardeupdateProgressBar(progressPercentage \+ “%”);// Formatteer de huidige tijd en totale duur voor weergavedoeleindenconst formattedCurrentTime =
Om deze methode herhaaldelijk elke 1000 milliseconden uit te voeren en zo een oneindige lus te creëren die de voortgangs- en tijdlabels van de video tijdens het afspelen blijft bijwerken, plant u deze bewerking als volgt:
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)
Zeker! Hier is mijn poging om de instructies in formelere taal te parafraseren:pythonclass VideoProgressBar(tk.Scale):def init (self, master=None, **kwargs):super(). init (master, **kwargs)# stel de initiële status en het gedrag van de voortgangsbalken inelf[‘orient’] = ‘horizontal’self[’tickinterval’] = - 1self[‘command’] = Noneself[‘showgrid’] = Falself[‘showlabel’] = Trueself[‘sliderrelief’] = ‘groove’self[‘start’] = 0self[’end’] = 100# stel de optie showvalue in op False om te voorkomen dat de
voortgangsbalk wordt weergegeven. Start de initialisatie van de voortgangsbalk door een bereik van 0 tot 100 op te geven, stel de oriëntatie in, bepaal de lengte en pas aanpassingen toe op de voortgangsbalk. Bind bovendien een event listener aan de voortgangsbalk zodat deze na interactie met de gebruiker de opgegeven on_click
methode activeert voor verdere verwerking.
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)
De functionaliteit van de “on_click”-gebeurtenishandler opnemen door deze te implementeren in de codebase. Het doel is om te bepalen of de voortgangsbalk is ingeschakeld voor interactie en vervolgens een bijgewerkte waarde voor de voortgangsbalk te berekenen op basis van de positie waarop de gebruiker heeft geklikt. Ten slotte wordt de weergegeven waarde van de voortgangsbalk bijgewerkt met deze nieuw berekende waarde.
def on_click(self, event):
if self.cget("state") == tk.NORMAL:
value = (event.x / self.winfo_width()) * 100
self.set(value)
Maak een nieuwe instantie van de klasse MediaPlayerApp
en voer de methode update_video_progress()
uit binnen de context van een Tkinter GUI. Zorg er bovendien voor dat de functie mainloop()
wordt aangeroepen om de gebeurtenislus te starten en actief te blijven totdat de gebruiker het venster sluit.
if __name__ == "__main__":
app = MediaPlayerApp()
app.update_video_progress()
app.mainloop()
Het testen van verschillende functies van de videomediaspeler
Bij het uitvoeren van de toepassing verschijnt een videomedia-interface met een ingebouwde optie “Bestand selecteren”, vergezeld van een reeks gebruiksvriendelijke besturingselementen zoals tijdsindicatoren, hulpmiddelen voor afspeelbeheer en een visuele weergave van het verloop van de video, allemaal ingekapseld in een visueel aantrekkelijk kader.
Bij het selecteren van een video wordt het afspelen vanaf het begin gestart, waarbij gelijktijdig zowel de starttijdstempel als het duurlabel worden aangepast om de verstreken tijd weer te geven.
Bij het indrukken van de “Pauze”-toets worden de visuele media onderbroken, terwijl wordt overgeschakeld naar de “Hervatten”-optie. Door de functie “Snel vooruitspoelen” te selecteren, gaat de audiovisuele presentatie tien seconden vooruit.
Op dezelfde manier wordt de video tien seconden teruggespoeld als de “Terugspoel”-toets wordt ingedrukt. De “Stop”-toets beëindigt het afspelen van de video volledig. Gebruikers kunnen de voortgangsbalk manipuleren om naar specifieke punten in de video te navigeren. Naarmate de voortgangsbalk langer wordt, geeft de weergegeven tijd de verstreken tijd sinds het begin van de video weer.
De toepassing Videomediaspeler verbeteren
Om de functionaliteit van deze videomediaspeler te verbeteren, wilt u misschien een functie toevoegen waarmee gebruikers ondertitelingsopties kunnen openen en weergeven. Andere mogelijke verbeteringen zijn het aanpassen van de schermafmetingen, het regelen van geluidsniveaus en het herhalen van specifieke segmenten van de video.
Om deze mogelijkheden in te bouwen, kun je gebruikmaken van de Pygame-bibliotheek. Pygame is een zeer aanpasbare, gebruiksvriendelijke tool die naadloos samengaat met Tkinter. Dit vindingrijke pakket biedt de mogelijkheid voor persoonlijke configuratie, laat een scala aan interactieve elementen zien en werkt feilloos op alle platformen.