📄 capturedlg.cpp
字号:
//连接解码器->声道
if (SUCCEEDED(m_FilterGraph->ConnectDirect(gcap.iWMAFilterOutput, gcap.iHtAudioFilterInput, NULL)))
{
//连接声道->声卡
if (SUCCEEDED(m_FilterGraph->ConnectDirect(gcap.iHtAudioFilterOutput, gcap.iAudioFilterInput, NULL)))
{
return true;
}
//MessageBox("声道->声卡连接失败 ! ");
}
//MessageBox("解码器->声道连接失败 ! ");
}
//MessageBox("重载声卡失败 ! ");
}
//MessageBox("重载声道失败 ! ");
}
//MessageBox("重载解码器失败 ! ");
//gcap.strFileName = "";
//AllRelease(); //释放全部应用
return E_FAIL;
}
//断开解码器 Filter 与声卡Filter 的连接---------------------------------------
HRESULT CCaptureDlg::Disconnects()
{
//m_FilterGraph->Disconnect(gcap.iAudioFilterInput);
//m_FilterGraph->Disconnect(gcap.iWMAFilterOutput);
if (SUCCEEDED(m_FilterGraph->Disconnect(gcap.iAudioFilterInput)))
{
if (SUCCEEDED(m_FilterGraph->Disconnect(gcap.iWMAFilterOutput)))
{
return true;
}
}
return E_FAIL;
}
//查找WMAFilter接口----------------------------------------------------------------
HRESULT CCaptureDlg::FindWMAFilterInOutPIN()
{
if (SUCCEEDED(GetPin(gcap.iWMAFilterID, PINDIR_OUTPUT, &gcap.iWMAFilterOutput)))
{
if (SUCCEEDED(GetPin(gcap.iWMAFilterID, PINDIR_INPUT, &gcap.iWMAFilterInput)))
{
return S_OK;
}
gcap.iWMAFilterOutput->Release();
}
return E_FAIL;
}
//查找HtAudio Filter INPUT OUTPUT 接口----------------------------------------------------------------
HRESULT CCaptureDlg::FindHtAudioFilterInOutPIN()
{
if (SUCCEEDED(GetPin(gcap.iHtAudioFilterID, PINDIR_OUTPUT, &gcap.iHtAudioFilterOutput)))
{
if (SUCCEEDED(GetPin(gcap.iHtAudioFilterID, PINDIR_INPUT, &gcap.iHtAudioFilterInput)))
{
return S_OK;
}
gcap.iHtAudioFilterInput->Release();
}
gcap.iHtAudioFilterOutput->Release();
return E_FAIL;
}
//查找声卡 Filter接口----------------------------------------------------------------
HRESULT CCaptureDlg::FindAudioFilterInPIN()
{
HRESULT hr;
hr = GetPin(gcap.iAudioFilterID, PINDIR_INPUT, &gcap.iAudioFilterInput);
if (FAILED(hr))
{
gcap.iAudioFilterInput->Release();
return E_FAIL;
}
return hr;
}
//查找使用中的声卡 Filter-------------------------------------------------------
HRESULT CCaptureDlg::FindAudioModes()
{
IBaseFilter *pAudioMode = NULL;
IBaseFilter *m_pACout = NULL;
ISpecifyPropertyPages *pAudioModes = NULL;
//按文件名获得声卡 Filter地址 "WMAudio Decoder DMO" "Default DirectSound Device" "Intel(r) Integrated Audio"
if (SUCCEEDED(m_FilterGraph->FindFilterByName(L"Default DirectSound Device", &pAudioMode)))//HtAudio
{
//获得使用中的声卡Filter指针
IBaseFilter *m_pACouts = NULL;
if (SUCCEEDED(pAudioMode->QueryInterface(IID_IBaseFilter, (void**)&gcap.iAudioFilterID)))
{
if (SUCCEEDED(FindAudioFilterInPIN()))//查找声卡Filter接口
{
return S_OK;
}
}
}
return E_FAIL;
}
//-----------------------------------------------------------------
// 枚举系统设备,找到声卡
HRESULT CCaptureDlg::FindCaptureDevice(IBaseFilter **ppSrcFilter)
{
//查找声卡建立设备列表对象,得到ICreateDevEnum接口
HRESULT hr;
IBaseFilter * pSrc = NULL;
CComPtr <IMoniker> pMoniker =NULL;
ULONG cFetched;
if (!ppSrcFilter) return E_POINTER;
// 创建设备枚举器
CComPtr <ICreateDevEnum> pDevEnum = NULL;
if (SUCCEEDED(CoCreateInstance (CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
IID_ICreateDevEnum, (void **) &pDevEnum)))
{
// 创建音频设备种类枚举器
CComPtr <IEnumMoniker> pClassEnum = NULL;
if (SUCCEEDED(pDevEnum->CreateClassEnumerator (CLSID_AudioInputDeviceCategory, &pClassEnum, 0)))
{
// 在枚举器中找出音频设备
UINT uIndex = 0;
gcap.iAudioFilterGraph = NULL;
while(hr = pClassEnum->Next(1, &pMoniker, &cFetched), hr==S_OK)
{
if ((int)uIndex == gcap.iAudioDevice)
{ // this is the one we want
//创建音频筛选器图表
hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter,
(void**) &gcap.iAudioFilterGraph);
break;
}
uIndex++;
}
//查找设备名称和获得指针
LPOLESTR strName = NULL;
IBaseFilter *m_pRin = NULL;
//IMoniker::GetDisplayName 方法将返回moniker的显示名称(display name)
if (SUCCEEDED(pMoniker->GetDisplayName(NULL, NULL, &strName)))
{
CString LPCTSTR = strName;
//OK----::AfxMessageBox(LPCTSTR);//AFxMessageBox("获得音频Filter名成功 !");
//Intel(r) Integrated Audio
if (SUCCEEDED(gcap.iAudioFilterGraph->QueryInterface(IID_IBaseFilter, (void**)&pSrc)))
{
return true;
}
//MessageBox("不能访问音频设备 !");
}
//MessageBox("没有探测到音频设备 !");
}
//MessageBox("创建音频设备种类枚举器失败 !");
}
//MessageBox("创建设备枚举器失败 !");
return E_FAIL;
}
// 设置显示图像窗口------------------------------------------------------------
HRESULT CCaptureDlg::SetupVideoWindow(HWND inWindow)
{
// VideoWindow存在,则显示图像
if (m_VideoWindow)
{
// 首先隐藏VideoWindow
m_VideoWindow->put_Visible(OAFALSE);
// 将VideoWindow置于对话框上的显示控件中
m_VideoWindow->put_Owner((OAHWND)inWindow);
// 设置VideoWindow的大小
RECT windowRect;
::GetClientRect(inWindow, &windowRect);
m_VideoWindow->put_Left(0);
m_VideoWindow->put_Top(0);
m_VideoWindow->put_Width(windowRect.right - windowRect.left);
m_VideoWindow->put_Height(windowRect.bottom - windowRect.top);
m_VideoWindow->put_WindowStyle(WS_CHILD|WS_CLIPCHILDREN|WS_CLIPSIBLINGS);
// 显示VideoWindow
if (inWindow != NULL)
{
m_VideoWindow->put_Visible(OATRUE);
}
else
{
m_VideoWindow->put_Visible(OAFALSE);
}
return S_OK;
}
return S_FALSE;
}
bool CCaptureDlg::SetNotifyWindow(HWND inWindow)
{
if (m_MediaEventEx)
{
m_MediaEventEx->SetNotifyWindow((OAHWND)inWindow, WM_GRAPHNOTIFY, 0);
SetTimer(0, 600, NULL);//启动计时器
KillTimer(1);
gcap.mUnGlobal = 0;//解锁读写剪贴板
return true;
}
return false;
}
//确认解码器->声卡的连接是否已断开-----------------------------------------------------
HRESULT CCaptureDlg::FindAudioDevices()
{
//HRESULT hr;
IBaseFilter *pAudioMode = NULL;
IBaseFilter *m_pACout = NULL;
ISpecifyPropertyPages *pAudioModes = NULL;
//按文件名获得Filter地址 "WMAudio Decoder DMO" "Default DirectSound Device" "Intel(r) Integrated Audio"
if (SUCCEEDED(m_FilterGraph->FindFilterByName(L"Default DirectSound Device", &pAudioMode)))//HtAudio
{
//获得Filter指针
IBaseFilter *m_pACouts = NULL;
if (SUCCEEDED(pAudioMode->QueryInterface(IID_IBaseFilter, (void**)&m_pACout)))
{
//查找声卡Filter接口
ASSERT(m_pACout);
HRESULT hr = E_FAIL;
bool bReturned = false;
IEnumPins * pEnumPins;
if (SUCCEEDED(m_pACout->EnumPins(&pEnumPins)))
{
ULONG nfetched = 0;
pEnumPins->Reset();
while(SUCCEEDED(pEnumPins->Next(1, &gcap.iAudioFile, &nfetched))&&nfetched)
{
if(gcap.iAudioFile)//查询声卡pin成功
{
PIN_DIRECTION pinDir; //取得被连接接口
PIN_DIRECTION pinDirection = pAudioMode? PINDIR_INPUT : PINDIR_OUTPUT;
if (SUCCEEDED(gcap.iAudioFile->QueryDirection(&pinDir)))//取得Filter本身接口指针
{
if(SUCCEEDED(gcap.iAudioFile->ConnectedTo(&gcap.iWMAFilterOutput)))
{
bReturned = true;
}
//MessageBox("声卡未被连接 ! ");
}
}
return E_FAIL;
}
pEnumPins->Release();
}
return bReturned;
}
}
return E_FAIL;
}
//播放检测--------------------------------------------------------------------
void CCaptureDlg::OnTimer(UINT nIDEvent)
{
switch (nIDEvent)
{
case 0: ///处理ID为0的定时器
if (m_FilterGraph == NULL)
{
if (gcap.strFileName != "")
{
DiskFree();//磁盘工作状态
if (gcap.DiskFreeCk == 2) OnOK(); //开始播放
}
else
{
if (gcap.waitFileName == "") //启动-->查找播放文件
{
RlpGlobal();//读剪贴板数据
OnHtAudioR();//外部播放控制
}
else
{
FoundPlayerFilts();//获取播放文件名
}
}
}
else
{
gcap.eventCode = 0, gcap.eventParam1 = 0, gcap.eventParam2 = 0;
//取出消息
m_MediaEventEx->GetEvent(&gcap.eventCode,&gcap.eventParam1,&gcap.eventParam2,0);
//释放空间
m_MediaEventEx->FreeEventParams(gcap.eventCode,gcap.eventParam1,gcap.eventParam2);
if (gcap.eventCode == EC_COMPLETE || gcap.eventCode == EC_USERABORT || gcap.eventCode == EC_ERRORABORT)//播放结束或错误
{
AllRelease();//释放全部应用
gcap.strFileName = "";//请空变量等待新任务
}
else
{
RlpGlobal();//读剪贴板数据
OnHtAudioR();//外部播放控制
}
}
break;
case 1: ///处理ID为1的定时器
SetTimer(0, 600, NULL);
gcap.mUnGlobal = 0;//解锁读写剪贴板
KillTimer(1);
break;
}
}
//判断驱动器是否在工作状态-------------------------------------------------------------------------
HRESULT CCaptureDlg::DiskFree()
{
__int64 Available(0);
__int64 Total(0);
__int64 Free(0);
BOOL fResult;
CString FileData;
CString Fast;
FileData = gcap.strFileName;
Fast = FileData.Left(4);//左取文件4字节(d:\\-z:\\盘符)
fResult = GetDiskFreeSpaceEx (
Fast,
(PULARGE_INTEGER)&Available,
(PULARGE_INTEGER)&Total,
(PULARGE_INTEGER)&Free);
if(fResult)//通过返回的BOOL数据判断驱动器是否在工作状态
{
//::AfxMessageBox("设备已准备好 ");
gcap.DiskFreeCk = 2;
}
else
{
//::AfxMessageBox("设备未准备好 ");
gcap.DiskFreeCk = 0;
}
return S_OK;
}
//释放全部应用-------------------------------------------------------------------------
HRESULT CCaptureDlg::AllRelease()
{
try //执行命令行
{
KillTimer(0); //销毁0定时器
if (m_FilterGraph)
{
m_MediaControl->Stop(); //停止播放
}
if (m_MediaSeeking)
{
m_MediaSeeking->Release();
m_MediaSeeking = NULL;
}
if (m_MediaControl)
{
m_MediaControl->Release();
m_MediaControl = NULL;
}
if (m_MediaEventEx)
{
m_MediaEventEx->Release();
m_MediaEventEx = NULL;
}
if (m_BasicVideo)
{
m_BasicVideo->Release();
m_BasicVideo = NULL;
}
if (m_BasicAudio)
{
m_BasicAudio->Release();
m_BasicAudio = NULL;
}
if (m_VideoWindow)
{
m_VideoWindow->put_Visible(OAFALSE);
m_VideoWindow->put_MessageDrain((OAHWND)NULL);
m_VideoWindow->put_Owner(OAHWND(0));
m_VideoWindow->Release();
m_VideoWindow = NULL;
}
if (m_pCapture)
{
m_pCapture->Release(); //释放图表
m_pCapture = NULL;
}
if (m_FilterGraph)
{
m_FilterGraph->Release(); //释放图表管理器
m_FilterGraph = NULL;
}
gcap.iWMAFilterOutput->Release();
gcap.iHtAudioFilterInput->Release();
gcap.iHtAudioFilterOutput->Release();
gcap.iAudioFilterInput->Release();
gcap.iAudioFilterGraph->Release(); //音频筛选器图表
gcap.iAudioFilterGraph = NULL;
SetTimer(0, 600, NULL);//重新启动计时器
}
catch(...) //异常处理
{
if (m_FilterGraph)
{
m_MediaControl->Stop(); //停止播放
}
SetTimer(1, 2000, NULL);//启动1计时器
}
return S_OK;
}
//设置播放图像窗口大小-----------------------------------------------------------------
bool CCaptureDlg::ResizeVideoWindow(long inLeft, long inTop, long inWidth, long inHeight)
{
if (m_VideoWindow)
{
long lVisible = OATRUE;
m_VideoWindow->get_Visible(&lVisible);
// Hide the video window first
m_VideoWindow->put_Visible(OAFALSE);
m_VideoWindow->put_Left(inLeft);
m_VideoWindow->put_Top(inTop);
m_VideoWindow->put_Width(inWidth);
m_VideoWindow->put_Height(inHeight);
// Restore the video window
m_VideoWindow->put_Visible(lVisible);
return true;
}
return false;
}
//退出系统-----------------------------------------------------------------------------
void CCaptureDlg::OnCancel()
{
for(int i = 0 ; i < 800002 ; i++) //缓冲
{
if(i > 800000)
{
gcap.mUnGlobal = 1;//退出加锁读写剪贴板
try
{
m_MediaControl->Stop(); //停止播放
AllRelease(); //释放全部应用
KillTimer(0); //销毁0定时器
CDialog::OnCancel();//退出系统
}
catch(...) //异常处理
{
KillTimer(0); //销毁0定时器
CDialog::OnCancel();//退出系统;
}
}
}
}
//CString str;
//str.Format("%s",s);
//::AfxMessageBox("连接声卡上的接口是 = " + str);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -