Chris P
Chris P

Reputation: 2357

Record audio using pyqt5

Is there any way to record microphone input in pyqt5?

I try this code:

from PyQt5 import QtCore, QtGui, QtWidgets, QtMultimedia
import time


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):

        self.destinationFile = QtCore.QFile()


        self.destinationFile.setFileName("record.raw")
        self.destinationFile.open( QtCore.QIODevice.WriteOnly | QtCore.QIODevice.Truncate )

        format = QtMultimedia.QAudioFormat()
        format.setSampleRate(8000);
        format.setChannelCount(1);
        format.setSampleSize(8);
        format.setCodec("audio/pcm");
        format.setByteOrder(QtMultimedia.QAudioFormat.LittleEndian)
        format.setSampleType(QtMultimedia.QAudioFormat.UnSignedInt)

        info = QtMultimedia.QAudioDeviceInfo.defaultInputDevice()
        if (info.isFormatSupported(format) is not True):
            format = info.nearestFormat(format)

        self.audio = QtMultimedia.QAudioInput(format)
        self.audio.start(self.destinationFile)

        
        self.timer = QtCore.QTimer(MainWindow)
        self.timer.timeout.connect(lambda:self.close_window(MainWindow))
        self.timer.start(10000)
        
    
    def close_window(self,MainWindow):
        self.audio.stop()
        self.destinationFile.close()
        
        MainWindow.close()
    
if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    app.addLibraryPath(r"C:/Users/Χρήστος/AppData/Local/Programs/Python/Python38/lib/site-packages/PyQt5/Qt/plugins")
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    
    sys.exit(app.exec_())

The above code outputs a file record.raw 80 kB. I cannot hear it. I convert it to mp3 with Switch Audio Converter. The duration is 10 seconds as it supposed to be, but i can hear only noise. Any help please?

Raw output: https://files.fm/u/cv4y8d7h

Mp3 output: https://files.fm/u/68c8zvvc#/view/v2rnbapw

print(info.deviceName()) -->Default Input Device

input_devices = QtMultimedia.QAudioDeviceInfo.availableDevices(QtMultimedia.QAudio.AudioInput)
for input_device in input_devices:
    print(input_device.deviceName())

Μικρόφωνο (Realtek High Definition Audio)

Μικρόφωνο (Realtek High Definition Audio)

(2 times the same microphone input)

Upvotes: 0

Views: 2223

Answers (1)

eyllanesc
eyllanesc

Reputation: 243945

If you want to record audios then you must use QAudioRecorder, in addition to that it is recommended that you review the official examples as Audio Recorder Example (translating them to python is not complicated since the classes are the same), based on that example I have implemented the following example that works for me:

import os
import sys

from PyQt5 import QtCore, QtWidgets, QtMultimedia

CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))

app = QtWidgets.QApplication(sys.argv)

recorder = QtMultimedia.QAudioRecorder()

selected_audio_input = recorder.audioInput()

print("Audio Inputs:")
for i, audio_input in enumerate(recorder.audioInputs()):
    print(f"{i}. {audio_input}")

recorder.setAudioInput(selected_audio_input)

settings = QtMultimedia.QAudioEncoderSettings()

selected_codec = ""
print("Codecs:")
for i, codec in enumerate(recorder.supportedAudioCodecs()):

    print(f"{i}. {codec}")
print(f"selected codec:{selected_codec}")
settings.setCodec(selected_codec)

selected_sample_rate = 0
print("Sample rates:")
sample_rates, continuous = recorder.supportedAudioSampleRates()
for i, sample_rate in enumerate(sample_rates):
    print(f"{i}. {sample_rate}")
settings.setSampleRate(selected_sample_rate)

bit_rate = 0  # other values: 32000, 64000,96000, 128000
settings.setBitRate(bit_rate)

channels = -1  # other values: 1, 2, 4
settings.setChannelCount(channels)
settings.setQuality(QtMultimedia.QMultimedia.NormalQuality)
settings.setEncodingMode(QtMultimedia.QMultimedia.ConstantBitRateEncoding)

print("Containers")
selected_container = ""
for i, container in enumerate(recorder.supportedContainers()):
    print(f"{i}. {container}")

recorder.setEncodingSettings(
    settings, QtMultimedia.QVideoEncoderSettings(), selected_container
)

filename = os.path.join(CURRENT_DIR, "test.mp3")
recorder.setOutputLocation(QtCore.QUrl.fromLocalFile(filename))


def handle_durationChanged(progress):
    print(f"progress: {progress/1000} seg")


def handle_statusChanged(status):
    if status == QtMultimedia.QMediaRecorder.FinalizingStatus:
        QtCore.QTimer.singleShot(1 * 1000, QtCore.QCoreApplication.quit)


recorder.durationChanged.connect(handle_durationChanged)
recorder.statusChanged.connect(handle_statusChanged)


def handle_timeout():
    recorder.stop()


QtCore.QTimer.singleShot(10 * 1000, handle_timeout)

recorder.record()

sys.exit(app.exec_())

On the other hand in windows you need to install the k-lite codecs.

Upvotes: 2

Related Questions