简体   繁体   English

当我使用 ffmpeg 将 numpy 数组转换为音频文件 (python) 时,为什么 mp3/wav 持续时间不同?

[英]Why is mp3/wav duration different when I convert a numpy array with ffmpeg into audiofile (python)?

I want to convert a numpy array which should contain 60s of raw audio into .wav and .mp3 file.我想将一个包含 60 秒原始音频的 numpy 数组转换为 .wav 和 .mp3 文件。 With ffmpeg (version 3.4.6) I try to convert the array to the desired formats.使用 ffmpeg(版本 3.4.6),我尝试将数组转换为所需的格式。 For comparison I also use the modul soundfile.为了进行比较,我还使用了模块声音文件。 Only the .wav-file created by soundfile has the expected length of exact 60s.只有 soundfile 创建的 .wav 文件的预期长度为 60 秒。 The .wav-file created by ffmpeg is a little shorter and the .mp3-file is ca.由 ffmpeg 创建的 .wav 文件有点短,而 .mp3 文件则是 ca。 32s long. 32 秒长。

I want all exports to be the same length.What am I doing wrong?我希望所有出口的长度相同。我做错了什么?

Here is a sample code:这是一个示例代码:

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)

Here the resulting files displayed in audacity:这里以audacity显示的结果文件:

You need to close pipe.stdin and wait for the sub-process to end.您需要关闭pipe.stdin并等待子进程结束。

Closing pipe.stdin flushes stdin pipe.关闭pipe.stdin刷新stdin管道。
The subject is explained here: Writing to a python subprocess pipe :此处解释了该主题:写入 python 子进程管道

The key it to close stdin (flush and send EOF) before calling wait在调用wait之前关闭stdin(刷新并发送EOF)的关键

Add the following code lines after pipe.stdin.write(data) :pipe.stdin.write(data)之后添加以下代码行:

pipe.stdin.close()
pipe.wait()

You can also try setting a large buffer size in sp.Popen :您还可以尝试在sp.Popen设置大缓冲区大小:

pipe = sp.Popen(out_cmds, stdin=sp.PIPE, stdout=sp.PIPE, stderr=sp.PIPE, bufsize=10**8)

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

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