简体   繁体   English

无法弄清楚为什么 PyDub 不起作用

[英]Can't figure out why PyDub is not working

I'm trying to use pydub for a music project, but when trying to play sounds with this chunk of code我正在尝试将 pydub 用于音乐项目,但是在尝试使用这段代码播放声音时

from pydub import AudioSegment
from pydub.playback import play
sound = AudioSegment.from_wav("s1.wav")
play(sound)

i get the following error:我收到以下错误:

RuntimeWarning: Couldn't find ffmpeg or avconv - defaulting to ffmpeg, but may not work
  warn("Couldn't find ffmpeg or avconv - defaulting to ffmpeg, but may not work", RuntimeWarning)
C:\Python\Python385\lib\site-packages\pydub\utils.py:184: RuntimeWarning: Couldn't find ffplay or avplay - defaulting to ffplay, but may not work
  warn("Couldn't find ffplay or avplay - defaulting to ffplay, but may not work", RuntimeWarning)
Traceback (most recent call last):
  File "C:/Users/vicen/Desktop/music project/mian.py", line 6, in <module>
    play(s1)
  File "C:\Python\Python385\lib\site-packages\pydub\playback.py", line 74, in play
    _play_with_ffplay(audio_segment)
  File "C:\Python\Python385\lib\site-packages\pydub\playback.py", line 18, in _play_with_ffplay
    seg.export(f.name, "wav")
  File "C:\Python\Python385\lib\site-packages\pydub\audio_segment.py", line 809, in export
    out_f, _ = _fd_or_path_or_tempfile(out_f, 'wb+')
  File "C:\Python\Python385\lib\site-packages\pydub\utils.py", line 60, in _fd_or_path_or_tempfile
    fd = open(fd, mode=mode)
PermissionError: [Errno 13] Permission denied: 'C:\\Users\\vicen\\AppData\\Local\\Temp\\tmpvwotqts5.wav'

Does someone understand why it isn't working?有人明白为什么它不起作用吗? I am fairly new to python so i don't.我对 python 相当陌生,所以我不知道。

The python script encountered a Permission Error It is trying to read 'C:\\Users\\vicen\\AppData\\Local\\Temp\\tmpvwotqts5.wav' file but doesn't have permission to write in the directory. python 脚本遇到Permission Error它正在尝试读取'C:\\Users\\vicen\\AppData\\Local\\Temp\\tmpvwotqts5.wav'文件,但没有在目录中写入的权限。

Changing permissions on the above mentioned Temp folder should solve the problem.更改上述临时文件夹的权限应该可以解决问题。

Or you could run your python script using sudo command.或者您可以使用sudo命令运行 python 脚本。 Since you are using windows this should help in this regard.由于您使用的是 windows 在这方面应该有所帮助。

Easy Fix from here : 从这里轻松修复:

pip install simpleaudio

Pydub uses tempfiles extensively.As suggested here you can add TMPDIR environment variable. Pydub广泛使用临时文件。如此处建议您可以添加TMPDIR环境变量。

the problem is with the tempfile, as mentioned here问题出在临时文件上,如此所述
so the file playback.py , which is one of the files of this pydub module (you may find it at Python\Python-version-\Lib\site-packages\pydub ), must be modified.所以文件playback.py ,它是这个pydub模块的文件之一(你可以在Python\Python-version-\Lib\site-packages\pydub找到它),必须被修改。
there are two recommended methods to solve this,有两种推荐的方法来解决这个问题,

  1. mentioned here 这里提到

  2. create a custom tempfile like below at playback.pyplayback.py中创建一个自定义临时文件,如下所示

` `

import subprocess
from tempfile import NamedTemporaryFile
from .utils import get_player_name, make_chunks
import random
import os
import tempfile


class CustomNamedTemporaryFile:
    """
    This custom implementation is needed because of the following limitation of tempfile.NamedTemporaryFile:

    > Whether the name can be used to open the file a second time, while the named temporary file is still open,
    > varies across platforms (it can be so used on Unix; it cannot on Windows NT or later).
    """
    def __init__(self, mode='wb', delete=True, suffix = ''):
        self._mode = mode
        self._delete = delete
        self.suffix = suffix

    def __enter__(self):
        # Generate a random temporary file name
        file_name = os.path.join(tempfile.gettempdir(), os.urandom(24).hex())
        # Ensure the file is created
        open(file_name+self.suffix, "x").close()
        # Open the file in the given mode
        self._tempFile = open(file_name+self.suffix, self._mode)
        return self._tempFile

    def __exit__(self, exc_type, exc_val, exc_tb):
        self._tempFile.close()
        if self._delete:
            os.remove(self._tempFile.name)
            
def _play_with_ffplay(seg):
    PLAYER = get_player_name()
    # with NamedTemporaryFile("w+b", suffix=".wav") as f:
    with CustomNamedTemporaryFile(mode='wb', suffix = ".wav") as f:
        seg.export(f.name, "wav")
        subprocess.call([PLAYER, "-nodisp", "-autoexit", "-hide_banner", f.name])

' '

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM