• 用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
  • 相关阅读:
    angularjs1.6.4中使用ng-table出现data.slice is not a function的问题
    使用sql语句获取数据库表的信息
    IIS部署web,字体404的问题
    SQL中partition关键字的使用
    asp.net 配置二级域名的共享session,并实现sso单点登录
    同一浏览器中同一JavaWeb程序不共享session方法
    Liquibase的使用
    对象并不一定都是在堆上分配内存的
    阿里面试题,为什么wait()方法要放在同步块中?
    粗浅看 Tomcat系统架构分析
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2876999.html
Copyright © 2020-2023  润新知