• 用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
  • 相关阅读:
    SAP S/4HANA extensibility扩展原理介绍
    SAP CRM系统订单模型的设计与实现
    使用nodejs代码在SAP C4C里创建Individual customer
    SAP Cloud for Customer Account和individual customer的区别
    Let the Balloon Rise map一个数组
    How Many Tables 简单并查集
    Heap Operations 优先队列
    Arpa’s obvious problem and Mehrdad’s terrible solution 思维
    Passing the Message 单调栈两次
    The Suspects 并查集
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2876999.html
Copyright © 2020-2023  润新知