Почему продолжительность mp3/wav отличается при преобразовании массива numpy с помощью ffmpeg в аудиофайл (python)?
Я хочу преобразовать массив numpy, который должен содержать 60 необработанных аудиофайлов в файлы.wav и.mp3. С помощью ffmpeg (версия 3.4.6) я пытаюсь преобразовать массив в нужные форматы. Для сравнения я также использую модульный звуковой файл. Только.wav-файл, созданный звуковым файлом, имеет ожидаемую длину точных 60 секунд..Wav-файл, созданный ffmpeg, немного короче, а.mp3-файл - приблизительно. 32 сек.
Я хочу, чтобы все экспортные файлы были одинаковой длины. Что я делаю не так?
Вот пример кода:
import subprocess as sp
import numpy as np
import soundfile as sf
def data2audiofile(filename,data):
out_cmds = ['ffmpeg',
'-f', 'f64le', # input 64bit float little endian
'-ar', '44100', # inpt samplerate 44100 Hz
'-ac','1', # input 1 channel (mono)
'-i', '-', # inputfile via pipe
'-y', # overwrite outputfile if it already exists
filename]
pipe = sp.Popen(out_cmds, stdin=sp.PIPE, stdout=sp.PIPE, stderr=sp.PIPE)
pipe.stdin.write(data)
data = (np.random.randint(low=-32000, high=32000, size=44100*60)/32678).astype('<f8')
data2audiofile('ffmpeg_mp3.mp3',data)
data2audiofile('ffmpeg_wav.wav',data)
sf.write('sf_wav.wav',data,44100)
Вот получившиеся файлы наглядно отображаются:
1 ответ
Вам нужно закрыть pipe.stdin
и дождитесь завершения подпроцесса.
Закрытие pipe.stdin
смывается stdin
труба.
Здесь объясняется тема: Запись в канал подпроцесса python:
Ключ, чтобы закрыть стандартный ввод (очистить и отправить EOF) перед вызовом
wait
Добавьте следующие строки кода после pipe.stdin.write(data)
:
pipe.stdin.close()
pipe.wait()
Вы также можете попробовать установить большой размер буфера в sp.Popen
:
pipe = sp.Popen(out_cmds, stdin=sp.PIPE, stdout=sp.PIPE, stderr=sp.PIPE, bufsize=10**8)