Windows Media Foundation录制音频 [英] Windows Media Foundation recording audio

查看:430
本文介绍了Windows Media Foundation录制音频的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



这是我的枚举代码:

我使用windows media foundation api枚举我的麦克风和可用的摄像机。

  class deviceInput {
public:
deviceInput(REFGUID source);
〜deviceInput();

int listDevices(bool refresh = false);
IMFActivate * getDevice(unsigned int deviceId);
const WCHAR * getDeviceName(unsigned int deviceId);

private:
void Clear();
HRESULT EnumerateDevices();

UINT32 m_count;
IMFActivate ** m_devices;
REFGUID m_source;
};

deviceInput :: deviceInput(REFGUID source)
:m_devices(NULL)
,m_count(0)
,m_source(source)
{}

deviceInput ::〜deviceInput()
{
Clear();
}

int deviceInput :: listDevices(bool refresh)
{
if(refresh ||!m_devices){
if(FAILED > EnumerateDevices()))return -1;
}
return m_count;
}

IMFActivate * deviceInput :: getDevice(unsigned int deviceId)
{
if(deviceId> = m_count)return NULL;

IMFActivate * device = m_devices [deviceId];
device-> AddRef();

return device;
}

const WCHAR * deviceInput :: getDeviceName(unsigned int deviceId)
{
if(deviceId> = m_count)return NULL;

HRESULT hr = S_OK;
WCHAR * devName = NULL;
UINT32 length;

hr = m_devices [deviceId] - > GetAllocatedString(MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME,& devName,& length);
if(FAILED(hr))return NULL;

return devName;
}

void deviceInput :: Clear()
{
if(m_devices){
for(UINT32 i = 0; i CoTaskMemFree(m_devices);
}
m_devices = NULL;
m_count = 0;
}

HRESULT deviceInput :: EnumerateDevices()
{
HRESULT hr = S_OK;
IMFAttributes * pAttributes = NULL;

Clear();

hr = MFCreateAttributes(& pAttributes,1);
if(SUCCEEDED(hr))hr = pAttributes-> SetGUID(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE,m_source);
if(SUCCEEDED(hr))hr = MFEnumDeviceSources(pAttributes,& m_devices,& m_count);

SafeRelease(& pAttributes);

return hr;
}

要抓取音频或相机捕获设备,请指定 MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_GUID MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID ,并且没有问题,我可以获取设备的名称以及IMFActivate。我有代码记录网络摄像头到输出视频文件,但是,我有一个艰难的时间,弄清楚如何将音频录制到文件。我的印象是,我需要使用IMFSinkWriter,但我找不到任何使用音频捕获IMFActivate和IMFSinkWriter的示例。



我不是大部分的windows api程序员,所以我敢肯定有一个相当直接的回答,但COM的东西只是一点点在我的头。至于音频格式,我真的不在乎,只要它进入一个文件 - 可以是wav,wma或任何。即使我正在录制视频,我需要单独的视频和音频文件,所以我不能只是找出如何添加音频到我的视频编码。

解决方案

我为迟到的回复道歉,我希望你仍然可以找到这个有价值的。我最近完成了一个类似于你的项目(将网络摄像机视频和选定的麦克风录制到一个带有音频的视频文件)。关键是创建汇总媒体来源。

  // http://msdn.microsoft.com/en-us/ library / windows / desktop / dd388085(v = vs.85).aspx 
HRESULT CreateAggregateMediaSource(IMFMediaSource * videoSource,IMFMediaSource * audioSource,IMFMediaSource ** aggregateSource)
{
* aggregateSource = NULL;
IMFCollection * pCollection = NULL;

HRESULT hr = MFCreateCollection(& pCollection);

if(SUCCEEDED(hr))
hr = pCollection-> AddElement(videoSource);

if(SUCCEEDED(hr))
hr = pCollection-> AddElement(audioSource);

if(SUCCEEDED(hr))
hr = MFCreateAggregateSource(pCollection,aggregateSource);

SafeRelease(& pCollection);
return hr;
}

配置接收器写入器时,将添加2个流一个用于视频)。
当然,您还将为输入流类型正确配置编写器。

  HRESULT hr = S_OK; 
IMFMediaType * videoInputType = NULL;
IMFMediaType * videoOutputType = NULL;
DWORD videoOutStreamIndex = 0;
DWORD audioOutStreamIndex = 0;
IMFSinkWriter * writer = NULL;

// [其他创建和配置写程序]

if(SUCCEEDED(hr))
hr = writer-> AddStream(videoOutputType,& videoOutStreamIndex) ;

// [更多配置代码]

if(SUCCEEDED(hr))
hr = writer-> AddStream(audioOutputType,& audioOutStreamIndex);

然后在阅读示例时,您需要密切关注读者streamIndex,适当地写作者。您还需要密切关注编解码器预期的格式。例如,IEEE float vs PCM等。祝你好运,我希望不会迟到。


I'm using the windows media foundation api to enumerate both my microphones and available cameras, which both work.

Here is my enumeration code:

class deviceInput {
public:
    deviceInput( REFGUID source );
    ~deviceInput();

    int listDevices(bool refresh = false);
    IMFActivate *getDevice(unsigned int deviceId);
    const WCHAR *getDeviceName(unsigned int deviceId);

private:
    void Clear();
    HRESULT EnumerateDevices();

    UINT32      m_count;
    IMFActivate **m_devices;
    REFGUID     m_source;
};

deviceInput::deviceInput( REFGUID source )
    : m_devices( NULL )
    , m_count( 0 )
    , m_source( source )
{   }

deviceInput::~deviceInput()
{
    Clear();
}

int deviceInput::listDevices(bool refresh)
{
    if ( refresh || !m_devices ) {
        if ( FAILED(this->EnumerateDevices()) ) return -1;
    }
    return m_count;
}

IMFActivate *deviceInput::getDevice(unsigned int deviceId)
{
    if ( deviceId >= m_count ) return NULL;

    IMFActivate *device = m_devices[deviceId];
    device->AddRef();

    return device;
}

const WCHAR *deviceInput::getDeviceName(unsigned int deviceId)
{
    if ( deviceId >= m_count ) return NULL;

    HRESULT hr = S_OK;
    WCHAR *devName = NULL;
    UINT32 length;

    hr = m_devices[deviceId]->GetAllocatedString( MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME, &devName, &length );
    if ( FAILED(hr) ) return NULL;

    return devName;
}

void deviceInput::Clear()
{
    if ( m_devices ) {
        for (UINT32 i = 0; i < m_count; i++) SafeRelease( &m_devices[i] );
        CoTaskMemFree( m_devices );
    }
    m_devices = NULL;
    m_count = 0;
}

HRESULT deviceInput::EnumerateDevices()
{
    HRESULT hr = S_OK;
    IMFAttributes *pAttributes = NULL;

    Clear();

    hr = MFCreateAttributes(&pAttributes, 1);
    if ( SUCCEEDED(hr) ) hr = pAttributes->SetGUID( MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, m_source );
    if ( SUCCEEDED(hr) ) hr = MFEnumDeviceSources( pAttributes, &m_devices, &m_count );

    SafeRelease( &pAttributes );

    return hr;
}

To grab audio or camera capture devices, I specify either MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_GUID or MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID and that works no problem, and I can grab the names of the devices, as well as the IMFActivate. I have code to record the webcam to an output video file, however, I'm having a tough time figuring out how to record the audio to a file. I'm under the impression that I need to use an IMFSinkWriter, but I can't find any examples that use an audio capture IMFActivate and IMFSinkWriter.

I'm not much of a windows api programmer, so I'm sure there's a fairly straight forward answer, but COM stuff is just a bit over my head. As far as audio format, I don't really care, as long as it gets into a file - can be wav, wma, or whatever. Even though I'm recording video, I need the video and audio files separate, so I can't just figure out how to add the audio into my video encoding.

解决方案

I apologize for the late response, and I hope you can still find this valuable. I recently completed a project similar to yours (recording webcam video along with a selected microphone to a single video file with audio). The key is to creating an aggregate media source.

// http://msdn.microsoft.com/en-us/library/windows/desktop/dd388085(v=vs.85).aspx
HRESULT CreateAggregateMediaSource(IMFMediaSource *videoSource, IMFMediaSource *audioSource, IMFMediaSource **aggregateSource)
{
    *aggregateSource = NULL;
    IMFCollection *pCollection = NULL;

    HRESULT hr = MFCreateCollection(&pCollection);

    if (SUCCEEDED(hr))
        hr = pCollection->AddElement(videoSource);

    if (SUCCEEDED(hr))
        hr = pCollection->AddElement(audioSource);

    if (SUCCEEDED(hr))
        hr = MFCreateAggregateSource(pCollection, aggregateSource);

    SafeRelease(&pCollection);
    return hr;
}

When configuring the sink writer, you will add 2 streams (one for audio and one for video). Of course, you will also configure the writer correctly for the input stream types.

HRESULT        hr = S_OK;
IMFMediaType  *videoInputType = NULL;
IMFMediaType  *videoOutputType = NULL;
DWORD          videoOutStreamIndex = 0;
DWORD          audioOutStreamIndex = 0;
IMFSinkWriter *writer = NULL;

// [other create and configure writer]

if (SUCCEEDED(hr))
    hr = writer->AddStream(videoOutputType, &videoOutStreamIndex);    

// [more configuration code]

if (SUCCEEDED(hr))
    hr = writer->AddStream(audioOutputType, &audioOutStreamIndex);

Then when reading the samples, you will need to pay close attention to the reader streamIndex, and sending them to the writer appropriately. You will also need to pay close attention to the format that the codec expects. For instance, IEEE float vs PCM, etc. Good luck, and I hope it is not to late.

这篇关于Windows Media Foundation录制音频的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆