1

我想将一个应该包含 60s 原始音频的 numpy 数组转换为 .wav 和 .mp3 文件。使用 ffmpeg(版本 3.4.6)我尝试将数组转换为所需的格式。为了比较,我还使用了 modul soundfile。只有 soundfile 创建的 .wav 文件的预期长度正好为 60 秒。ffmpeg 创建的 .wav 文件要短一些,而 .mp3 文件大约是 ca。32s 长。

我希望所有导出的长度相同。我做错了什么?

这是一个示例代码:

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)

这里的结果文件以大胆的方式显示:

4

1 回答 1

2

您需要关闭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)
于 2020-02-03T22:15:11.127 回答