Я пытаюсь использовать Python + ffmpeg + oggenc для преобразования любого аудиофайла в ogg. Работы программы, почти. Но для больших файлов (я думаю> ~6mb) процесс ffmpeg начинает спать в pipe_wait. Я не знаю, какого канала это ожидает.
Если я уничтожаю процесс ffmpeg, процесс oggenc продолжается, и я получаю получающийся ogg-файл с приблизительно ~2:40 всего звука.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from subprocess import Popen, PIPE
from sys import argv
ffmpeg = Popen([
"ffmpeg",
"-i", argv[1],
"-vcodec", "null",
"-acodec", "pcm_s16le",
"-ac", "2",
"-ab", "44100",
"-f", "wav",
"-"
],stdout = PIPE,stderr = PIPE)
oggenc = Popen([
"oggenc",
"-", "--raw",
"-q", "4",
"-o", argv[2]
],stdin = ffmpeg.stdout,stderr = PIPE)
oggenc.communicate()
ffmpeg.communicate()
Править:
Мысль я мог бы добавить, что это работает отлично:
#!/bin/bash
ffmpeg -i "$1" -vcodec null -acodec pcm_s16le -ac 2 -ab 44100 -f wav - | oggenc - --raw -q 4 -o "$2"
Что именно вы делаете с каналами stderr
из двух каналов?
Кодеры / декодеры обычно производят много вывода stderr в виде обновлений статуса; этот вывод передается в ваш процесс, и буферы заполняются. Возможно, вам стоит добавить фиктивный вызов ffmpeg.stderr.read ()
перед (бесполезным, я думаю) вызовом .communicate
или, что еще лучше, отбросить вызов stderr = PIPE
аргументы полностью.
Для эквивалента > / dev / null
выполните следующие действия:
nulfp = open(os.devnull, "w")
…
… = subprocess.Popen(…, stderr=nulfp.fileno())
Очевидно, вы можете повторно использовать тот же nulfp
для всех stderr
, которые вы хотите игнорировать.
Сложно понять, кому нужно передать трубу, то есть вам следует использовать отладчик, подобный тому, что есть в NetBeans, чтобы получить больше подсказок. Труба может быть не лучшим подходом, возможно, использование временного файла упростит ситуацию.