Fbrowser/testmid.py

137 lines
4.4 KiB
Python

import os
import subprocess
from PyQt6.QtWidgets import QWidget, QVBoxLayout, QPushButton, QLabel, QFileDialog, QSlider, QListWidget
from PyQt6.QtCore import Qt, QUrl
from PyQt6.QtMultimedia import QMediaPlayer, QAudioOutput
DEFAULT_SOUNDFONT = '/home/stan/Documents/Dev/Tests/MidPlay/SoundFonts/FinalFantasyVI.sf2'
class MidPlay(QWidget):
def __init__(self):
super().__init__()
self.current_file = None
self.current_soundfont = DEFAULT_SOUNDFONT
self.process = None
self.media_player = QMediaPlayer()
self.audio_output = QAudioOutput()
self.media_player.setAudioOutput(self.audio_output)
self.playlist = []
self.current_index = 0
self.current_volume = 50
self.init_ui()
def init_ui(self):
layout = QVBoxLayout()
self.playlist_widget = QListWidget()
self.playlist_widget.itemDoubleClicked.connect(self.play_selected)
layout.addWidget(self.playlist_widget)
self.play_button = QPushButton("Play")
self.play_button.clicked.connect(self.play)
layout.addWidget(self.play_button)
self.stop_button = QPushButton("Stop")
self.stop_button.clicked.connect(self.stop)
layout.addWidget(self.stop_button)
self.next_button = QPushButton("Next")
self.next_button.clicked.connect(self.play_next)
layout.addWidget(self.next_button)
self.volume_slider = QSlider(Qt.Orientation.Horizontal)
self.volume_slider.setRange(0, 100)
self.volume_slider.setValue(self.current_volume)
self.volume_slider.valueChanged.connect(self.set_volume)
layout.addWidget(self.volume_slider)
self.status_label = QLabel("No file loaded")
layout.addWidget(self.status_label)
self.setLayout(layout)
def add_to_playlist(self, file_path):
self.playlist.append(file_path)
self.playlist_widget.addItem(os.path.basename(file_path))
if not self.current_file:
self.current_file = file_path
self.play()
def play_selected(self, item):
index = self.playlist_widget.row(item)
self.current_index = index
self.current_file = self.playlist[index]
self.play()
def play(self):
if not self.current_file:
self.status_label.setText("No file selected")
return
self.stop() # Stop any current playback
if self.current_file.lower().endswith(('.mid', '.midi')):
self.play_midi()
else:
self.play_audio()
def play_midi(self):
self.media_player.stop()
command = [
"fluidsynth",
"-a", "pulseaudio",
"-g", str(self.current_volume / 50),
self.current_soundfont,
self.current_file
]
self.process = subprocess.Popen(command)
self.status_label.setText(f"Playing MIDI: {os.path.basename(self.current_file)}")
def play_audio(self):
if self.process:
self.process.terminate()
self.process = None
self.media_player.setSource(QUrl.fromLocalFile(self.current_file))
self.media_player.play()
self.status_label.setText(f"Playing Audio: {os.path.basename(self.current_file)}")
self.media_player.mediaStatusChanged.connect(self.handle_media_status_change)
def stop(self):
if self.process:
self.process.terminate()
self.process = None
self.media_player.stop()
self.status_label.setText("Playback stopped")
def set_volume(self, value):
self.current_volume = value
self.audio_output.setVolume(value / 50)
if self.process and self.current_file.lower().endswith(('.mid', '.midi')):
self.update_midi_volume()
def update_midi_volume(self):
pass
def play_next(self):
if self.playlist:
self.current_index = (self.current_index + 1) % len(self.playlist)
self.current_file = self.playlist[self.current_index]
self.play()
def handle_media_status_change(self, status):
if status == QMediaPlayer.MediaStatus.EndOfMedia:
self.play_next()
def closeEvent(self, event):
self.stop()
super().closeEvent(event)
def showUI(self):
self.setWindowTitle("MidPlay")
super().show()
def close(self):
self.stop()
super().close()