用Cocos2d-x和libvlc写一个跨平台播放器

来源:互联网 发布:2017年淘宝双十一报名 编辑:程序博客网 时间:2024/06/06 02:40

简介:本文使用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-CaiDate: 2013-01-25****************************************************************************/#include <vlc\vlc.h>#include "sprite_nodes\CCSprite.h"NS_CC_BEGINclass 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_BEGINMoviePlayer * 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;}
复制代码

 本人QQ214390117,如有问题可以联系:)


转自http://www.cnblogs.com/evan-cai/archive/2013/01/25/2876803.html

原创粉丝点击