Search code examples
pythonpysidepyside6

How do I record an audio track of unlimited length and save it to a file?


How do I record an unlimited length audio track and save it to a PySide/PyQt file?

I need to record an unlimited length audio track in PySide. In future, recording will stop by pressing the button. I tried running the code from the official documentation QMediaRecorder.

from PySide6.QtCore import QUrl, QDir
from PySide6.QtMultimedia import QMediaCaptureSession, QAudioInput, QMediaRecorder, QMediaFormat

session = QMediaCaptureSession()
audioInput = QAudioInput()
session.setAudioInput(audioInput)
recorder = QMediaRecorder()
session.setRecorder(recorder)
recorder.setMediaFormat(QMediaFormat.MP3)
recorder.setQuality(QMediaRecorder.HighQuality)
file_location = QUrl(QDir.currentPath() + '/test.mp3')
recorder.setOutputLocation(file_location)
recorder.record()

The program runs for about 2-3 seconds, after which it terminates with code 0. The file does not appear in the current directory. I was trying to run this on Windows.


Solution

  • You have to run your script in a Qt eventloop:

    import os
    from pathlib import Path
    
    from PySide6.QtCore import QDir, QUrl 
    from PySide6.QtMultimedia import (
        QMediaCaptureSession,
        QAudioInput,
        QMediaRecorder,
        QMediaFormat,
    )
    from PySide6.QtWidgets import QApplication, QPushButton
    
    
    def main():
        app = QApplication([])
    
        session = QMediaCaptureSession()
        audioInput = QAudioInput()
        session.setAudioInput(audioInput)
        recorder = QMediaRecorder()
        session.setRecorder(recorder)
        recorder.setMediaFormat(QMediaFormat.MP3)
        recorder.setQuality(QMediaRecorder.HighQuality)
        filename = Path(QDir.currentPath()) / "test.mp3"
        url = QUrl.fromLocalFile(os.fspath(filename))
        recorder.setOutputLocation(url)
        recorder.record()
    
        button = QPushButton("Stop")
        button.show()
        button.clicked.connect(recorder.stop)
    
        app.exec()
    
    
    if __name__ == "__main__":
        main()