Python Forum
Thread Rating:
  • 1 Vote(s) - 1 Average
  • 1
  • 2
  • 3
  • 4
  • 5
AudioConverter
#1
convert Audio Files (flac, wav, m4a, ogg) in a folder to mp3 or ogg.
used PyQt5 and pydub (requires ffmpeg)
remove entries with 'Delete' Key

Code on Github

Linux App

[Image: 8995542-screenshot.png]

#!/usr/bin/python3
########################################################
from PyQt5.QtCore import (QAbstractListModel, QDir, QFile,
                                                    QModelIndex, Qt, QItemSelectionModel)
from PyQt5.QtWidgets import (QApplication, QGridLayout, QMenu, QAction, 
                                                            QTableWidget, QTableWidgetItem, QWidget, QPushButton, QFileDialog, QMainWindow, 
                                                            QMessageBox, QAbstractItemView, QComboBox, QLabel, QSpacerItem)
from PyQt5.QtGui import QIcon
from PyQt5.Qt import QKeySequence, QSizePolicy
import os, subprocess
import encodings
#import platform ### replace comment for Windows or OSX
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("*.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", "/tmp", 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_())
Reply
#2
(Dec-27-2019, 08:50 PM)Barbarita Wrote: Here is free audio to text converter https://audext.com/ It's most comfortable to use it instead of making your own. 1-hour-speech can be recognized just in 10 minutes.

Does this have anything to do with python or is it just spam?
Reply
#3
LOL
Reply
#4
* Skaperen whispers: i see spam people
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020