273 lines
12 KiB
Python
Executable File
273 lines
12 KiB
Python
Executable File
# Path: Fbrowser.py
|
|
# Sample Music Browser & Ogranizer: Main.py
|
|
|
|
# Importing Libraries
|
|
import sys
|
|
import os
|
|
|
|
from ScanOrg import organizer, file_scanner, DirectoryFilterProxyModel, FileFilterProxyModel
|
|
from stanzip import Extractor as extractor
|
|
from stanzip import Compressor as compressor
|
|
from stanzip import zipfile, py7zr, rarfile
|
|
from PyQt5.QtGui import QStandardItem , QStandardItemModel, QContextMenuEvent
|
|
from PyQt5.QtWidgets import QApplication, QLabel, QPushButton, QVBoxLayout, QMenu, QTreeView, QMessageBox, QSlider, QWidget, QFileSystemModel, QSplitter, QHBoxLayout, QFileDialog
|
|
from PyQt5.QtMultimedia import QMediaPlaylist, QMediaPlayer, QMediaContent, QAudioFormat, QAudioDeviceInfo, QAudio
|
|
from PyQt5.QtCore import QDir, QSortFilterProxyModel, Qt, QUrl
|
|
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as MPLCanvas
|
|
from matplotlib.figure import Figure
|
|
|
|
|
|
|
|
# Sample Music Browser Main Class
|
|
class SampleMusicBrowser(QWidget):
|
|
def __init__(self):
|
|
super().__init__()
|
|
self.organizer = organizer()
|
|
self.extractor = extractor()
|
|
self.file_model = QStandardItemModel()
|
|
self.player = QMediaPlayer()
|
|
self.playlist = QMediaPlaylist()
|
|
self.player.setPlaylist(self.playlist)
|
|
self.tree_model = QFileSystemModel()
|
|
|
|
self.init_ui()
|
|
#self.midi_player = MidPlay()
|
|
self.folder_contents_view.setEditTriggers(QTreeView.NoEditTriggers)
|
|
self.player.error.connect(self.player_error)
|
|
self.player.mediaStatusChanged.connect(self.player_media_status_changed)
|
|
self.player.setAudioRole(QAudio.MusicRole)
|
|
self.layout = QHBoxLayout()
|
|
self.canvas = MPLCanvas()
|
|
self.layout.addWidget(self.canvas)
|
|
self.setLayout(self.layout)
|
|
|
|
# Player Error Debugging
|
|
def player_error(self, error):
|
|
try:
|
|
if error == QMediaPlayer.NoError:
|
|
return
|
|
print(f"An error occurred: Code:{error} {self.player.errorString()}")
|
|
except Exception as e:
|
|
print(f"Error: {e}")
|
|
|
|
# Media Status Changed Debugging
|
|
def player_media_status_changed(self, status):
|
|
if status == QMediaPlayer.NoMedia:
|
|
return
|
|
print('Media Status: ' + str(status))
|
|
|
|
|
|
def on_extract_button_clicked(self):
|
|
extraction_directory = QFileDialog.getExistingDirectory(self, "Select Extraction Directory")
|
|
if extraction_directory:
|
|
index = self.folder_contents_view.currentIndex()
|
|
if index.isValid():
|
|
self.extractor.zipviewer(index, self.file_filter_model, self.list_model, extraction_directory)
|
|
|
|
def show_context_menu(self, position):
|
|
menu = QMenu(self)
|
|
extract_action = menu.addAction('Extract')
|
|
extract_action.triggered.connect(self.on_extract_button_clicked) # Connect to the extraction function
|
|
menu.exec(self.folder_contents_view.mapToGlobal(position))
|
|
|
|
def init_ui(self):
|
|
layout = QVBoxLayout()
|
|
label = QLabel('Sample Music Browser')
|
|
buttons_layout = QHBoxLayout()
|
|
layout.addWidget(label)
|
|
|
|
|
|
#self.midi_player = MidPlay()
|
|
self.file_tree = QTreeView()
|
|
|
|
self.file_tree.setHeaderHidden(True)
|
|
self.file_tree.clicked.connect(self.change_directory)
|
|
|
|
|
|
play_button = QPushButton('Play')
|
|
play_button.clicked.connect(self.player.play)
|
|
#play_button.clicked.connect(self.midi_player.play_midi)
|
|
buttons_layout.addWidget(play_button)
|
|
|
|
stop_button = QPushButton('Stop')
|
|
stop_button.clicked.connect(self.player.stop)
|
|
# stop_button.clicked.connect(self.midi_player.stop)
|
|
buttons_layout.addWidget(stop_button)
|
|
self.player.stateChanged.connect(self.player_state_changed)
|
|
self.player.positionChanged.connect(self.player_position_changed)
|
|
self.player.durationChanged.connect(self.player_duration_changed)
|
|
|
|
|
|
layout.addLayout(buttons_layout)
|
|
|
|
self.folder_contents_view = QTreeView()
|
|
self.folder_contents_view.setHeaderHidden(False)
|
|
self.folder_contents_view.setRootIsDecorated(False)
|
|
self.folder_contents_view.setSortingEnabled(True)
|
|
|
|
splitter = QSplitter()
|
|
splitter.addWidget(self.file_tree)
|
|
splitter.addWidget(self.folder_contents_view)
|
|
layout.addWidget(splitter)
|
|
self.current_dir_label = QLabel()
|
|
layout.addWidget(self.current_dir_label)
|
|
|
|
up_dir_button = QPushButton('Up Directory')
|
|
up_dir_button.clicked.connect(self.go_up_directory)
|
|
layout.addWidget(up_dir_button)
|
|
|
|
forward_button = QPushButton('Forward')
|
|
forward_button.clicked.connect(self.go_forward_directory)
|
|
layout.addWidget(forward_button)
|
|
self.setLayout(layout)
|
|
|
|
self.setWindowTitle('Samples are life!')
|
|
path = QFileDialog.getExistingDirectory(self, 'Select Directory')
|
|
if path:
|
|
self.populate_file_tree(path)
|
|
|
|
|
|
self.player.setVolume(50)
|
|
volume_slider = QSlider(Qt.Horizontal)
|
|
volume_slider.setRange(0, 100)
|
|
volume_slider.setValue(50)
|
|
volume_slider.valueChanged.connect(self.player.setVolume)
|
|
layout.addWidget(volume_slider)
|
|
self.playlist.currentIndexChanged.connect(self.playlist_current_index_changed)
|
|
self.playlist.currentMediaChanged.connect(self.playlist_current_media_changed)
|
|
self.playlist.mediaInserted.connect(self.playlist_media_inserted)
|
|
self.playlist.mediaRemoved.connect(self.playlist_media_removed)
|
|
self.playlist.setPlaybackMode(QMediaPlaylist.Loop)
|
|
self.folder_contents_view.doubleClicked.connect(self.play_file)
|
|
self.folder_contents_view.setContextMenuPolicy(Qt.CustomContextMenu)
|
|
self.folder_contents_view.customContextMenuRequested.connect(self.show_context_menu)
|
|
|
|
|
|
def directory_loaded(self, path):
|
|
self.file_tree.setRootIndex(self.directory_model.mapFromSource(self.model.index(path)))
|
|
self.folder_contents_view.setRootIndex(self.file_filter_model.mapFromSource(self.list_model.index(path)))
|
|
|
|
def populate_file_tree(self, path):
|
|
try:
|
|
self.tree_model.setRootPath(path)
|
|
self.file_tree.setModel(self.tree_model)
|
|
self.directory_model = DirectoryFilterProxyModel()
|
|
self.directory_model.setSourceModel(self.tree_model)
|
|
self.file_tree.setModel(self.directory_model)
|
|
self.file_tree.setRootIndex(self.directory_model.mapFromSource(self.tree_model.index(path)))
|
|
self.list_model = QFileSystemModel()
|
|
self.list_model.setRootPath(path)
|
|
self.file_filter_model = FileFilterProxyModel()
|
|
self.file_filter_model.setSourceModel(self.list_model)
|
|
self.folder_contents_view.setModel(self.file_filter_model)
|
|
self.folder_contents_view.setRootIndex(self.file_filter_model.mapFromSource(self.list_model.index(path)))
|
|
self.current_dir_label.setText(path)
|
|
except Exception as e:
|
|
print(f"Error Populating File Tree: {e}")
|
|
|
|
def closeEvent(self, event):
|
|
reply = QMessageBox.question(self, 'Exit', 'Are you sure you want to exit?',
|
|
QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
|
|
if reply == QMessageBox.Yes:
|
|
event.accept()
|
|
else:
|
|
event.ignore()
|
|
|
|
def play_file(self, index):
|
|
try:
|
|
index = self.file_filter_model.mapToSource(index)
|
|
file_path = self.list_model.filePath(index)
|
|
if file_path.endswith(('.zip', '.rar', '.7z')):
|
|
with zipfile.ZipFile(file_path, 'r') as zip_ref:
|
|
for filename in zip_ref.namelist():
|
|
if filename.lower().endswith(('mp3', 'wav', 'ogg', 'flac',
|
|
'm4a', 'wma', 'aac', 'aiff', 'alac',
|
|
'mid', 'midi', 'mp4', 'm4a')):
|
|
audo_file = zip_ref.extract(filename)
|
|
media = QMediaContent(QUrl.fromLocalFile(audo_file))
|
|
self.playlist.clear()
|
|
self.playlist.addMedia(media)
|
|
self.player.play()
|
|
break
|
|
if os.path.exists(audo_file):
|
|
os.remove(audo_file)
|
|
|
|
elif file_path.endswith(('.mid', '.midi')):
|
|
#self.midi_player = MidPlay()
|
|
#fig = self.midi_player.play_midi(file_path)
|
|
self.canvas.draw()
|
|
|
|
else:
|
|
media = QMediaContent(QUrl.fromLocalFile(file_path))
|
|
self.playlist.clear()
|
|
self.playlist.addMedia(media)
|
|
self.player.play()
|
|
except Exception as e:
|
|
print(f"Error Playing File: {e}")
|
|
|
|
def player_state_changed(self, state):
|
|
if state == QMediaPlayer.StoppedState:
|
|
self.playlist.setCurrentIndex(0)
|
|
|
|
def player_position_changed(self, position):
|
|
pass
|
|
def player_duration_changed(self, duration):
|
|
pass
|
|
def playlist_current_index_changed(self, index):
|
|
pass
|
|
def playlist_current_media_changed(self, media):
|
|
pass
|
|
def playlist_media_inserted(self, start, end):
|
|
pass
|
|
def playlist_media_removed(self, start, end):
|
|
pass
|
|
|
|
def change_directory(self, index):
|
|
index = self.directory_model.mapToSource(index)
|
|
try:
|
|
file_path = self.tree_model.filePath(index)
|
|
self.list_model.setRootPath(file_path)
|
|
self.current_dir_label.setText(file_path)
|
|
self.folder_contents_view.setRootIndex(self.file_filter_model.mapFromSource(self.list_model.index(file_path)))
|
|
except Exception as e:
|
|
print(f"Error Changing Dirs.: {e}")
|
|
|
|
def go_up_directory(self):
|
|
index = self.folder_contents_view.rootIndex()
|
|
index = self.file_filter_model.mapToSource(index)
|
|
parent_index = index.parent()
|
|
if parent_index.isValid(): # Check if the parent index is valid
|
|
self.folder_contents_view.setRootIndex(self.file_filter_model.mapFromSource(parent_index))
|
|
self.current_dir_label.setText(self.list_model.filePath(parent_index))
|
|
|
|
def go_forward_directory(self):
|
|
index = self.folder_contents_view.rootIndex()
|
|
index = self.file_filter_model.mapToSource(index)
|
|
parent_index = index.parent()
|
|
if parent_index.isValid():
|
|
self.folder_contents_view.setRootIndex(self.file_filter_model.mapFromSource(parent_index))
|
|
self.current_dir_label.setText(self.list_model.filePath(parent_index))
|
|
|
|
|
|
if __name__ == '__main__':
|
|
# player = MidPlay()
|
|
# file_path = list(player.select_file()) # Get the selected file path
|
|
|
|
# viewer = MidViewer()
|
|
|
|
# viewer.read_midi(file_path)
|
|
# viewer.view_midi()
|
|
#viewer.show()
|
|
# viewer.save('test.png')
|
|
# viewer.clear()
|
|
# viewer.close()
|
|
# print(viewer.get_midi_info(file_path)) # Use the file path
|
|
# print(viewer.get_piano_roll(file_path)) # Use the file path
|
|
# print(viewer.get_tempo(file_path)) # Use the file path
|
|
# print(viewer.get_notes(file_path)) # Use the file path
|
|
app = QApplication(sys.argv)
|
|
sampleMusicBrowser = SampleMusicBrowser()
|
|
sampleMusicBrowser.show()
|
|
|
|
|
|
sys.exit(app.exec_()) |