Last active
May 30, 2021 16:11
-
-
Save Axel-Erfurt/df4d8f75b2872354c6bffd7c2ce6ae97 to your computer and use it in GitHub Desktop.
AudioConverter
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
#!/usr/bin/python3 | |
# -*- coding: utf-8 -*- | |
######################################################## | |
from PyQt5.QtCore import (QDir, Qt) | |
from PyQt5.QtWidgets import (QApplication, QGridLayout, | |
QTableWidget, QTableWidgetItem, QWidget, QPushButton, QFileDialog, | |
QMainWindow, QMessageBox, QAbstractItemView, QComboBox, QLabel) | |
from PyQt5.QtGui import QIcon | |
import os, subprocess | |
import pydub | |
class Window(QMainWindow): | |
def __init__(self, parent=None): | |
super(Window, self).__init__(parent) | |
self.songlist = [] | |
self.infolder = "" | |
self.outfolder = "" | |
self.setStyleSheet(myStyleSheet(self)) | |
### buttons & combo boxes | |
btnLoad = QPushButton("select Folder") | |
btnLoad.setIcon(QIcon.fromTheme("folder")) | |
btnLoad.setFixedWidth(130) | |
btnLoad.clicked.connect(self.loadDir) | |
btn_mp3 = QPushButton("convert to mp3") | |
btn_mp3.setIcon(QIcon.fromTheme("audio-x-generic")) | |
# btn_mp3.setFixedWidth(130) | |
btn_mp3.clicked.connect(self.make_mp3) | |
btn_ogg = QPushButton("convert to ogg") | |
btn_ogg.setIcon(QIcon.fromTheme("audio-x-generic")) | |
# btn_ogg.setFixedWidth(130) | |
btn_ogg.clicked.connect(self.make_ogg) | |
self.comboBitrate_mp3 = QComboBox() | |
self.comboBitrate_mp3.setFixedWidth(130) | |
self.comboBitrate_mp3.addItem("96") | |
self.comboBitrate_mp3.addItem("128") | |
self.comboBitrate_mp3.addItem("192") | |
self.comboBitrate_mp3.addItem("256") | |
self.comboBitrate_mp3.addItem("320") | |
self.comboBitrate_ogg = QComboBox() | |
self.comboBitrate_ogg.setFixedWidth(130) | |
self.comboBitrate_ogg.addItem("45") | |
self.comboBitrate_ogg.addItem("64") | |
self.comboBitrate_ogg.addItem("80") | |
self.comboBitrate_ogg.addItem("96") | |
self.comboBitrate_ogg.addItem("112") | |
self.comboBitrate_ogg.addItem("128") | |
self.comboBitrate_ogg.addItem("192") | |
lbl_mp3 = QLabel("kBit/s") | |
lbl_mp3.setFixedWidth(44) | |
lbl_ogg = QLabel("kBit/s") | |
lbl_ogg.setFixedWidth(44) | |
self.view = QTableWidget() | |
self.view.setToolTip("delete entry with 'delete' key") | |
self.view.setSelectionBehavior(QAbstractItemView.SelectRows) | |
self.view.setSelectionMode(QAbstractItemView.SingleSelection) | |
self.view.setEditTriggers(QAbstractItemView.NoEditTriggers) | |
self.view.verticalHeader().setVisible(False) | |
self.view.horizontalHeader().setVisible(False) | |
self.view.horizontalHeader().setStretchLastSection(True) | |
self.view.setColumnCount(1) | |
### layout | |
layout = QGridLayout() | |
layout.addWidget(self.view, 0, 0, 1, 6) | |
layout.addWidget(btnLoad, 1, 0) | |
layout.addWidget(self.comboBitrate_mp3, 1, 1) | |
layout.addWidget(lbl_mp3, 1, 2) | |
layout.addWidget(self.comboBitrate_ogg, 1, 3) | |
layout.addWidget(lbl_ogg, 1, 4) | |
layout.addWidget(btn_mp3, 2, 1) | |
layout.addWidget(btn_ogg, 2, 3) | |
myWidget = QWidget() | |
myWidget.setLayout(layout) | |
self.setCentralWidget(myWidget) | |
self.setWindowTitle("Audio Converter * convert to mp3 or ogg") | |
self.setWindowIcon(QIcon.fromTheme("audio-x-generic")) | |
self.setMinimumSize(520, 200) | |
self.setGeometry(0,0,550,400) | |
self.createStatusBar() | |
self.view.setFocus() | |
self.comboBitrate_mp3.setCurrentIndex(2) | |
self.comboBitrate_ogg.setCurrentIndex(3) | |
def keyPressEvent(self, event): | |
self.view.setFocus() | |
print(event.key()) | |
if event.key() == Qt.Key_Delete: | |
self.deleteSelectedRow() | |
else: | |
event.accept() | |
def deleteSelectedRow(self): | |
row = self.selectedRow() | |
self.view.removeRow(row) | |
del self.songlist[row] | |
print("Row " + str(row) + " deleted") | |
self.view.selectRow(row) | |
def check_ffmpeg(self, name): | |
try: | |
devnull = open(os.devnull) | |
subprocess.Popen([name], stdout=devnull, stderr=devnull).communicate() | |
except OSError as e: | |
if e.errno == os.errno.ENOENT: | |
return False | |
return True | |
def make_ogg(self): | |
if self.songlist == []: | |
QMessageBox.warning(self, "Error", "no files in list!") | |
else: | |
quality = self.comboBitrate_ogg.currentText() | |
dir = QDir(self.infolder) | |
print(dir.absolutePath()) | |
if dir.mkpath("ogg_" + quality): | |
self.outfolder = self.infolder + "/ogg_" + quality | |
print("%s%s%s" % ("dir ", "ogg_" + quality, " created")) | |
i = 0 | |
self.view.selectRow(i) | |
if self.songlist == []: | |
QMessageBox.warning(self, "Error", "no files in list!") | |
else: | |
for song in self.songlist: | |
base=os.path.basename(self.infolder + song) | |
oldsong = os.path.splitext(base)[0] | |
targetsong = self.infolder + song | |
newsong = self.outfolder + "/" + oldsong + ".ogg" | |
self.statusBar().showMessage("converting " + song, 0 ) | |
sound = pydub.AudioSegment.from_file(targetsong) | |
sound.export(newsong, "ogg", codec="libvorbis", parameters=["-aq", "0", "-ar", quality + "000"]) | |
i = i + 1 | |
self.view.selectRow(i) | |
self.statusBar().showMessage("Finished!", 0) | |
self.open_folder(self.outfolder) | |
else: | |
print("%s%s%s" % ("cannot create", "dir", self.outfolder)) | |
def make_mp3(self): | |
if self.songlist == []: | |
QMessageBox.warning(self, "Error", "no files in list!") | |
else: | |
dir = QDir(self.infolder) | |
print(dir.absolutePath()) | |
if dir.mkpath("mp3_" + self.comboBitrate_mp3.currentText()): | |
self.outfolder = self.infolder + "/mp3_" + self.comboBitrate_mp3.currentText() | |
print("%s%s%s" % ("dir ", "mp3_" + self.comboBitrate_mp3.currentText(), " created")) | |
i = 0 | |
self.view.selectRow(i) | |
if self.songlist == []: | |
QMessageBox.warning(self, "Error", "no files in list!") | |
else: | |
for song in self.songlist: | |
base=os.path.basename(self.infolder + song) | |
oldsong = os.path.splitext(base)[0] | |
targetsong = self.infolder + song | |
newsong = self.outfolder + "/" + oldsong + ".mp3" | |
self.statusBar().showMessage("converting " + song, 0 ) | |
sound = pydub.AudioSegment.from_file(targetsong) | |
sound.export(newsong, format="mp3", bitrate=self.comboBitrate_mp3.currentText()) | |
i = i + 1 | |
self.view.selectRow(i) | |
self.statusBar().showMessage("Finished!", 0) | |
self.open_folder(self.outfolder) | |
else: | |
print("%s%s%s" % ("cannot create", "dir", self.outfolder)) | |
### replace comments for Windows or OSX | |
def open_folder(self, path): | |
# if platform.system() == "Windows": | |
# os.startfile(path) | |
# elif platform.system() == "Darwin": | |
# subprocess.Popen(["open", path]) | |
# else: | |
subprocess.Popen(["xdg-open", path]) | |
def fillTable(self, path): | |
self.view.clear() | |
self.dir = QDir(path) | |
self.infolder = path + "/" | |
mlist = [] | |
mlist.append("*.flac") | |
mlist.append("*.wav") | |
mlist.append("*.m4a") | |
mlist.append("*.ogg") | |
mlist.append("*.mp3") | |
mlist.append("*.mp4") | |
self.fileList = self.dir.entryList(mlist, QDir.Files, QDir.IgnoreCase) | |
for f in self.fileList: | |
self.view.insertRow(self.view.rowCount()) | |
mf = QTableWidgetItem(str(f)) | |
self.view.setItem(self.view.rowCount() - 1, 0, mf) | |
self.songlist.append(f) | |
self.view.resizeRowsToContents() | |
if self.view.rowCount() > 0: | |
self.updateStatus(self.view.rowCount()) | |
def selectedRow(self): | |
if self.view.selectionModel().hasSelection(): | |
row = self.view.selectionModel().selectedIndexes()[0].row() | |
return int(row) | |
def selectFirstRow(self): | |
self.view.selectRow(0) | |
def loadDir(self): | |
dlg = QFileDialog() | |
dlg.setFileMode(QFileDialog.Directory) | |
fileName = dlg.getExistingDirectory(self, "select Directory", "", QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks) | |
if fileName: | |
self.infolder = fileName | |
self.fillTable(fileName) | |
def updateStatus(self, number): | |
self.statusBar().showMessage("loaded %d files" % number) | |
self.selectFirstRow() | |
def createStatusBar(self): | |
self.statusBar().showMessage("Welcome to Audio Converter Linux", 0) | |
def msgbox(self, message): | |
QMessageBox.warning(self, "Message", message) | |
def closeEvent(self, event): | |
return | |
def handleQuit(self): | |
quit() | |
def myStyleSheet(self): | |
return """ | |
QTableWidget | |
{ | |
border: 1px solid #d3d7cf; | |
border-radius: 0px; | |
font-family: Noto Sans; | |
font-size: 9pt; | |
font-weight: bold; | |
background-color: #eeeeec; | |
color: #555753; | |
selection-color: #ffffff | |
} | |
QTableWidget::item:hover | |
{ | |
color: #2e3436; | |
background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #cfbb72, stop:1 #d3d7cf); | |
} | |
QTableWidget::item:selected | |
{ | |
color: #ffffff; | |
background: qlineargradient(x1:0, y1:0, x1:2, y1:2, stop:0 #204a87, stop:1 #729fcf); | |
} | |
QStatusBar | |
{ | |
height: 20px; | |
font-size: 8pt; | |
font-weight: bold; | |
color: #324864; | |
} | |
""" | |
if __name__ == '__main__': | |
import sys | |
app = QApplication(sys.argv) | |
window = Window() | |
window.show() | |
if window.check_ffmpeg("ffmpeg") == False: | |
QMessageBox.warning(window, "Error", "<b>ffmpeg not found</b><br><br><i>Please install ffmpeg</i>") | |
window.handleQuit() | |
else: | |
window.statusBar().showMessage("Welcome to AudioConverterLinux *** found ffmpeg", 0) | |
sys.exit(app.exec_()) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
convert all Audio Files (flac, wav, m4a, ogg, mp3, mp4) in a folder to mp3 or ogg.
used PyQt5 and pydub (requires ffmpeg)
remove entries with 'Delete' Key