简体   繁体   English

从wav中提取视频中的音频

[英]Extract audio from video as wav

I know there is a question similar to mine: Extract wav file from video file 我知道有一个类似于我的问题: 从视频文件中提取wav文件

I am new to C++ and understand about COM library + directX is needed for video and audio. 我是C ++的新手,了解COM库+视频和音频需要directX。 I been looking for tutorial and samples code but little success. 我一直在寻找教程和示例代码,但收效甚微。

My question is how do I code the application to take video file (any type) and saved the extracted audio as .wav in my application rather than using other applications such as graphedit or virtualdub? 我的问题是如何编写应用程序以获取视频文件(任何类型)并将提取的音频保存为我的应用程序中的.wav,而不是使用其他应用程序,如graphedit或virtualdub?

Can't you use something like ffmpeg , or one of the libraries it uses? 你不能使用像ffmpeg或它使用的其中一个库吗? Or maybe mencoder, which can do the same. 或者也许mencoder,它可以做同样的事情。 Both of them have a command line interface as far as I know, and they might have some API as well... 据我所知,他们都有一个命令行界面,他们可能也有一些API ...

I'll second the motion to just use a build of ffmpeg to perform the audio extraction. 我将在动作中使用ffmpeg的构建来执行音频提取。 It can be done in one easy command as opposed to most likely hundreds of lines of code (If your going to check for all of the possible problems that could happen when dealing with different video formats and codecs). 它可以在一个简单的命令中完成,而不是很可能是数百行代码(如果您要检查处理不同视频格式和编解码器时可能发生的所有问题)。

ffmpeg -i video.avi -vn soundfile.wav

You could use libavformat and libavformat(libraries behind ffmpeg) to do the same thing, but unless you need to do some processing on the raw audio before outputting to wav, there would be nothing to gain except for knowledge. 您可以使用libavformat和libavformat(ffmpeg后面的库)来做同样的事情,但除非您需要在输出到wav之前对原始音频进行一些处理,否则除了知识之外没有什么可以获得的。

ffmpeg is nice because the executable contains all of the audio and video decoders you'll probably ever need so the solution is highly portable. ffmpeg很不错,因为可执行文件包含了您可能需要的所有音频和视频解码器,因此该解决方案具有高度可移植性。 You don't have it install codecs or anything. 你没有安装编解码器或任何东西。 The input video file can be in any format or codec that ffmpeg supports and you don't have to bother with treating them differently in your code. 输入视频文件可以是ffmpeg支持的任何格式或编解码器,您不必费心在代码中对它们进行不同的处理。

From C++ you can call ffmpeg by building the command line string in your code and kicking off the process from your code (being new the C++, you'll probably need to research how to do this, but it's pretty easy). 从C ++开始,您可以通过在代码中构建命令行字符串来调用ffmpeg并从代码中开始流程(作为新的C ++,您可能需要研究如何执行此操作,但这很简单)。

You can use Directshow filters to construct a graph that will save the audio as .wav. 您可以使用Directshow过滤器构建一个将音频保存为.wav的图形。

The interfaces that you need to use are: (Note: This solution will extract audio from avi files) 您需要使用的接口是:( 注意:此解决方案将从avi文件中提取音频)

IGraphBuilder : This will be used to build graph. IGraphBuilder :这将用于构建图形。

IBaseFilter : This will be the filters that you initialize to make part of the graph IBaseFilter :这将是您初始化以构成图表一部分的过滤器

To initialize graph you do: 要初始化图形,您可以:

IGraphBuilder *pGraph = NULL;
CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&pGraph)

CLSID_FilterGraph is defined in uuids.h which is part of PaltformSDK. CLSID_FilterGraph在uuids.h中定义,它是PaltformSDK的一部分。

Once the graph is initialized, you will need to initialize 3 filters that will be added in the graph. 初始化图形后,您需要初始化将在图形中添加的3个过滤器。

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

You can initialize filters by: 您可以按以下方式初始化过滤器

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

And add the filter in graph using: 并使用以下方法在图表中添加过滤器

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

Once you initialize 'File writer' filter you will need to set the path where you wish to write the file. 初始化“文件编写器”过滤器后,您需要设置要写入文件的路径。 You can do that: 你可以这样做:

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


Here: fileWriter = file writer filter instance.

Make sure that the extension of file name is .wav 确保文件名的扩展名为.wav

Once you added the filters in graph, you will need to render the video file like: 在图表中添加过滤器后,您需要呈现视频文件,如:

pGraph->RenderFile(sourcePath, NULL);

Once rendered, you will now need to Run this graph. 渲染完成后,您现在需要运行此图形。 You can do this by querying couple of interfaces from the graph: 您可以通过从图中查询几个接口来完成此操作:

IMediaControl Used to run the filter IMediaControl用于运行过滤器

and IMediaEvent Used to get events from graph. IMediaEvent用于从图中获取事件。

Query the interface: 查询界面:

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

Run the graph: 运行图表:

pControl->Run();

And wait for the rendering for completion: 等待渲染完成:

pEvent->WaitForCompletion(INFINITE, &evCode);

Once done, you will find a file having audio in .wav format. 完成后,您将找到一个具有.wav格式音频的文件。

I have tested this through graphedit and it works. 我已经通过graphedit对此进行了测试,但它确实有效。 I hope this will help. 我希望这将有所帮助。

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

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