Python Popen: «OSError: [Errno 24] Слишком много открытых файлов» Мохаве - PullRequest
0 голосов
/ 11 октября 2019

Я использую стороннюю библиотеку Pydub в MacOS Mojave, я пытаюсь обработать> 100 тыс. Треков MP3, используя Pydub для ввода-вывода, поэтому эта функция часто вызывается. Оскорбительная функция в Pydub ниже. Я попытался изменить его, поместив Popen в оператор with, как предложено здесь , но я все еще получаю ошибку. Я знаю, что мог бы решить эту проблему, увеличив ulimit, но это кажется неправильным подходом?

Что-то не так с этим кодом?

def mediainfo_json(filepath):
    """Return json dictionary with media info(codec, duration, size, bitrate...) from filepath
    """
    prober = get_prober_name()
    command_args = [
        "-v", "info",
        "-show_format",
        "-show_streams",
    ]
    try:
        command_args += [fsdecode(filepath)]
        stdin_parameter = None
        stdin_data = None
    except TypeError:
        command_args += ["-"]
        stdin_parameter = PIPE
        file = _fd_or_path_or_tempfile(filepath, 'rb', tempfile=False)
        file.seek(0)
        stdin_data = file.read()

    command = [prober, '-of', 'json'] + command_args
    with Popen(command, stdin=stdin_parameter, stdout=PIPE, stderr=PIPE) as res:
        output, stderr = res.communicate(input=stdin_data)
        output = output.decode("utf-8", 'ignore')
        stderr = stderr.decode("utf-8", 'ignore')

    info = json.loads(output)

    if not info:
        # If ffprobe didn't give any information, just return it
        # (for example, because the file doesn't exist)
        return info

    extra_info = get_extra_info(stderr)

    audio_streams = [x for x in info['streams'] if x['codec_type'] == 'audio']
    if len(audio_streams) == 0:
        return info

    # We just operate on the first audio stream in case there are more
    stream = audio_streams[0]

Это актуальночасть трассировки стека:

/usr/local/anaconda3/envs/dl/lib/python3.7/site-packages/pydub/utils.py in mediainfo_json(filepath)
    261 
    262     command = [prober, '-of', 'json'] + command_args
--> 263     with Popen(command, stdin=stdin_parameter, stdout=PIPE, stderr=PIPE) as res:
    264         output, stderr = res.communicate(input=stdin_data)
    265         output = output.decode("utf-8", 'ignore')

/usr/local/anaconda3/envs/dl/lib/python3.7/subprocess.py in __init__(self, args, bufsize, executable, stdin, stdout, stderr, preexec_fn, close_fds, shell, cwd, env, universal_newlines, startupinfo, creationflags, restore_signals, start_new_session, pass_fds, encoding, errors, text)
    773                                 c2pread, c2pwrite,
    774                                 errread, errwrite,
--> 775                                 restore_signals, start_new_session)
    776         except:
    777             # Cleanup if the child failed starting.

/usr/local/anaconda3/envs/dl/lib/python3.7/subprocess.py in _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, start_new_session)
   1410             # Data format: "exception name:hex errno:description"
   1411             # Pickle is not used; it is complex and involves memory allocation.
-> 1412             errpipe_read, errpipe_write = os.pipe()
   1413             # errpipe_write must not be in the standard io 0, 1, or 2 fd range.
   1414             low_fds_to_close = []

OSError: [Errno 24] Too many open files
...