2012-10-16 23 views
5

मैं अपने माइक्रोफ़ोन और उपलब्ध कैमरे दोनों की गणना करने के लिए विंडोज मीडिया नींव एपीआई का उपयोग कर रहा हूं, जो दोनों काम करते हैं।विंडोज मीडिया फाउंडेशन रिकॉर्डिंग ऑडियो

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; 
} 

ऑडियो या कैमरा कैप्चर डिवाइस हड़पने के लिए, मैं या तो MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_GUID या MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID निर्दिष्ट और कहा कि कोई समस्या नहीं काम करता है, और मैं उपकरणों के नाम प्राप्त कर सकते हैं, साथ ही:

यहाँ मेरी गणन कोड है IMFActivate। मेरे पास आउटपुट वीडियो फ़ाइल में वेबकैम रिकॉर्ड करने के लिए कोड है, हालांकि, मुझे फ़ाइल में ऑडियो रिकॉर्ड करने का तरीका पता लगाना मुश्किल समय है। मैं इस धारणा के तहत हूं कि मुझे IMFSinkWriter का उपयोग करने की आवश्यकता है, लेकिन मुझे कोई ऐसा उदाहरण नहीं मिल रहा है जो ऑडियो कैप्चर IMFActivate और IMFSinkWriter का उपयोग करता हो।

मैं विंडोज़ एपीआई प्रोग्रामर का अधिकतर नहीं हूं, इसलिए मुझे यकीन है कि काफी सीधे जवाब है, लेकिन COM सामान मेरे सिर पर थोड़ा सा है। जहां तक ​​ऑडियो प्रारूप है, मुझे वास्तव में परवाह नहीं है, जब तक यह एक फ़ाइल में हो जाता है - WAV, WMA, या जो कुछ भी हो सकता है। भले ही मैं वीडियो रिकॉर्ड कर रहा हूं, मुझे वीडियो और ऑडियो फाइलों को अलग करने की ज़रूरत है, इसलिए मैं यह नहीं समझ सकता कि ऑडियो को मेरे वीडियो एन्कोडिंग में कैसे जोड़ा जाए।

उत्तर

7

मैं देर से प्रतिक्रिया के लिए क्षमा चाहता हूं, और मुझे उम्मीद है कि आप अभी भी यह मूल्यवान पा सकते हैं। मैंने हाल ही में आपके जैसा एक प्रोजेक्ट पूरा किया है (ऑडियो के साथ एक वीडियो फ़ाइल में एक चयनित माइक्रोफोन के साथ वेबकैम वीडियो रिकॉर्डिंग)। एक समग्र मीडिया स्रोत बनाने की कुंजी है।

// 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; 

// [other create and configure writer] 

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

// [more configuration code] 

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

फिर जब नमूने पढ़ने, आप पाठक streamIndex पर अधिक ध्यान दें करने के लिए लेखक को उन्हें उचित रूप से भेजने की जरूरत है, और होगा। आपको कोडेक की अपेक्षा के प्रारूप पर भी ध्यान देना होगा। उदाहरण के लिए, आईईईई फ्लोट बनाम पीसीएम, आदि शुभकामनाएं, और मुझे उम्मीद है कि देर से नहीं है।

+0

यह लंबे समय से रहा है क्योंकि मैं उस परियोजना पर काम कर रहा हूं, और तब से इसे किसी अन्य व्यक्ति द्वारा लिया गया है जो इसे एक अलग दिशा में ले गया है। भले ही, उदाहरण कोड के साथ स्पष्ट उत्तर के लिए धन्यवाद, यह बहुत सराहना की है, और शायद किसी और को यह बहुत उपयोगी लगेगा :) – OzBarry

0

क्या आपको Record directshow audio device to file में डायरेक्टशो ऑडियो कैप्चर प्रबंधित करने में कठिनाई हुई है?

मीडिया फाउंडेशन के साथ कैप्चरिंग शायद ही आसान है। यहां तक ​​कि उल्लेख नहीं है कि सामान्य रूप में वहाँ डायरेक्टशो पर एक बहुत अधिक संसाधन हैं ....

MSDN आप एक WavSink Sample कि फाइल में ऑडियो कैप्चर लागू करता है प्रदान करता है:

दिखाता है कि कैसे एक कस्टम मीडिया सिंक लागू करने के लिए माइक्रोसॉफ्ट मीडिया फाउंडेशन में। नमूना एक संग्रह सिंक लागू करता है जो एक .wav फ़ाइल में असंपीड़ित पीसीएम ऑडियो लिखता है।

मुझे यकीन नहीं है कि उन्होंने इसे मानक घटक बनाने का फैसला क्यों नहीं किया। डायरेक्टशो से कई तरीकों से मीडिया फाउंडेशन को कम करने के बाद, वे कम से कम इस छोटी चीज़ को लाभ के रूप में बना सकते हैं। वैसे भी, आपके पास नमूना है और यह एक अच्छी शुरुआत की तरह दिखता है।

+0

हाँ, मैंने WavSink उदाहरण देखा, यह मुद्दा वास्तव में एक ट्रांसकोडर है; यह एक पीसीएम ऑडियो फ़ाइल लेता है, और इसे * .wav फ़ाइल में परिवर्तित करता है, इसलिए यह वास्तव में मुझे नहीं बताता है कि वास्तव में किसी डिवाइस से ऑडियो डेटा कैसे प्राप्त करें। मैं प्रत्यक्ष प्रदर्शन का उपयोग कर रहा था, लेकिन मेरे मालिक ने मुझे मीडिया नींव का उपयोग करने के लिए प्रोत्साहित किया (जैसा कि मुझे बताया गया) पढ़ें। – OzBarry

+0

यह आपको वैसे भी सबसे महत्वपूर्ण टुकड़ा देता है।हां आपको टोपोलॉजी को ट्रांसकोडिंग नहीं करना है, लेकिन असली ऑडियो कैप्चर डिवाइस का उपयोग करना है। –