VLC Music Player Python
👤 Sharing: AI
----------------------------------------------------------------
----------------------------requirement.txt---------------------
----------------------------------------------------------------
mutagen==1.47.0
tkinter-tooltip==2.1.0
python-vlc==3.0.20123
----------------------------------------------------------------
---------------------------vlc_music_player.py------------------
----------------------------------------------------------------
import tkinter as tk
from tkinter import ttk, filedialog, messagebox
import os
import threading
import time
import json
import random
from mutagen.mp3 import MP3
from mutagen.m4a import M4A
from mutagen.id3 import ID3
import vlc
class VLCMusicPlayer:
def __init__(self, root):
self.root = root
self.root.title("? VLC Müzik Oynatıcı")
self.root.geometry("900x700") # Pencereyi büyüttüm
self.root.configure(bg='#2b2b2b')
# VLC instance oluştur
self.vlc_instance = vlc.Instance()
self.player = self.vlc_instance.media_player_new()
# Değişkenler
self.current_song = ""
self.song_list = []
self.current_index = 0
self.is_playing = False
self.is_paused = False
self.volume = 0.7
self.song_length = 0
self.current_time = 0
self.shuffle_mode = False
self.repeat_mode = 0 # 0: kapalı, 1: tek şarkı, 2: tüm liste
self.original_playlist = []
self.playback_speed = 1.0
self.total_duration = 0
# GUI oluşturma
self.create_gui()
# Zamanlayıcı
self.update_timer()
def create_gui(self):
# Ana frame
main_frame = tk.Frame(self.root, bg='#2b2b2b')
main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
# Üst panel - Başlık ve kontroller (daha kompakt)
top_panel = tk.Frame(main_frame, bg='#2b2b2b')
top_panel.pack(fill=tk.X, pady=(0, 10))
# Sol taraf - Başlık
title_frame = tk.Frame(top_panel, bg='#2b2b2b')
title_frame.pack(side=tk.LEFT, fill=tk.Y, padx=(0, 20))
title_label = tk.Label(title_frame, text="? VLC Müzik Oynatıcı",
font=("Arial", 16, "bold"),
fg='#ffffff', bg='#2b2b2b')
title_label.pack(anchor=tk.W)
# Sağ taraf - Mod kontrolleri
mode_frame = tk.Frame(top_panel, bg='#2b2b2b')
mode_frame.pack(side=tk.RIGHT, fill=tk.Y)
# Karıştır butonu
self.shuffle_button = tk.Button(mode_frame, text="?",
font=("Arial", 12),
command=self.toggle_shuffle,
bg='#4a4a4a', fg='#ffffff',
relief=tk.FLAT, padx=8, pady=5)
self.shuffle_button.pack(side=tk.LEFT, padx=2)
# Tekrarlama butonu
self.repeat_button = tk.Button(mode_frame, text="?",
font=("Arial", 12),
command=self.toggle_repeat,
bg='#4a4a4a', fg='#ffffff',
relief=tk.FLAT, padx=8, pady=5)
self.repeat_button.pack(side=tk.LEFT, padx=2)
# Şarkı bilgisi frame (daha kompakt)
song_info_frame = tk.Frame(main_frame, bg='#3b3b3b', relief=tk.RAISED, bd=2)
song_info_frame.pack(fill=tk.X, pady=(0, 10))
# Şarkı adı ve zaman bilgisi aynı hizada
info_frame = tk.Frame(song_info_frame, bg='#3b3b3b')
info_frame.pack(fill=tk.X, padx=15, pady=8)
# Sol taraf - Şarkı adı
self.song_name_label = tk.Label(info_frame, text="Şarkı seçilmedi",
font=("Arial", 11, "bold"),
fg='#ffffff', bg='#3b3b3b',
anchor=tk.W)
self.song_name_label.pack(side=tk.LEFT, fill=tk.X, expand=True)
# Sağ taraf - Zaman bilgisi
time_frame = tk.Frame(info_frame, bg='#3b3b3b')
time_frame.pack(side=tk.RIGHT)
self.current_time_label = tk.Label(time_frame, text="00:00",
font=("Arial", 10),
fg='#cccccc', bg='#3b3b3b')
self.current_time_label.pack(side=tk.LEFT, padx=(0, 5))
separator_label = tk.Label(time_frame, text="/",
font=("Arial", 10),
fg='#666666', bg='#3b3b3b')
separator_label.pack(side=tk.LEFT, padx=2)
self.total_time_label = tk.Label(time_frame, text="00:00",
font=("Arial", 10),
fg='#cccccc', bg='#3b3b3b')
self.total_time_label.pack(side=tk.LEFT, padx=(5, 0))
# İlerleme çubuğu (modern tasarım)
progress_frame = tk.Frame(main_frame, bg='#2b2b2b')
progress_frame.pack(fill=tk.X, pady=(0, 10))
self.progress_var = tk.DoubleVar()
self.progress_bar = ttk.Scale(progress_frame, from_=0, to=100,
orient=tk.HORIZONTAL,
variable=self.progress_var,
command=self.seek_song,
style='Modern.Horizontal.TScale')
self.progress_bar.pack(fill=tk.X, padx=10)
# Tıklama olayı ekle
self.progress_bar.bind('<Button-1>', self.on_progress_click)
# Modern stil tanımla
style = ttk.Style()
style.configure('Modern.Horizontal.TScale',
background='#3b3b3b',
troughcolor='#4a4a4a',
sliderwidth=12,
sliderlength=20)
# Kontrol butonları (daha kompakt)
control_frame = tk.Frame(main_frame, bg='#2b2b2b')
control_frame.pack(pady=(0, 10))
# Sol taraf - Ses kontrolü
volume_frame = tk.Frame(control_frame, bg='#2b2b2b')
volume_frame.pack(side=tk.LEFT, padx=(0, 15))
volume_label = tk.Label(volume_frame, text="?",
font=("Arial", 10),
fg='#ffffff', bg='#2b2b2b')
volume_label.pack(side=tk.LEFT, padx=(0, 5))
self.volume_var = tk.DoubleVar(value=self.volume * 100)
self.volume_scale = ttk.Scale(volume_frame, from_=0, to=100,
orient=tk.HORIZONTAL,
variable=self.volume_var,
command=self.change_volume,
style='Volume.Horizontal.TScale',
length=80)
self.volume_scale.pack(side=tk.LEFT)
# Ses seviyesi göstergesi
self.volume_value_label = tk.Label(volume_frame, text="70%",
font=("Arial", 8),
fg='#cccccc', bg='#2b2b2b')
self.volume_value_label.pack(side=tk.LEFT, padx=(5, 0))
# Orta - Oynatma kontrolleri
play_controls = tk.Frame(control_frame, bg='#2b2b2b')
play_controls.pack(side=tk.LEFT)
# Önceki buton
self.prev_button = tk.Button(play_controls, text="⏮",
font=("Arial", 8),
command=self.previous_song,
bg='#4a90e2', fg='#ffffff',
relief=tk.FLAT, padx=4, pady=4)
self.prev_button.pack(side=tk.LEFT, padx=5)
# Oynat/Duraklat buton
self.play_button = tk.Button(play_controls, text="▶",
font=("Arial", 8),
command=self.play_pause,
bg='#4a90e2', fg='#ffffff',
relief=tk.FLAT, padx=4, pady=4)
self.play_button.pack(side=tk.LEFT, padx=5)
# Durdur buton
self.stop_button = tk.Button(play_controls, text="⏹",
font=("Arial", 8),
command=self.stop_song,
bg='#4a90e2', fg='#ffffff',
relief=tk.FLAT, padx=4, pady=4)
self.stop_button.pack(side=tk.LEFT, padx=5)
# Sonraki buton
self.next_button = tk.Button(play_controls, text="⏭",
font=("Arial", 8),
command=self.next_song,
bg='#4a90e2', fg='#ffffff',
relief=tk.FLAT, padx=4, pady=4)
self.next_button.pack(side=tk.LEFT, padx=5)
# Sağ taraf - Dosya işlemleri
file_controls = tk.Frame(control_frame, bg='#2b2b2b')
file_controls.pack(side=tk.RIGHT)
self.add_button = tk.Button(file_controls, text="?",
command=self.add_files,
bg='#4a4a4a', fg='#ffffff',
relief=tk.FLAT, padx=4, pady=4,
font=("Arial", 6))
self.add_button.pack(side=tk.LEFT, padx=3)
self.folder_button = tk.Button(file_controls, text="?",
command=self.add_folder,
bg='#4a4a4a', fg='#ffffff',
relief=tk.FLAT, padx=4, pady=4,
font=("Arial", 6))
self.folder_button.pack(side=tk.LEFT, padx=3)
self.clear_button = tk.Button(file_controls, text="?️Liste",
command=self.clear_playlist,
bg='#4a4a4a', fg='#ffffff',
relief=tk.FLAT, padx=4, pady=4,
font=("Arial", 6))
self.clear_button.pack(side=tk.LEFT, padx=3)
# Ses stili tanımla
style.configure('Volume.Horizontal.TScale',
background='#3b3b3b',
troughcolor='#4a4a4a',
sliderwidth=8,
sliderlength=16)
# Hız kontrolü (alt satır)
speed_frame = tk.Frame(main_frame, bg='#2b2b2b')
speed_frame.pack(pady=(0, 10))
speed_label = tk.Label(speed_frame, text="⚡",
font=("Arial", 10),
fg='#ffffff', bg='#2b2b2b')
speed_label.pack(side=tk.LEFT, padx=(0, 5))
# Hız butonları (daha kompakt)
speeds = [("1x", 1.0), ("1.25x", 1.25), ("1.5x", 1.5), ("1.75x", 1.75), ("2x", 2.0)]
self.speed_buttons = {}
for text, speed in speeds:
btn = tk.Button(speed_frame, text=text,
font=("Arial", 8),
command=lambda s=speed: self.change_speed(s),
bg='#4a4a4a', fg='#ffffff',
relief=tk.FLAT, padx=4, pady=1,
width=3)
btn.pack(side=tk.LEFT, padx=1)
self.speed_buttons[speed] = btn
# Varsayılan hızı seç
self.speed_buttons[1.0].config(bg='#ff6b6b')
# Çalma listesi (daha büyük alan)
playlist_frame = tk.Frame(main_frame, bg='#2b2b2b')
playlist_frame.pack(fill=tk.BOTH, expand=True)
playlist_header = tk.Frame(playlist_frame, bg='#2b2b2b')
playlist_header.pack(fill=tk.X, pady=(0, 5))
playlist_label = tk.Label(playlist_header, text="? Çalma Listesi",
font=("Arial", 12, "bold"),
fg='#ffffff', bg='#2b2b2b')
playlist_label.pack(side=tk.LEFT)
# Toplam süre ve şarkı sayısı
self.playlist_info_label = tk.Label(playlist_header, text="0 şarkı • 00:00",
font=("Arial", 10),
fg='#cccccc', bg='#2b2b2b')
self.playlist_info_label.pack(side=tk.RIGHT)
# Çalma listesi listbox
listbox_frame = tk.Frame(playlist_frame, bg='#3b3b3b', relief=tk.SUNKEN, bd=2)
listbox_frame.pack(fill=tk.BOTH, expand=True)
self.playlist_box = tk.Listbox(listbox_frame,
bg='#3b3b3b', fg='#ffffff',
selectbackground='#4a4a4a',
font=("Arial", 10),
selectmode=tk.SINGLE)
self.playlist_box.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
# Scrollbar
scrollbar = tk.Scrollbar(listbox_frame, orient=tk.VERTICAL,
command=self.playlist_box.yview)
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
self.playlist_box.config(yscrollcommand=scrollbar.set)
# Çift tıklama ile oynatma
self.playlist_box.bind('<Double-Button-1>', self.play_selected)
def toggle_shuffle(self):
"""Karıştırma modunu aç/kapat"""
self.shuffle_mode = not self.shuffle_mode
if self.shuffle_mode:
self.shuffle_button.config(bg='#ff6b6b')
# Mevcut çalma listesini kaydet
if not self.original_playlist:
self.original_playlist = self.song_list.copy()
# Listeyi karıştır
shuffled_list = self.song_list.copy()
random.shuffle(shuffled_list)
self.song_list = shuffled_list
self.update_playlist_display()
else:
self.shuffle_button.config(bg='#4a4a4a')
# Orijinal listeyi geri yükle
if self.original_playlist:
self.song_list = self.original_playlist.copy()
self.update_playlist_display()
def toggle_repeat(self):
"""Tekrarlama modunu değiştir"""
self.repeat_mode = (self.repeat_mode + 1) % 3
if self.repeat_mode == 0:
self.repeat_button.config(text="?", bg='#4a4a4a')
elif self.repeat_mode == 1:
self.repeat_button.config(text="?1", bg='#ff6b6b')
else:
self.repeat_button.config(text="?", bg='#ff6b6b')
def change_speed(self, speed):
"""Oynatma hızını değiştir"""
self.playback_speed = speed
# Tüm hız butonlarını sıfırla
for btn in self.speed_buttons.values():
btn.config(bg='#4a4a4a')
# Seçili hızı vurgula
self.speed_buttons[speed].config(bg='#ff6b6b')
# VLC'de hızı ayarla
if self.is_playing:
self.player.set_rate(speed)
def update_playlist_display(self):
"""Çalma listesi görünümünü güncelle"""
self.playlist_box.delete(0, tk.END)
for song in self.song_list:
self.playlist_box.insert(tk.END, os.path.basename(song))
self.update_playlist_info()
def update_playlist_info(self):
"""Çalma listesi bilgilerini güncelle"""
count = len(self.song_list)
total_time = self.format_time(self.total_duration)
self.playlist_info_label.config(text=f"{count} şarkı • {total_time}")
def calculate_total_duration(self):
"""Toplam süreyi hesapla"""
total = 0
for song in self.song_list:
try:
if song.lower().endswith('.mp3'):
audio = MP3(song)
total += audio.info.length
elif song.lower().endswith('.m4a'):
audio = M4A(song)
total += audio.info.length
else:
# VLC ile uzunluk al
media = self.vlc_instance.media_new(song)
media.parse()
duration = media.get_duration() / 1000.0
total += duration
except Exception as e:
# Hata durumunda VLC ile dene
try:
media = self.vlc_instance.media_new(song)
media.parse()
duration = media.get_duration() / 1000.0
total += duration
except:
pass
self.total_duration = total
self.update_playlist_info()
def add_files(self):
"""Dosya ekleme"""
files = filedialog.askopenfilenames(
title="Müzik dosyalarını seçin",
filetypes=[
("Müzik dosyaları", "*.mp3 *.m4a *.wav *.flac *.ogg"),
("MP3 dosyaları", "*.mp3"),
("M4A dosyaları", "*.m4a"),
("WAV dosyaları", "*.wav"),
("FLAC dosyaları", "*.flac"),
("OGG dosyaları", "*.ogg"),
("Tüm dosyalar", "*.*")
]
)
for file in files:
if file not in self.song_list:
self.song_list.append(file)
self.update_playlist_display()
self.calculate_total_duration()
if self.song_list and not self.current_song:
self.current_index = 0
self.load_song()
def add_folder(self):
"""Klasör ekleme"""
folder = filedialog.askdirectory(title="Müzik klasörünü seçin")
if folder:
for root, dirs, files in os.walk(folder):
for file in files:
if file.lower().endswith(('.mp3', '.m4a', '.wav', '.flac', '.ogg')):
file_path = os.path.join(root, file)
if file_path not in self.song_list:
self.song_list.append(file_path)
self.update_playlist_display()
self.calculate_total_duration()
if self.song_list and not self.current_song:
self.current_index = 0
self.load_song()
def clear_playlist(self):
"""Çalma listesini temizleme"""
if messagebox.askyesno("Onay", "Çalma listesini temizlemek istediğinizden emin misiniz?"):
self.stop_song()
self.song_list.clear()
self.original_playlist.clear()
self.shuffle_mode = False
self.shuffle_button.config(bg='#4a4a4a')
self.update_playlist_display()
self.total_duration = 0
self.current_song = ""
self.song_name_label.config(text="Şarkı seçilmedi")
self.current_time_label.config(text="00:00")
self.total_time_label.config(text="00:00")
self.progress_var.set(0)
def load_song(self):
"""Şarkı yükleme"""
if self.song_list:
self.current_song = self.song_list[self.current_index]
self.song_name_label.config(text=os.path.basename(self.current_song))
# Şarkı uzunluğunu al
try:
if self.current_song.lower().endswith('.mp3'):
audio = MP3(self.current_song)
self.song_length = audio.info.length
elif self.current_song.lower().endswith('.m4a'):
audio = M4A(self.current_song)
self.song_length = audio.info.length
else:
# VLC ile uzunluk al
media = self.vlc_instance.media_new(self.current_song)
media.parse()
self.song_length = media.get_duration() / 1000.0
self.total_time_label.config(text=self.format_time(self.song_length))
except Exception as e:
# Hata durumunda VLC ile dene
try:
media = self.vlc_instance.media_new(self.current_song)
media.parse()
self.song_length = media.get_duration() / 1000.0
self.total_time_label.config(text=self.format_time(self.song_length))
except:
self.song_length = 0
self.total_time_label.config(text="00:00")
# Çalma listesinde seçili öğeyi güncelle
self.playlist_box.selection_clear(0, tk.END)
self.playlist_box.selection_set(self.current_index)
self.playlist_box.see(self.current_index)
def play_pause(self):
"""Oynat/Duraklat"""
if not self.current_song:
if self.song_list:
self.current_index = 0
self.load_song()
self.play_song()
return
if self.is_playing:
if self.is_paused:
self.resume_song()
else:
self.pause_song()
else:
self.play_song()
def play_song(self):
"""Şarkı oynatma"""
try:
if self.current_song:
# VLC ile media oluştur
media = self.vlc_instance.media_new(self.current_song)
self.player.set_media(media)
self.player.play()
self.player.audio_set_volume(int(self.volume * 100))
self.player.set_rate(self.playback_speed)
self.is_playing = True
self.is_paused = False
self.play_button.config(text="⏸")
# İlerleme çubuğunu sıfırla
self.progress_var.set(0)
self.current_time = 0
self.current_time_label.config(text="00:00")
except Exception as e:
messagebox.showerror("Hata", f"Şarkı oynatılamadı: {str(e)}")
def pause_song(self):
"""Şarkı duraklatma"""
self.player.pause()
self.is_paused = True
self.play_button.config(text="▶")
def resume_song(self):
"""Şarkı devam ettirme"""
self.player.pause() # VLC'de pause/resume aynı fonksiyon
self.is_paused = False
self.play_button.config(text="⏸")
def stop_song(self):
"""Şarkı durdurma"""
self.player.stop()
self.is_playing = False
self.is_paused = False
self.play_button.config(text="▶")
self.current_time = 0
self.progress_var.set(0)
self.current_time_label.config(text="00:00")
def next_song(self):
"""Sonraki şarkı"""
if self.song_list:
if self.repeat_mode == 1: # Tek şarkı tekrarlama
self.load_song()
if self.is_playing:
self.play_song()
else:
self.current_index = (self.current_index + 1) % len(self.song_list)
self.load_song()
if self.is_playing:
self.play_song()
def previous_song(self):
"""Önceki şarkı"""
if self.song_list:
self.current_index = (self.current_index - 1) % len(self.song_list)
self.load_song()
if self.is_playing:
self.play_song()
def play_selected(self, event):
"""Seçili şarkıyı oynatma"""
selection = self.playlist_box.curselection()
if selection:
self.current_index = selection[0]
self.load_song()
self.play_song()
def seek_song(self, value):
"""Şarkıda ilerleme (sürükleme ile)"""
if self.current_song and self.song_length > 0:
position = float(value) / 100.0 * self.song_length
self.player.set_time(int(position * 1000)) # VLC milisaniye kullanır
self.current_time = position
self.current_time_label.config(text=self.format_time(self.current_time))
def on_progress_click(self, event):
"""İlerleme çubuğuna tıklama ile ilerleme"""
if self.current_song and self.song_length > 0:
# Tıklanan pozisyonu hesapla
widget_width = self.progress_bar.winfo_width()
click_x = event.x
percentage = (click_x / widget_width) * 100
# Yüzdeyi sınırla
percentage = max(0, min(100, percentage))
# Pozisyonu hesapla ve uygula
position = (percentage / 100.0) * self.song_length
self.player.set_time(int(position * 1000)) # VLC milisaniye kullanır
self.current_time = position
self.current_time_label.config(text=self.format_time(self.current_time))
# İlerleme çubuğunu güncelle
self.progress_var.set(percentage)
def change_volume(self, value):
"""Ses seviyesi değiştirme"""
self.volume = float(value) / 100.0
self.player.audio_set_volume(int(self.volume * 100))
# Ses seviyesi göstergesini güncelle
self.volume_value_label.config(text=f"{int(self.volume * 100)}%")
def format_time(self, seconds):
"""Zamanı formatlama"""
minutes = int(seconds // 60)
seconds = int(seconds % 60)
return f"{minutes:02d}:{seconds:02d}"
def update_timer(self):
"""Zamanlayıcı güncelleme"""
if self.is_playing and not self.is_paused:
try:
# VLC'den mevcut pozisyonu al
current_pos = self.player.get_time() / 1000.0
if current_pos >= 0: # 0 dahil olmalı
self.current_time = current_pos
self.current_time_label.config(text=self.format_time(self.current_time))
if self.song_length > 0:
progress = (self.current_time / self.song_length) * 100
# İlerleme çubuğunu güncelle (sadece oynatma sırasında)
if not self.is_paused:
self.progress_var.set(progress)
# Şarkı bittiğinde sonrakine geç
if self.current_time >= self.song_length - 1: # 1 saniye tolerans
if self.repeat_mode == 2: # Liste tekrarlama
self.next_song()
elif self.repeat_mode == 1: # Tek şarkı tekrarlama
self.play_song()
else: # Tekrarlama kapalı
if self.current_index < len(self.song_list) - 1:
self.next_song()
else:
self.stop_song()
except Exception as e:
# Hata durumunda sessizce devam et
pass
# Daha sık güncelleme (500ms)
self.root.after(500, self.update_timer)
def main():
root = tk.Tk()
app = VLCMusicPlayer(root)
root.mainloop()
if __name__ == "__main__":
main()
-------------------------------------------------------------------
----------------------------Built with Cursor----------------------
-------------------------------------------------------------------
👁️ Viewed: 76
Comments