PythonQMediaPlayer发布资源

2024-09-28 20:59:30 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一些代码:

  1. 使用pyqt5音频输入从麦克风录制

  2. 使用pydub AudioSegment写入文件record.mp3

  3. 使用以下代码预览record.mp3:

    def preview_record(self,ui): filename = self.record_path #filename = filename.replace(" ","+") url = QtCore.QUrl.fromLocalFile(r""+filename) content = QtMultimedia.QMediaContent(url) self.player = QtMultimedia.QMediaPlayer() self.player.setMedia(content) self.player.play()

问题是,如果预览录制的文件,然后录制新文件,则在步骤2中):

PermissionError: [Errno 13] Permission denied: '../disket box/weather news/record.mp3'

这是因为资源是为预览而打开的。 如何释放资源以解决问题

编辑:重现问题的示例:

from PyQt5 import QtCore, QtGui, QtWidgets, QtMultimedia
from PyQt5.QtCore import QDate, QTime,QTimer, QDateTime, Qt
from pydub import AudioSegment
from datetime import datetime
import vlc
import ctypes
import os
from pathlib import Path
import shutil
from PyQt5 import QtCore, QtGui, QtWidgets, QtMultimedia
import time
import moviepy.editor
import moviepy.video.fx.all as vfx
from pydub import AudioSegment

class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(400, 300)
        self.record = QtWidgets.QPushButton(Form)
        self.record.setGeometry(QtCore.QRect(110, 30, 161, 61))
        self.record.setObjectName("record")
        self.stop = QtWidgets.QPushButton(Form)
        self.stop.setGeometry(QtCore.QRect(110, 140, 161, 61))
        self.stop.setObjectName("stop")
        self.preview = QtWidgets.QPushButton(Form)
        self.preview.setGeometry(QtCore.QRect(120, 250, 151, 81))
        self.preview.setObjectName("preview")

        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)
        
        self.destinationFile = QtCore.QFile()
        
        self.record.clicked.connect(lambda state:self.start_recording())
        self.stop.clicked.connect(lambda state:self.stop_recording())
        self.preview.clicked.connect(lambda state:self.preview_record())

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "StackOverflow example"))
        self.record.setText(_translate("Form", "Record"))
        self.stop.setText(_translate("Form", "Stop"))
        self.preview.setText(_translate("Form", "Preview"))
        
    def start_recording(self):
        self.destinationFile.setFileName("record.raw")
        self.destinationFile.open( QtCore.QIODevice.ReadWrite | QtCore.QIODevice.Truncate )
        
        info = QtMultimedia.QAudioDeviceInfo.defaultInputDevice()

        format = QtMultimedia.QAudioFormat()
        format.setSampleRate(44100);
        format.setChannelCount(1);
        format.setSampleSize(16);
        format.setCodec("audio/pcm");
        format.setByteOrder(QtMultimedia.QAudioFormat.LittleEndian)
        format.setSampleType(QtMultimedia.QAudioFormat.SignedInt)

        
        
        input_devices = QtMultimedia.QAudioDeviceInfo.availableDevices(QtMultimedia.QAudio.AudioInput)
        
        if (info.isFormatSupported(format) is not True):
            format = info.nearestFormat(format)
            print("format changed")

        self.audio = QtMultimedia.QAudioInput(input_devices[0],format)
        self.audio.start(self.destinationFile)
    
    def stop_recording(self):
        self.audio.stop()
        self.destinationFile.close()
        raw_audio = AudioSegment.from_file("record.raw", format="raw",frame_rate=44100, channels=1, sample_width=2)
        raw_audio.export("record.mp3", format="mp3")

        
        self.record_path = os.path.abspath("record.mp3")
        
    def preview_record(self):
        filename = self.record_path
        url = QtCore.QUrl.fromLocalFile(r""+filename)
        content = QtMultimedia.QMediaContent(url)
        self.player = QtMultimedia.QMediaPlayer()
        self.player.setMedia(content)
        self.player.play()


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")
    Form = QtWidgets.QWidget()
    ui = Ui_Form()
    ui.setupUi(Form)
    Form.showMaximized()
    sys.exit(app.exec_())

要复制它,请执行以下步骤:

  1. 按录制按钮开始录制
  2. 按停止按钮停止录制
  3. 按预览按钮预览录制(并等待预览完成)
  4. 再次按“录制”按钮可获得新的录制
  5. 按停止按钮停止新录制

错误是:

Traceback (most recent call last):
  File "stack_record.py", line 36, in <lambda>
    self.stop.clicked.connect(lambda state:self.stop_recording())
  File "stack_record.py", line 75, in stop_recording
    raw_audio.export("record.mp3", format="mp3")
  File "C:\Users\╫±▐≤ΪΎ≥\AppData\Local\Programs\Python\Python38\lib\site-packages\pydub\audio_segment.py", line 809, in export
    out_f, _ = _fd_or_path_or_tempfile(out_f, 'wb+')
  File "C:\Users\╫±▐≤ΪΎ≥\AppData\Local\Programs\Python\Python38\lib\site-packages\pydub\utils.py", line 60, in _fd_or_path_or_tempfile
    fd = open(fd, mode=mode)
PermissionError: [Errno 13] Permission denied: 'record.mp3'

Tags: fromimportselfformformatdeffilenamepreview
1条回答
网友
1楼 · 发布于 2024-09-28 20:59:30
  1. 我使用self.player的stateChanged信号

self.player.stateChanged.connect(lambda state:self.mediastate_changed(state,ui))

  1. 预览完成后,我将删除self.player实例

def mediastate_changed(self, state,ui): if self.player.state() != QtMultimedia.QMediaPlayer.PlayingState: del self.player

相关问题 更多 >