• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • 利用ATL實現QuickTime多媒體文件播放

    發表于:2007-07-14來源:作者:點擊數: 標簽:
    摘要本文主要介紹了Windows平臺上Visual C++ 6利用ATL庫和QuickTime SDK 開發 播放QuickTime多媒體軟件。為從事多媒體播放開發工作者提供借鑒和參考。 關鍵詞多媒體 播放 QuickTime ATL 1 前言 在當今多媒體播放軟件主要有Windows media player、Real player
    摘要  本文主要介紹了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 || !m_hViewWnd)

             return FALSE;



         VIDEO_STATUE oldState = m_enState;

         

         if ( strlen ((char*)fullPath ) != 0)

         {

             OSErr                   err;

             short                   nTheFile = 0;

             long               lControllerFlags = 0L;

             FSSpec                   sfFile;

             short                   nMovieResFile;

             short                   nMovieResId;

             char               theFullPath[255];



             // Close any previously opened movie

              CloseMovie();

         

             // make a copy of our full path name

             strcpy ( (char *)theFullPath, (const char *) fullPath );        

         

             // convert theFullPath to pstring

              c2pstr( (char*)theFullPath );



             // Make a FSSpec with a pascal string filename

              FSMakeFSSpec(0,0L,(unsigned char*)theFullPath, &sfFile);

             

             // Set the port

              SetGWorld((CGrafPtr)GetHWNDPort(m_hViewWnd), nil);



             // Open the movie file

             err = OpenMovieFile(&sfFile, &nMovieResFile, fsRdPerm);

             if (err == noErr)

             {

                  // Get the Movie from the file

                  nMovieResId = 0;

                  err = NewMovieFromFile(&m_Movie,nMovieResFile,

                                              &nMovieResId,

                                              nil,

                                              newMovieActive, /* flags */

                                              nil);

             

                  // Close the movie file

                  CloseMovieFile(nMovieResFile);           



                  if (err == noErr)

                  {

                       SetMovieTimeScale(m_Movie,1000);

                       

                       m_bBegineDownload = TRUE;



                       // Create the movie controller

                          CreateNewMovieController(m_hViewWnd,m_Movie,&m_MC);

                       p2cstr((unsigned char*)theFullPath);



                       if(m_MC)

                       {

                           return TRUE;

                       }

                       

                  }                   

             }

         }



         CloseMovie();

             

         return FALSE;

    }



    如果是URL文件,調用OpenURLMovie,該函數跟OpenLocalMovie區別主要在于不用NewMovieFromFile而用NewMovieFromDataRef來得到句柄。



         一般電影在創建完Movie Controller后最好調用PrePrerollMovie。

    void CQuickTime::CreateNewMovieController(HWND hwnd, Movie theMovie, MovieController *theMC)

    {

         ……

    PrePrerollMovie(theMovie, GetMovieTime(theMovie, NULL), GetMoviePreferredRate(theMovie), NewMoviePrePrerollCompleteProc(QTPrePrerollCompleteProc), (void *)m_hViewWnd);

    }



    3.2.3關閉電影

         void CQuickTime::CloseMovie(void)

    {

        if (m_MC)

        {

            DisposeMovieController(m_MC);

        }

             if (m_Movie)

              {

                  DisposeMovie(m_Movie);

              }

              m_Movie = NULL;

              m_MC = NULL;

    }



    3.2.4建立和取消電影窗口關聯

    int CQuickTime::OnMovieWindowCreate(HWND hWnd, CREATESTRUCT *lpCreateStruct)

    {



         if ( hWnd != NULL)

         {

              m_hViewWnd = hWnd;                     // the view's hwnd

             

             // Create GrafPort <-> HWND association

              CreatePortAssociation(m_hViewWnd, NULL, kQTMLHandlePortEvents);  

         }



         return 0;

    }

    void CQuickTime::OnMovieWindowDestroy()

    {

         if(m_Movie)

              AbortPrePrerollMovie(m_Movie,noErr);

         



         CGrafPtr     windowPort = NULL;

         

         // close any movies   before destroying PortAssocation

         CloseMovie();



         // Destroy the view's GrafPort <-> HWND association

         if (m_hViewWnd)

              windowPort = (CGrafPtr)GetHWNDPort(m_hViewWnd);

         

         if (windowPort)

              DestroyPortAssociation(windowPort);



    }



    3.2.5控制電影播放

    筆者用控制MCDoAction來控制播放,這樣可以得到播放的狀態,當然也可以調用StartMovie、StopMovie等api函數。例如,

    void CQuickTime::Play()

    {

    if(m_Movie)

    {

         MCDoAction (m_MC, mcActionPlay, (void *)GetMoviePreferredRate(m_Movie));

         long     controllerFlags;

         MCGetControllerInfo(m_MC,&controllerFlags);

         if((controllerFlags&mcInfoIsPlaying))             

              //Now this is playing state.

    }

    }



    4 綜述

      通過上面較為詳細的討論對于建立一個QuickTime的窗口,打開和控制QuickTime電影文件的播放的基本概念和基本過程,我認為QuickTime Player在Windows的平臺的應用將更為寬廣。同時為Apple公司在多媒體播放上的努力而致敬。

    原文轉自:http://www.kjueaiud.com

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>