用Python从视频文件中提取wav音频文件

36

相关:

如何使用Python从视频文件中提取音频?

将视频作为wav提取音频

如何从视频中提取音频?

我的问题是如何从视频文件(例如video.avi)中提取wav音频轨道?我阅读了很多文章,并且人们到处建议使用(从Python)ffmpeg作为子进程(因为没有可靠的Python绑定到ffmpeg——唯一的希望是PyFFmpeg,但我发现它现在已经不再维护)。 我不知道这是否是正确的解决方案,我正在寻找更好的解决方案。
我看过gstreamer,发现它很不错,但无法满足我的需要——我找到的唯一一种从命令行实现此操作的方法是:

 gst-launch-0.10 playbin2 uri=file://`pwd`/ex.mp4  audio-sink='identity single-segment=true ! audioconvert ! audio/x-raw-int, endianness=(int)1234, signed=(boolean)true, width=(int)16, depth=(int)16, rate=(int)16000, channels=(int)1 ! wavenc !  filesink location=foo.wav’ 

但这并不高效,因为我需要在播放视频和同时录制到wav文件时等待很久。

ffmpeg更好:

avconv  -i foo.mp4  -ab 160k -ac 1 -ar 16000 -vn ffaudio.wav

但是我无法从Python中启动它(不是作为命令行子进程)。您能指出从Python作为命令行实用程序启动ffmpeg的利弊吗?(我的意思是使用Python multiprocessing 模块或类似的东西)。

第二个问题。

有没有简单的方法将长WAV文件切成长度为10-20秒的片段,以便在句子/单词的停顿期间开始和结束,这样就不会打断任何单词?我的意思是,它们必须在句子/单词的停顿期间开始和结束。

我知道如何将它们断成任意长度的片段:

import wave


win= wave.open('ffaudio.wav', 'rb')
wout= wave.open('ffsegment.wav', 'wb')

t0, t1= 2418, 2421 # cut audio between 2413, 2422 seconds
s0, s1= int(t0*win.getframerate()), int(t1*win.getframerate())
win.readframes(s0) # discard
frames= win.readframes(s1-s0)

wout.setparams(win.getparams())
wout.writeframes(frames)

win.close()
wout.close()

3
你提到了 ffmpeg, 但你正在使用的是 avconv - llogan
请参考https://dev59.com/EWox5IYBdhLWcg3wCQAq。它们是不同的项目,不能互相替代。“avconv”是“ffmpeg”的一个分支,为了远离“FFmpeg项目”而创建。 - xolodec
如果在Ubuntu中启动FFMPEG,您会看到以下信息:“FFMPEG程序仅提供脚本兼容性,并将在未来版本中被删除。它已经被弃用,在Libav项目中,为了允许其替代品AVCONV中的不兼容命令行语法改进。请改用AVCONV。” - xolodec
请根据Daweo在此处的建议[https://dev59.com/ylMI5IYBdhLWcg3w4Pvq#55081534],探索MoviePy库。 - Nasheed Yasin
4个回答

59

使用ffmpegPython子进程非常容易完成此任务,人们之所以指向这个解决方案是有原因的。

以下是从给定视频文件提取音频的基本命令:

ffmpeg -i test.mp4 -ab 160k -ac 2 -ar 44100 -vn audio.wav

Python代码只需将该命令封装起来即可:

import subprocess

command = "ffmpeg -i C:/test.mp4 -ab 160k -ac 2 -ar 44100 -vn audio.wav"

subprocess.call(command, shell=True)

您需要确保ffmpeg是一个已知的任务,在您的系统环境变量中,路径下应列出ffmpeg.exe的路径,或者您可以在Python代码中使用可执行文件的完整路径。


非常感谢。但我并不是 Python 的新手,知道如何使用 subprocessmultiprocessing 模块来完成这个任务。我询问的是这种方法可能存在的缺点。除了在系统中找不到 ffmpeg/aconv 的未知路径(我可以轻松自行查找),我对它们一无所知。因此,我希望有人能指出这种方法的其他缺点。 - xolodec
老实说,如果你试图使用免费可用的库,我认为你不会找到比ffmpeg更好、更容易使用的东西了。 - user1767754
如果我们的.py文件位于不同的位置,那么在这段代码中,我们是否必须指定videofileaudiofile的绝对路径? - abhi1610
无论您从哪里启动Python会话,都是基本路径。我建议使用绝对路径,在某个时候如果您正在调试,可以复制并粘贴命令在shell中运行。 - user1767754
很好,这个答案也适用于以webm为源文件! - Hoff
它保存在哪里? - Farhang Amaji

10

这个名为Python视频转换器的工具可能比FFmpeg更好用且更易于使用,它可以用来从视频中提取音频。https://github.com/senko/python-video-converter 它可以与mpg123配合使用,请参考以下示例:

    from converter import Converter
    import os
    c = Converter()
    clip = 'clip.avi'
    conv = c.convert(clip, 'audio.mp3', {'format':'mp3','audio':{'codec': 'mp3','bitrate':'22050','channels':1}})
    for timecode in conv:
        pass    
    os.system("mpg123 -w audio.wav audio.mp3")

转换器模块从视频中提取音频并将其保存为mp3文件,而mpg123将mp3文件转换为mp4格式。

另一种解决方案如下: 使用Python中的moviepy模块 https://github.com/Zulko/moviepy

    import moviepy.editor as mp
    clip = mp.VideoFileClip("video.avi").subclip(0,20)
    clip.audio.write_audiofile("theaudio.mp3")

subclip函数中的数字指定音频的开始和结束时间,单位为秒。然后您可以使用mpg123将音频转换为任何其他格式。


9

1
例如从中提取mp3。
import os

VIDEOS_PATH = '/Users/****/videos'
VIDEOS_EXTENSION = '.webm'  # for example
AUDIO_EXT = 'wav'

EXTRACT_VIDEO_COMMAND = ('ffmpeg -i "{from_video_path}" '
                         '-f {audio_ext} -ab 192000 '
                         '-vn "{to_audio_path}"')

os.chdir(VIDEOS_PATH)
files = os.listdir(VIDEOS_PATH)
for f in files:
    if not f.endswith(VIDEOS_EXTENSION):
        continue

    audio_file_name = '{}.{}'.format(f, AUDIO_EXT)
    command = EXTRACT_VIDEO_COMMAND.format(
        from_video_path=f, audio_ext=AUDIO_EXT, to_audio_path=audio_file_name,
    )
    os.system(command)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接