从视频中提取音频为wav格式。

4
我知道有一个类似于我的问题:从视频文件中提取WAV文件 我是C++的新手,了解需要使用COM库+ DirectX来处理视频和音频。我一直在寻找教程和示例代码,但成果不大。
我的问题是,如何编写应用程序以获取视频文件(任何类型)并将提取的音频保存为.wav文件在我的应用程序中,而不是使用其他应用程序,例如graphedit或virtualdub?
3个回答

5

您可以使用类似ffmpeg或其使用的库之一吗?或者可以使用mencoder,它也可以实现相同的功能。据我所知,它们都有命令行界面,可能也有一些API...


5

我支持使用ffmpeg构建来执行音频提取,这可以通过一个简单的命令完成,而不是可能需要数百行代码(如果您要检查处理不同视频格式和编解码器可能出现的所有问题)。

ffmpeg -i video.avi -vn soundfile.wav

您可以使用libavformat和libavformat(ffmpeg背后的库)来完成相同的事情,但除非您需要在输出到wav之前对原始音频进行一些处理,否则除了知识外,没有任何收益。
ffmpeg很好用,因为可执行文件包含您可能需要的所有音频和视频解码器,因此解决方案具有高度的可移植性。您不必安装编解码器或任何其他东西。输入视频文件可以是ffmpeg支持的任何格式或编解码器,您不必在代码中对它们进行区分。
从C++中,您可以通过在代码中构建命令行字符串并从代码中启动进程来调用ffmpeg(作为新的C++用户,您可能需要研究如何做到这一点,但这很容易)。

感谢您的回答和清晰的解释。我已经下载了FFmpeg,但是发现网站上关于构建FFmpeg的维基页面很混乱且没有更新。我不确定要构建哪种类型的库(静态或动态链接库),但我认为如果我将该库包含在我的应用程序中并发布给其他人,则应该是静态链接库。 - John Meyers
您可以在此处获取FFmpeg的Win32二进制文件:http://ffmpeg.arrozcru.org/builds/,因此您无需自己构建它。只需下载最新的Win32二进制包(ffmpeg-r16537-gpl-static-win32.tar.bz2),它将在bin目录中包含“ffmpeg.exe”。由于它是一个静态构建,所以您只需要exe文件即可。在li/unix系统上构建FFmpeg非常简单,但在Windows上则更加困难,因为您无法使用Visual Studio的编译器来构建它,所以必须使用mingw。我建议您直接使用预构建的二进制文件。 - Jason B

2
你可以使用Directshow过滤器构建一个图形,将音频保存为.wav格式。
你需要使用的接口有:(注意:此解决方案将从avi文件中提取音频) IGraphBuilder:用于构建图形。 IBaseFilter:这些过滤器将被初始化以成为图形的一部分。
要初始化图形,请执行以下操作:
IGraphBuilder *pGraph = NULL;
CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&pGraph)

CLSID_FilterGraph定义在uuids.h中,该文件是PaltformSDK的一部分。

一旦图形被初始化,您需要初始化3个过滤器,这些过滤器将被添加到图形中。

  1. AVI多路复用器:CLSID_AviDest
  2. 文件编写器:CLSID_FileWriter。
  3. 空渲染器:CLSID_NullRenderer

您可以通过以下方式初始化过滤器:

IBaseFilter *pF = NULL;
CoCreateInstance(clsid, 0, CLSCTX_INPROC_SERVER,  IID_IBaseFilter, (void**)&pF);
clsid = clsid of the filter

使用以下方法在图表中添加筛选器:

pGraph->AddFilter(pF, name)
name = name of the filter. Can be 'AVI Mux' etc

当您初始化 '文件写入器' 过滤器后,您需要设置要写入文件的路径。您可以这样做:

IFileSinkFilter* pFileSink=NULL;
 fileWriterFilter->QueryInterface(IID_IFileSinkFilter, (void**)&pFileSink);
pFileSink->SetFileName(filepath, NULL);


Here: fileWriter = file writer filter instance.

确保文件名的扩展名为.wav

一旦您在图形中添加了过滤器,您需要渲染视频文件,如下所示:

pGraph->RenderFile(sourcePath, NULL);

一旦渲染完成,现在您需要运行此图。您可以通过从图中查询几个接口来实现:

IMediaControl 用于运行过滤器

IMediaEvent 用于从图中获取事件。

查询接口:

pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);
and pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);

运行图表:

pControl->Run();

等待渲染完成:

pEvent->WaitForCompletion(INFINITE, &evCode);

操作完成后,您将会找到一个以.wav格式存储音频的文件。

我已经通过graphedit进行了测试,它可以正常工作。希望这能对您有所帮助。


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