您的位置:首页 > 编程语言 > C语言/C++

visual c++ 音频视频处理技术及工程实践

2011-10-20 12:03 609 查看

10.19

这里我写好了界面,但我不知道8.2节具体是做什么工作的,所以我跳过了

8.2,首先创建一个最简单的媒体播放器。

8.3 我所做的工作步骤是:

    1:给打开按钮添加了事件响应函数

    2:在BOOL CMediaPlayerApp::InitInstance()里添加了//初始化COM

CoInitialize(NULL);

3:我将code里的打开的事件响应函数的代码复制到我了我的工程里面。

#if 1

CString strFilter = _T("AVI File (*.avi) | *.avi|");

strFilter += "MPEG File (*.mpg; *.mpeg) | *.mpg; *.mpeg|";

strFilter += "MP3 File (*.mp3) | *.mp3|";

strFilter += "WMA File (*.wma) | *.wma|";

strFilter += "All File (*.*) | *.*|";

#else

CString strFilter = _T("AVI File (*.avi)|*.avi|MPEG File (*.mpg)|*.mpg|MP3 File (*.mp3)|*.mp3|All Files (*.*)|*.*||");

#endif

CFileDialog dlg(TRUE, NULL, NULL, OFN_PATHMUSTEXIST|OFN_HIDEREADONLY, strFilter, this);

if (dlg.DoModal() == IDOK)

{

m_sourceFile = dlg.GetPathName();

m_mediaFileName =GetFileTitleFromFileName(m_sourceFile,1);

CreateGraph();

}

这里有几个问题,1:这里和书中的代码不一样。

2:编译一样有下面的错误

mediaplayerdlg.cpp(172) : error C2065: 'm_sourceFile' : undeclared identifier
mediaplayerdlg.cpp(173) : error C2065: 'm_mediaFileName' : undeclared identifier
mediaplayerdlg.cpp(173) : error C3861: 'GetFileTitleFromFileName': identifier not found
mediaplayerdlg.cpp(175) : error C3861: 'CreateGraph': identifier not found

第一二个错误好解决,我的解决方法是。m_sourceFile m_mediaFileName 实际上是CMediaPlayerDlg类的两个成员变量,加进去就可以。
public:
CString m_sourceFile; // m_sourceFile 表示的是媒体的路径

CString m_mediaFileName; // m_mediaFileName 表示是的媒体的文件名。

GetFileTitleFromFileName 完成的功能是从路径中获取多媒体文件的名称。这个函数在MSDN没有找到, 我姑计是作者自己写的一个函数。

CreateGraph 完成的功能是创建链表,连接滤波器。这个函数在MSDN没有找到,我姑计是作者自己写的一个函数。

基于此,我是这样办的。

首先处理GetFileTitleFromFileName 我在MediaPlayerDlg.h : 头文件里添加了代码

public:
CString GetFileTitleFromFileName(CString FileName, BOOL Ext);

然后在MediaPlayerDlg.cpp文件里添加了这个函数的实现。

CString CMediaPlayerDlg::GetFileTitleFromFileName(CString FileName, BOOL Ext)

{

int Where;

Where = FileName.ReverseFind('\\');

if (Where == -1)

Where = FileName.ReverseFind('/');

CString FileTitle = FileName.Right(FileName.GetLength() - 1 - Where);

if (!Ext)

{

int Which = FileTitle.ReverseFind('.');

if (Which != -1)

FileTitle = FileTitle.Left(Which);

}

return FileTitle;

} // 我记得应该有三个地方要改的,可是我找不到地方,这里我就不管了,反正编译只有一个错误了。

接着处理CreateGraph :

我按照我先前的做法void CreateGraph(); void DestroyGraph(); 两个函数,可是我却发现了好多的错误。我都快晕了。

mediaplayerdlg.cpp(204) : error C2065: 'm_pFilterGraph' : undeclared identifier
mediaplayerdlg.cpp(204) : error C2061: syntax error : identifier 'CDXGraph'
mediaplayerdlg.cpp(205) : error C2227: left of '->Create' must point to class/struct/union/generic type type is ''unknown-type''
mediaplayerdlg.cpp(210) : error C2227: left of '->RenderFile' must point to class/struct/union/generic type type is ''unknown-type''
mediaplayerdlg.cpp(217) : error C2227: left of '->SetDisplayWindow' must point to class/struct/union/generic type type is ''unknown-type''
mediaplayerdlg.cpp(217) : error C2065: 'm_videoWindow' : undeclared identifier
mediaplayerdlg.cpp(217) : error C2228: left of '.GetSafeHwnd' must have class/struct/union
type is ''unknown-type''
mediaplayerdlg.cpp(219) : error C2227: left of '->SetNotifyWindow' must point to class/struct/union/generic type type is ''unknown-type''
mediaplayerdlg.cpp(221) : error C2227: left of '->Pause' must point to class/struct/union/generic type type is ''unknown-type''
mediaplayerdlg.cpp(231) : error C2227: left of '->Stop' must point to class/struct/union/generic type type is ''unknown-type''
mediaplayerdlg.cpp(232) : error C2227: left of '->SetNotifyWindow' must point to class/struct/union/generic type type is ''unknown-type''
mediaplayerdlg.cpp(234) : error C2541: 'delete' : cannot delete objects that are not pointers

我觉得我应该是没有添加CDXGraph这个类,所以我加了上去。并在CMediaPlayerDlg 类的头文件里加了#include "CDXGraph.h" 还是有很多错误,没办法,还得一个一个。

经过纠结 我只是没有添加几个变量,添加一下就可以了,CStatic m_videoWindow; CDXGraph *m_pFilterGraph; # pragma comment (lib , "strmiids.lib") 加了这里基本上就没有错了,呵呵,

4:接着我给PLAY按钮增加响应函数。并添加代码。

if (m_pFilterGraph)

{

SetWindowText(_T("1倍速播放") + m_mediaFileName);

m_pFilterGraph->Run();

//m_volume = m_pFilterGraph->GetAudioVolume();

//m_sliderAudio.SetPos(m_volume);

//m_volume = 100;

m_pFilterGraph->ChangeAudioVolume(m_volume);

m_sliderVolume.SetPos(m_volume);

if (m_playerTimer == 0)

{

m_playerTimer = SetTimer(SLIDER_TIMER, 100, NULL);

} // 在这里我把这部代码注释,发可以放了,

}

但是有小问题,1:图像初始化的时候不显示在图像控件上。

2:视频很小。

实然,我感觉这个错误是我在生成窗口的时间,点一个叫什么框架的东西,于是,我打算重来一遍。

如果设置是

结果是这个窗口在桌面的左顶上角,且停在最小化状态。

如果选择是这样的。

这时编译窗口显示正常,且开始显示在中间。

如果不要thick frame 选项,结果跟第二个是一样的。

综上,我选择只要MAX BOX MIN BOX两个选择。(下面的工程设计都是这样的,希望不会错。) 这里我再时间去纠结代码。

经过我再一次实验,发现不是我刚刚发现的错误。现象依旧,怎么办,我还没有吃饭!!!。

10.20.2011

继续昨天的工作 , 我又发现,很可能跟位图和图像控件有关系,于是,我去找找线索。

找了没有线索。

我突然发现是不是有一个函数可以将坐标进行转换的。
public:
afx_msg BOOL OnEraseBkgnd(CDC* pDC); 于是我找到了它,现在试一下。

唉也不是,

于是我只能接着往前走了,不管这个问题。上面的代码我没有注释,因为好像对程序没有什么影响。

昨天有一个问题就是在按键PLAY里面有一段代码不知道是什么意思 。我这里把它加进去,

终于找到视频显示在顶端的原因了。

m_videoWindow 是图像控件变量,我没有将它和控件相关联,而仅仅是添加这个成员变量。唉控件变量。

m_sliderPlayer m_sliderVolume 这两个也是控件变量。

当我加进play按钮代码发现了很多问题。比如在对话框初始化的时候,有这么些代码是我没有注意到的。

// TODO: Add extra initialization here

m_pFilterGraph = NULL;

m_sliderPlayer.SetRange(0, 1000);

m_sliderPlayer.SetPos(0);

m_sliderVolume.SetRange(50,100);

m_sliderVolume.SetPos(50);

m_volume = 100;

这应该很重要。另外我给函数添加了两个消息。一个是WM_TIMER消息,另一个是WM_HSCROLL 消息。完成滚动条滚动时控制的命令。

接下来,给STOP按钮添加命令响应消息。 添加下面的代码

if (m_pFilterGraph != NULL)

{

m_pFilterGraph->Stop();

}

给暂停添加命令响应消息。添加下面的代码。

if (m_pFilterGraph != NULL)

{

m_pFilterGraph->Pause();

}

给退出添加命令响应消息。添加下面的代码。

OnBnClickedButtonStop();

CoUninitialize();

CDialog::OnOK();

给抓图添加命令响应消息。添加下面的代码。

static int c = 0;

TCHAR szFilename[MAX_PATH];

DWORD dwPathLen = 0;

if((dwPathLen = ::GetModuleFileName(::AfxGetInstanceHandle(),szFilename, MAX_PATH ))== 0)

{

return;

}

for( int i=dwPathLen-1; i>=0; i--)

{

if(('\\' == szFilename[i]) || ('/' == szFilename[i]))

{

break;

} else {

szFilename[i] = '\0';

}

}

CString str;

str.Format(_T("%s"),szFilename);

CString strTemp;

strTemp.Format(_T("%d"),c);

str += strTemp + _T(".bmp");

c++;

TCHAR *p=str.GetBuffer(str.GetLength());

str.ReleaseBuffer();

if (m_pFilterGraph != NULL)

{

if (m_pFilterGraph->SnapshotBitmap(p))

{

}else

MessageBox(_T("抓图失败!"));

}

这里我注意到,图片被保存到工程目录下,。但当我抓图完成后。播放器界面就会显示最开始的位图,只有当窗口重绘时才会显示动态的影像。这里应该是要对图像进行窗口重绘。这个工作我打算最后做。这里在书的P328面有说明 ,不全是我先前想的那样。这里提供了另一种方法。 当然,在窗口切换时还是会有不能正常显示的现象。

至此,我已经完成了一个小小的视频播放器了。

接着完成P320D面以后的工作。

捕获媒体播放的消息和各种事件,向窗口发送通知。

 这里按照书上做没有错。

接着升级我的播放器。

  为了在视频中显示窗口,单击鼠标右键激活菜单,需要我们重载窗口消息捕获处理函数PreTranslateMessage .

CToolTipCtrl m_tooltip 我不知道这是一个什么控件类型。我只能COPY

接着完成书中的内容,就可以实现一个播放器的功能了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: