用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 #endifMoviePlayer.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写一个跨平台播放器的详细内容...
声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://haodehen.cn/did47057