[摘要]摘要 本文主要介绍了Windows平台上Visual C++ 6利用ATL库和QuickTime SDK开发播放QuickTime多媒体软件。为从事多媒体播放开发工作者提供借鉴和参考。关键词 多...
摘要 本文主要介绍了Windows平台上Visual C++ 6利用ATL库和QuickTime SDK开发播放QuickTime多媒体软件。为从事多媒体播放开发工作者提供借鉴和参考。
关键词 多媒体 播放 QuickTime ATL
1 前言
在当今多媒体播放软件主要有Windows media player、Real player和QuickTime。 Apple公司的QuickTime于1991年登台亮相,是Apple公司面向专业视频编辑、Web网站创建和CD-ROM内容制作领域开发的多媒体技术平台,QuickTime支持几乎所有主流的个人计算机平台,是数字媒体领域事实上的工业标准,是创建3D动画、实时效果、虚拟现实、A/V和其他数字流媒体的重要基础。
由于众多企业有对QuickTime player应用的需求,在国内外相关资料中有用Windows SDK或MFC的相关应用,本文试用小巧的ATL库和QuickTime SDK开发定制QuickTime 多媒体播放软件做了分析。
2 QuickTime Windows程序的开发概述
2.1开发前的准备
登陆Apple官方网站下载QuickTime SDK和了解有关技术资料。
由于QuickTime原先是为Mac OS设计,所以它里面的许多概念和函数的调用都是面向Mac。
表1 Windows and QTML 术语比较
Windows 术语
QTML 对应术语
Message ( MSG )
Event ( EventRecord )
Graphics Device Interface (GDI)
QuickDraw
Device context ( DC )
Graphics port ( CGrafPort )
Window handle ( HWND )
Window pointer ( CWindowPtr )
Common Dialog Box Library
Standard File Package
对于一个原来是Windows程序员必须对于一些QuickTime概念有些最基本的了解才能比较快的掌握典型QuickTime Windows程序的开发。
2.2开发基本步骤
开发一个简单的QuickTime Windows程序必须采取下面基本步骤加入到Windows应用中。
2.2.1在程序的开头初始化QuickTime媒体层(InitializQTML)和QuickTime(EnterMovies)。
2.2.2和电影窗口建立图形端口的关联(CreatePortAssociation)。
2.2.3打开电影(OpenMovieFile)和得到电影的句柄(NewMovieFromFile)。
2.2.4创建在屏幕上显示电影图像的控件(NewMovieController)。
2.2.5在Windows处理函数中,将接收的Windows消息转换为QTML事件(WinEventToMacEvent)并将它们传到电影控件处理(MCIsPlayerEvent)。
2.2.6如果不在用到,释放电影句柄(DisposeMovie)和电影控件(DisPoseMovieController)。
2.2.7当销毁窗口时,破坏电影图形端口的关联(DestroyPortAssociation)。
3 在ATL上实现播放
3.1用ATL创建Windows窗口
以CWindowImpl为基类,编写自己的窗口类CQTVideoWnd。并且定义宏来接收窗口消息。
#define MY_QT_MSG_HANDLE(func) \
{ \
BOOL bHandled = TRUE; \
lResult; \
func(uMsg,wParam,lParam,bHandled); \
if(bHandled) \
return TRUE; \
}
class CQTVideoWnd:
public CWindowImpl<CVideoPlayerQT>
{
public:
CQTVideoWnd(HWND hParent, RECT& rc, IVideoPlayerNotifySink* pVPSink);
virtual ~ CQTVideoWnd();
public:
BEGIN_MSG_MAP(CVideoPlayerQT)
MY_QT_MSG_HANDLE (NewProc)
END_MSG_MAP()
protected:
LRESULT NewProc(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
……
CQuickTime m_QT;
……
}
CQuickTime为笔者调用QuickTime API的辅助类,后面将介绍。
NewProc成员函数根据接收不同的窗口消息分别调用不同的成员函数处理。
LRESULT CQTVideoWnd::NewProc(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
if(uMsg == WM_ERASEBKGND)
{
bHandled = FALSE;
LRESULT theResult = DefWindowProc(uMsg, wParam, lParam);
m_QT.ProcessMovieEvent (m_hWnd, uMsg, wParam, lParam);
return theResult;
}
else
{
m_QT.ProcessMovieEvent (m_hWnd, uMsg, wParam, lParam);
switch(uMsg)
{
case WM_CREATE:
OnCreate(uMsg, wParam, lParam,bHandled);
break;
case WM_PAINT:
OnPaint(uMsg, wParam, lParam,bHandled);
break;
case WM_DESTROY:
OnDestroy(uMsg, wParam, lParam,bHandled);
break;
default:
bHandled = FALSE;
break;
}
}
return 0;
}
其中OnCreate、OnPaint、OnDestroy等成员函数将根据2.2,分别调用辅助类CQuickTime处理。如
LRESULT CQTVideoWnd::OnCreate(UINT uMsg, WPARAM wParam , LPARAM lParam, BOOL& bHandled)
{
m_QT.OnMovieWindowCreate(m_hWnd,NULL);
return 0;
}
3.2 CQuickTime
CQuickTime为调用QuickTime API函数的辅助类。
3.2.1初始化和退出应用
InitializeQT和Terminate分别为初始化QuickTime媒体层和退出QuickTime媒体层。它们可以在程序的开始和结束。我们在CQTVideoWnd的构造函数和析构函数中调用它们。
BOOL CQuickTime::InitializeQT(IQTEventSink* pQTEventSink /*= NULL*/)
{
……
OSErr Err = noErr;
// Initialize QuickTime Media Layer
Err = InitializeQTML(0);
// Initialize QuickTime
if(Err == noErr)
{
Err = EnterMovies();
}
else
{
Err = QT_NOPLAYER;
}
if(Err == noErr)
{
//Because we can not distinguish the error from which object
//So we marked SetMoviesErrorProc
// SetMoviesErrorProc(MoviesErrorProc,(long)this);
}
else
Err = QT_INITIAL_ERR;
……
return Err == noErr ? TRUE : FALSE;
}
如果要得到QuickTime的错误代码,我们可以在初始化完后调用SetMoviesErrorProc函数,但是假如一个应用中有多个QuickTime的电影对象。我们将不能区分错误来自哪个对象。
void CQuickTime::Terminate()
{
// Clean up
ExitMovies();
TerminateQTML();
DebugInfo("CQuickTime::Terminate this = %p,m_pQTEventSink = %p",this,m_pQTEventSink);
}
3.2.2得到电影的句柄
如果是本地文件调用OpenLocalMovie,得到句柄后保存在成员变量里m_Movie。该函数打开电影后创建Movie Controller。Apple公司推荐一般用Movie Controller来播放电影。
BOOL CQuickTime::OpenLocalMovie(LPCSTR fullPath)
{
_ASSERTE(fullPath && m_hViewWnd);
if(!fullPath
关键词:运用ATL完成QuickTime多媒体文件播放