如何在ffmpeg中使用字节而不是文件路径?

Posted

技术标签:

【中文标题】如何在ffmpeg中使用字节而不是文件路径?【英文标题】:How to use bytes instead of file path in ffmpeg? 【发布时间】:2021-04-03 12:44:13 【问题描述】:

我有一个函数,它当前接收字节,将其保存到磁盘上的音频 WEBM 文件,然后将其转换为磁盘上的另一个音频 WAV 文件。

我正在寻找一种在不将 WEBM 文件保存到磁盘的情况下使用 FFMPEG 进行上述转换的方法。

FFMPEG 能否使用内存中的字节而不是磁盘中文件的路径来处理此类转换?

我现在在做什么(Python 3.8.8 64Bit):

# audio_data = bytes received

def save_to_webm(audio_data, username):
    mainDir = os.path.dirname(__file__)
    tempDir = os.path.join(mainDir, 'temp')
    webm_path = os.path.join(tempDir, f'username.webm')
    with open(webm_path, 'wb') as f:
        f.write(audio_data)
    return webm_path

# webm_path = input path in FFMPEG

def convert_webm_to_wav(webm_path, username):
    mainDir = os.path.dirname(__file__)
    tempDir = os.path.join(mainDir, 'temp')
    outputPath = os.path.join(tempDir, f'username.wav')

    if platform == 'win32':
        ffmpeg_path = os.path.join(mainDir, 'ffmpeg.exe')
    else:
        os.chdir("/ffmpeg")
        ffmpeg_path = './ffmpeg'

    command = [ffmpeg_path, '-i', webm_path, '-acodec', 'pcm_s16le', '-ar', '11025', '-ac', '1', '-y', outputPath]
    subprocess.run(command,stdout=subprocess.PIPE,stdin=subprocess.PIPE)
    return outputPath

【问题讨论】:

【参考方案1】:

您可以通过使用- 作为文件名轻松地让ffmpeg 从标准输入中读取字节;但是您可能希望它与读取它们的进程并行运行,而不是将它们全部读入内存然后开始转换。

但是对于一个快速的原型,也许可以尝试这样的事情:

def convert_webm_save_to_wav(audio_data, username):
    mainDir = os.path.dirname(__file__)
    tempDir = os.path.join(mainDir, 'temp')
    wav_path = os.path.join(tempDir, f'username.wav')

    if platform == 'win32':
        ffmpeg_path = os.path.join(mainDir, 'ffmpeg.exe')
    else:
        # Almost certainly should not need to os.chdir here
        ffmpeg_path = '/ffmpeg/ffmpeg'

    command = [ffmpeg_path, '-i', '-', '-acodec', 'pcm_s16le',
               '-ar', '11025', '-ac', '1', '-y', wav_path]
    subprocess.run(command, input=audio_data)

    return wav_path

在脚本目录中创建临时目录的约定是可疑的;您可能应该改用 Python 的 tempfile 模块,或者让调用用户指定他们想要文件的位置。

【讨论】:

raise ValueError('stdin and input arguments may not be used.') ValueError: stdin and input arguments may not be used.你能帮忙吗?我做了你做的事 很抱歉;也删除了 stdin= 关键字参数。 有没有我可以用 Java 做同样的事情? 我相信你可以,但我对 Java 一无所知。提出一个新问题(但首先检查是否有重复问题,并可能链接到这个问题以获取上下文)。 我已经问过了,但没有人回答,我也在努力寻找 Java 中存在的相同问题

以上是关于如何在ffmpeg中使用字节而不是文件路径?的主要内容,如果未能解决你的问题,请参考以下文章

如何通过传递文件对象(而不是磁盘上文件的位置)将 ffmpeg 与 Python 一起使用

ffmpeg如何获取播放文件总的时间

ffmpeg 可以从文件中的特定位置解析吗?

如何解决“迭代器应该返回字符串,而不是字节”

您如何将 zip 文件中的文件作为文本而不是字节读取?

FFmpeg:“[h264 @ <hexnumber>]AVC:仅消耗 n 个字节而不是 n+6”