Skip to content

Instantly share code, notes, and snippets.

@eros18123
Created November 23, 2024 11:11
Show Gist options
  • Save eros18123/49d183c4f74b52079373c1361c3b39d5 to your computer and use it in GitHub Desktop.
Save eros18123/49d183c4f74b52079373c1361c3b39d5 to your computer and use it in GitHub Desktop.
Music Audio Sound pyqt5 versao 2
import os
import json
try:
from PyQt6.QtWidgets import (QDialog, QVBoxLayout, QPushButton, QFileDialog, QSlider, QLabel, QListWidget, QApplication, QAction)
from PyQt6.QtMultimedia import QMediaPlayer, QAudioOutput
from PyQt6.QtCore import QUrl, Qt, QTimer
from PyQt6.QtGui import QPixmap, QPalette, QBrush
from aqt import mw
pyqt_version = "PyQt6"
except ImportError:
from PyQt5.QtWidgets import (QDialog, QVBoxLayout, QPushButton, QFileDialog, QSlider, QLabel, QListWidget, QApplication, QAction)
from PyQt5.QtMultimedia import QMediaPlayer, QMediaContent, QAudioOutput
from PyQt5.QtCore import QUrl, Qt, QTimer
from PyQt5.QtGui import QPixmap, QPalette, QBrush
from aqt import mw
pyqt_version = "PyQt5"
# Caminho do arquivo JSON para salvar a lista de músicas
ADDON_DIR = os.path.dirname(__file__)
PLAYLIST_FILE = os.path.join(ADDON_DIR, "playlist.json")
class AudioPlayerDialog(QDialog):
def __init__(self):
super().__init__(None, Qt.WindowType.Window | Qt.WindowType.WindowMinimizeButtonHint |
Qt.WindowType.WindowMaximizeButtonHint | Qt.WindowType.WindowCloseButtonHint |
Qt.WindowType.WindowStaysOnTopHint)
self.setWindowTitle("Reprodutor de Áudio")
self.setMinimumSize(400, 450)
# Caminho da imagem de fundo
background_image_path = os.path.join(ADDON_DIR, "image.jpg")
# Configura o fundo da caixa de diálogo
if os.path.exists(background_image_path):
pixmap = QPixmap(background_image_path)
palette = QPalette()
palette.setBrush(QPalette.ColorRole.Window, QBrush(pixmap))
self.setPalette(palette)
else:
print(f"Imagem de fundo não encontrada em: {background_image_path}")
self.layout = QVBoxLayout(self)
# Botão para carregar arquivos de áudio
self.load_button = QPushButton("Adicionar Áudios (.wav, .mp3, .mp4)")
self.layout.addWidget(self.load_button)
# Botão para remover músicas
self.remove_button = QPushButton("Remover Música")
self.layout.addWidget(self.remove_button)
# Lista de músicas
self.audio_list = QListWidget()
self.layout.addWidget(self.audio_list)
# Controles do reprodutor
self.player = QMediaPlayer(self)
# Handling for PyQt5 and PyQt6
if pyqt_version == "PyQt6":
self.audio_output = QAudioOutput(self)
self.player.setAudioOutput(self.audio_output)
else:
# For PyQt5, use QMediaPlayer's default audio output (no need for explicit setAudioOutput)
self.audio_output = QAudioOutput() # You can still use QAudioOutput directly
# Note: PyQt5 does not need a special method to link to the audio output in this case
# Slider de progresso do áudio
self.progress_label = QLabel("Progresso: 00:00 / 00:00")
self.layout.addWidget(self.progress_label)
self.progress_slider = QSlider(Qt.Orientation.Horizontal)
self.layout.addWidget(self.progress_slider)
# Botão Play/Pause
self.play_button = QPushButton("▶ Play / ⏸ Pause")
self.layout.addWidget(self.play_button)
# Slider de velocidade
self.speed_label = QLabel("Velocidade: 1.0x")
self.layout.addWidget(self.speed_label)
self.speed_slider = QSlider(Qt.Orientation.Horizontal)
self.speed_slider.setRange(5, 20) # Velocidade entre 0.5x e 2.0x
self.speed_slider.setValue(10) # Valor padrão: 1.0x
self.layout.addWidget(self.speed_slider)
# Slider de volume
self.volume_label = QLabel("Volume: 100%")
self.layout.addWidget(self.volume_label)
self.volume_slider = QSlider(Qt.Orientation.Horizontal)
self.volume_slider.setRange(0, 100) # Volume entre 0% e 100%
self.volume_slider.setValue(100) # Valor padrão: 100%
self.layout.addWidget(self.volume_slider)
# Conectar eventos
self.load_button.clicked.connect(self.load_audio)
self.remove_button.clicked.connect(self.remove_audio)
self.play_button.clicked.connect(self.toggle_play_pause)
self.speed_slider.valueChanged.connect(self.change_speed)
self.volume_slider.valueChanged.connect(self.change_volume)
self.audio_list.itemClicked.connect(self.select_audio)
self.progress_slider.sliderReleased.connect(self.change_position)
# Conectar eventos de status do player
self.player.positionChanged.connect(self.update_progress)
self.player.durationChanged.connect(self.update_duration)
self.player.mediaStatusChanged.connect(self.handle_media_status)
# Carregar músicas salvas
self.load_saved_playlist()
def closeEvent(self, event):
# Parar o áudio ao fechar a caixa de diálogo
self.player.stop()
super().closeEvent(event)
def load_audio(self):
file_paths, _ = QFileDialog.getOpenFileNames(
self,
"Selecione arquivos de áudio/vídeo",
"",
"Mídia Suportada (*.wav *.mp3 *.mp4)"
)
for file_path in file_paths:
if file_path and file_path not in self.get_current_playlist():
self.audio_list.addItem(file_path)
self.save_playlist()
def remove_audio(self):
selected_item = self.audio_list.currentItem()
if selected_item:
self.audio_list.takeItem(self.audio_list.row(selected_item))
self.save_playlist()
def select_audio(self, item):
file_path = item.text()
if file_path:
self.play_audio(file_path)
def play_audio(self, file_path):
self.player.stop()
QTimer.singleShot(100, lambda: self.load_and_play(file_path))
def load_and_play(self, file_path):
try:
# Corrigir para usar o método correto para PyQt6 (e PyQt5)
media_content = QMediaContent(QUrl.fromLocalFile(file_path))
self.player.setMedia(media_content)
self.player.play()
except Exception as e:
print(f"Erro ao carregar o áudio: {e}")
# def toggle_play_pause(self):
# if self.player.playbackState() == QMediaPlayer.PlaybackState.PlayingState:
# self.player.pause()
#else:
# self.player.play()
def toggle_play_pause(self):
# Para PyQt5, usamos state() ao invés de playbackState()
if self.player.state() == QMediaPlayer.PlayingState:
self.player.pause()
else:
self.player.play()
def change_speed(self, value):
speed = value / 10
self.player.setPlaybackRate(speed)
self.speed_label.setText(f"Velocidade: {speed:.1f}x")
def change_volume(self, value):
# Ajuste gradual do volume, mantendo os valores mais controláveis
# Usamos uma fórmula para suavizar o volume e garantir que a mudança não seja abrupta
volume = value / 100.0 # Conversão de 0-100 para 0.0-1.0
# Filtro para suavizar a mudança de volume (ajustar o fator para menos sensibilidade)
volume = volume ** 2 # Potencializa o valor para um ajuste mais suave
# Atualiza o volume no áudio
if pyqt_version == "PyQt6":
self.audio_output.setVolume(volume)
else:
self.player.setVolume(int(volume * 100)) # Para PyQt5, precisa de volume em inteiro
# Atualiza a exibição do volume
self.volume_label.setText(f"Volume: {value}%")
def update_progress(self, position):
self.progress_slider.setValue(position)
self.update_progress_label(position)
def update_duration(self, duration):
self.progress_slider.setRange(0, duration)
self.update_progress_label(self.player.position())
def update_progress_label(self, position):
duration = self.player.duration()
current_time = self.format_time(position)
total_time = self.format_time(duration)
self.progress_label.setText(f"Progresso: {current_time} / {total_time}")
def format_time(self, milliseconds):
seconds = milliseconds // 1000
minutes = seconds // 60
seconds = seconds % 60
return f"{minutes:02}:{seconds:02}"
def change_position(self):
new_position = self.progress_slider.value()
self.player.setPosition(new_position)
def get_current_playlist(self):
return [self.audio_list.item(i).text() for i in range(self.audio_list.count())]
def save_playlist(self):
playlist = self.get_current_playlist()
with open(PLAYLIST_FILE, "w", encoding="utf-8") as f:
json.dump(playlist, f, indent=4)
def load_saved_playlist(self):
if os.path.exists(PLAYLIST_FILE):
with open(PLAYLIST_FILE, "r", encoding="utf-8") as f:
playlist = json.load(f)
for file_path in playlist:
if os.path.exists(file_path):
self.audio_list.addItem(file_path)
def handle_media_status(self, status):
if status == QMediaPlayer.MediaStatus.EndOfMedia:
current_row = self.audio_list.currentRow()
next_row = (current_row + 1) % self.audio_list.count()
next_item = self.audio_list.item(next_row)
if next_item:
self.audio_list.setCurrentRow(next_row)
self.play_audio(next_item.text())
def show_audio_player_dialog():
global dialog # Mantém uma referência global à caixa de diálogo
dialog = AudioPlayerDialog()
dialog.show()
# Adicionar o menu "Sound" ao menu principal do Anki
action = QAction("Sound", mw)
action.triggered.connect(show_audio_player_dialog)
mw.form.menuTools.addAction(action)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment