Created
November 23, 2024 11:11
-
-
Save eros18123/49d183c4f74b52079373c1361c3b39d5 to your computer and use it in GitHub Desktop.
Music Audio Sound pyqt5 versao 2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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