好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

用Cocos2dx和libvlc写一个跨平台播放器

用Cocos2dx和libvlc写一个跨平台播放器

简介:本文使用cocos2d-x和libvlc两大免费开源的跨平台框架,实现一个视频播放器。开发工具使用Visual Studio 2010,测试运行平台为Windows(其它平台暂时没测试)。cocos2d-x版本2.0.3,VLC版本2.0.5。

    目前游戏程序开发者大部分在以下几个平台上开发游戏:Windows、Mac OS X、IOS和Android。开发2D游戏且跨平台,cocos2d-x是个非常不错的选择,而libvlc也提供了各大平台的支持,因此使用这两大框架基本可以做到一次编写,全平台运行的目的。

    打开Visual Studio 2010,新建一个Cocos2d-win32 Application项目,我这里叫Cocos2dPlayer,配置好整个项目,直到可以编译通过且能运行(如何配置可以参考网上很多帖子教程,在此就不多说,见谅)。另外还要加上vlc头文件、库文件和动态链接库文件,我是直接下载vlc播放器的安装版本然后在sdk目录中把vlc文件夹拷贝到Visual Studio 2010的VC\include目录下,库文件和动态链接库文件则放在本项目的Debug.win32和Release.win32目录下。

    接下来进入正题:

    创建文件MoviePlayer.h和MoviePlayer.cpp

MoviePlayer.h

 #ifndef __MOVIEPLAYER_H__
  #define  __MOVIEPLAYER_H__

 /*  ***************************************************************************
  http://www.cnblogs.com/evan-cai/  

Author: Evan-Cai
Date: 2013-01-25
***************************************************************************  */  

#include  <vlc\vlc.h> 
#include   "  sprite_nodes\CCSprite.h  "  

NS_CC_BEGIN

  class  MoviePlayer :  public   CCSprite
{
  public  :
     ~ MoviePlayer();

      static  MoviePlayer * instance( void  );

      bool  init( void  );
      void  play( char  * path);
      void  stop( void  );
      void  pause( void  );
      void  draw( void  );
  protected  :
    MoviePlayer();

  private  :

    libvlc_instance_t  * vlc;
    libvlc_media_player_t  * vlc_player;

    unsigned   int   width;
    unsigned   int   height;

      static  MoviePlayer *  _instance; 
};

NS_CC_END

  #endif 

MoviePlayer.cpp

#include  "  MoviePlayer.h  "  
#include   "  CCDirector.h  "  

NS_CC_BEGIN

MoviePlayer  * MoviePlayer::_instance =  0  ;

  static   char  * videobuf =  0  ;

  static   void  * lock ( void  *data,  void  ** p_pixels)
{
     *p_pixels =  videobuf;
      return   NULL;
}

  static   void  unlock( void  *data,  void  *id,  void  * const  * p_pixels)
{
    assert(id  ==  NULL);
}

  static   void  display( void  *data,  void  * id)
{
    (  void  ) data;
    assert(id  ==  NULL);
}

MoviePlayer::MoviePlayer():
vlc(  0 ), vlc_player( 0  )
{
    init();
}

MoviePlayer:: ~ MoviePlayer()
{
    CCSprite:: ~ CCSprite();
    free(videobuf);

    libvlc_media_player_stop(vlc_player);
    libvlc_media_player_release(vlc_player);
    libvlc_release(vlc);
}

  bool  MoviePlayer::init( void  )
{
    vlc  = libvlc_new( 0  , NULL);
    vlc_player  =  libvlc_media_player_new(vlc);

    CCSize size  = CCDirector::sharedDirector()-> getWinSize();
    width  =  size.width;
    height  =  size.height;
    videobuf  = ( char  *)malloc((width * height) <<  2  );
    memset(videobuf,   0 , (width * height) <<  2  );
    libvlc_video_set_callbacks(vlc_player,   lock  , unlock, display, NULL);
    libvlc_video_set_format(vlc_player,   "  RGBA  " , width, height, width <<  2  );
    
    CCTexture2D  *texture =  new   CCTexture2D();
    texture -> initWithData(videobuf, kCCTexture2DPixelFormat_RGBA8888, width, height, size);
      return   initWithTexture(texture);
}

  void  MoviePlayer::play( char  * path)
{
    libvlc_media_t  *media =  libvlc_media_new_path(vlc, path);
    libvlc_media_player_set_media(vlc_player, media);
    libvlc_media_release(media);
    libvlc_media_player_play(vlc_player);
}

  void  MoviePlayer::stop( void  )
{
    libvlc_media_player_stop(vlc_player);
}

  void  MoviePlayer::pause( void  )
{
    libvlc_media_player_pause(vlc_player);
}

  void  MoviePlayer::draw( void  )
{

    CC_PROFILER_START_CATEGORY(kCCProfilerCategorySprite,   "  CCSprite - draw  "  );

    CCAssert( !m_pobBatchNode,  "  If CCSprite is being rendered by CCSpriteBatchNode, CCSprite#draw SHOULD NOT be called  "  );

    CC_NODE_DRAW_SETUP();

    ccGLBlendFunc( m_sBlendFunc.src, m_sBlendFunc.dst );

      if  (m_pobTexture !=  NULL)
    {
        ccGLBindTexture2D( m_pobTexture -> getName() );
        glTexImage2D(GL_TEXTURE_2D,   0 , GL_RGBA, width, height,  0 , GL_RGBA, GL_UNSIGNED_BYTE,(uint8_t * ) videobuf);
    }
      else  
    {
        ccGLBindTexture2D(  0  );
    }

      // 
     //   Attributes
      //
  
    ccGLEnableVertexAttribs( kCCVertexAttribFlag_PosColorTex );

  #define  kQuadSize sizeof(m_sQuad.bl)
     long  offset = ( long )& m_sQuad;

      //   vertex 
     int  diff =  offsetof( ccV3F_C4B_T2F, vertices);
    glVertexAttribPointer(kCCVertexAttrib_Position,   3 , GL_FLOAT, GL_FALSE, kQuadSize, ( void *) (offset +  diff));

      //   texCoods 
    diff =  offsetof( ccV3F_C4B_T2F, texCoords);
    glVertexAttribPointer(kCCVertexAttrib_TexCoords,   2 , GL_FLOAT, GL_FALSE, kQuadSize, ( void *)(offset +  diff));

      //   color 
    diff =  offsetof( ccV3F_C4B_T2F, colors);
    glVertexAttribPointer(kCCVertexAttrib_Color,   4 , GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, ( void *)(offset +  diff));

    glDrawArrays(GL_TRIANGLE_STRIP,   0 ,  4  );

    CHECK_GL_ERROR_DEBUG();

    CC_INCREMENT_GL_DRAWS(  1  );

    CC_PROFILER_STOP_CATEGORY(kCCProfilerCategorySprite,   "  CCSprite - draw  "  );
}

MoviePlayer  *  MoviePlayer::instance()
{
      if (_instance ==  0  )
        _instance  =  new   MoviePlayer();
      return   _instance;
}

NS_CC_END 

    然后编辑HelloWorldScene.cpp文件的init函数,最后函数如下:
    (说明:我把HelloWorld类改成了Cocos2dPlayer类,所以浏览本文章的朋友只要把下面的Cocos2dPlayer::init改成HelloWorld::init就可以编译运行了,另外Can't Wait.mp4是我在网络上下载下来的mp4文件,请朋友你自行更改名称^_^)

 bool   Cocos2dPlayer::init()
{
      bool  bRet =  false  ;
      do   
    {
          ////////////////////////////////////////////////////////////////////////  // 
         //   super init first 
         ////////////////////////////////////////////////////////////////////////  // 
 
        CC_BREAK_IF( !  CCLayer::init());

          ////////////////////////////////////////////////////////////////////////  // 
         //   add your codes below... 
         ////////////////////////////////////////////////////////////////////////  // 

         //   1. Add a menu item with "X" image, which is clicked to quit the program.

          //   Create a "close" menu item with close icon, it's an auto release object. 
        CCMenuItemImage *pCloseItem =  CCMenuItemImage::create(
              "  CloseNormal.png  "  ,
              "  CloseSelected.png  "  ,
              this  ,
            menu_selector(Cocos2dPlayer::menuCloseCallback));
        CC_BREAK_IF( !  pCloseItem);

          //   Place the menu item bottom-right conner. 
        pCloseItem->setPosition(ccp(CCDirector::sharedDirector()->getWinSize().width -  20 ,  20  ));

          //   Create a menu with the "close" menu item, it's an auto release object. 
        CCMenu* pMenu =  CCMenu::create(pCloseItem, NULL);
        pMenu -> setPosition(CCPointZero);
        CC_BREAK_IF( !  pMenu);

          //   Add the menu to Cocos2dPlayer layer as a child layer. 
         this ->addChild(pMenu,  1  );

          //   2. Add a label shows "Hello World".

          //   Create a label and initialize with string "Hello World".
          //  CCLabelTTF* pLabel = CCLabelTTF::create("Let's PLAY!", "Arial", 24);
          //  CC_BREAK_IF(! pLabel);

          //   Get window size and place the label upper.  
        CCSize size = CCDirector::sharedDirector()-> getWinSize();
          //  pLabel->setPosition(ccp(size.width / 2, size.height - 50));

          //   Add the label to Cocos2dPlayer layer as a child layer.
          //  this->addChild(pLabel, 1);

          //   3. Add add a splash screen, show the cocos2d splash image. 
        MoviePlayer* pPlayer =  MoviePlayer::instance();

          //   Place the sprite on the center of the screen 
        pPlayer->setPosition(ccp(size.width/ 2 , size.height/ 2  ));

          //   Add the sprite to Cocos2dPlayer layer as a child layer. 
         this ->addChild(pPlayer,  0  );

        pPlayer ->play( "  Can't Wait.mp4  "  );

        bRet  =  true  ;
    }   while  ( 0  );

      return   bRet;
} 

 

 

分类:  Cocos2d-x

标签:  Cocos2d-x libvlc 跨平台 播放器 Player Play Video

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于用Cocos2dx和libvlc写一个跨平台播放器的详细内容...

  阅读:39次