問(wèn)題描述
我正在使用 windows media Foundation api 來(lái)枚舉我的麥克風(fēng)和可用的攝像頭,它們都可以工作.
I'm using the windows media foundation api to enumerate both my microphones and available cameras, which both work.
這是我的枚舉代碼:
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;
}
要抓取音頻或相機(jī)捕獲設(shè)備,我指定 MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_GUID
或 MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID
沒(méi)有問(wèn)題,我可以抓取設(shè)備的名稱(chēng),以及IMF 激活.我有將網(wǎng)絡(luò)攝像頭錄制到輸出視頻文件的代碼,但是,我很難弄清楚如何將音頻錄制到文件中.我的印象是我需要使用 IMFSinkWriter,但我找不到任何使用音頻捕獲 IMFActivate 和 IMFSinkWriter 的示例.
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.
我不是一個(gè) Windows api 程序員,所以我確信有一個(gè)相當(dāng)直接的答案,但 COM 的東西只是有點(diǎn)超出我的頭腦.至于音頻格式,我并不在乎,只要它進(jìn)入一個(gè)文件 - 可以是 wav、wma 或其他任何格式.即使我正在錄制視頻,我也需要將視頻和音頻文件分開(kāi),所以我無(wú)法弄清楚如何將音頻添加到我的視頻編碼中.
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.
推薦答案
對(duì)于遲到的回復(fù),我深表歉意,我希望你仍然能發(fā)現(xiàn)這很有價(jià)值.我最近完成了一個(gè)與您類(lèi)似的項(xiàng)目(將網(wǎng)絡(luò)攝像頭視頻與選定的麥克風(fēng)一起錄制到帶有音頻的單個(gè)視頻文件中).關(guān)鍵是創(chuàng)建聚合媒體源.
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 = nullptr;
IMFCollection *pCollection = nullptr;
HRESULT hr = ::MFCreateCollection(&pCollection);
if (S_OK == hr)
hr = pCollection->AddElement(videoSource);
if (S_OK == hr)
hr = pCollection->AddElement(audioSource);
if (S_OK == hr)
hr = ::MFCreateAggregateSource(pCollection, aggregateSource);
SafeRelease(&pCollection);
return hr;
}
在配置接收器編寫(xiě)器時(shí),您將添加 2 個(gè)流(一個(gè)用于音頻,一個(gè)用于視頻).當(dāng)然,您還將為輸入流類(lèi)型正確配置編寫(xiě)器.
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 = nullptr;
IMFMediaType *videoOutputType = nullptr;
DWORD videoOutStreamIndex = 0u;
DWORD audioOutStreamIndex = 0u;
IMFSinkWriter *writer = nullptr;
// [other create and configure writer]
if (S_OK == hr))
hr = writer->AddStream(videoOutputType, &videoOutStreamIndex);
// [more configuration code]
if (S_OK == hr)
hr = writer->AddStream(audioOutputType, &audioOutStreamIndex);
然后在閱讀樣本時(shí),您需要密切關(guān)注閱讀器streamIndex,并適當(dāng)?shù)貙⑺鼈儼l(fā)送給編寫(xiě)者.您還需要密切注意編解碼器期望的格式.比如IEEE float vs PCM等等.祝你好運(yùn),希望現(xiàn)在還不算太晚.
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 too late.
這篇關(guān)于Windows Media Foundation 錄制音頻的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!