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

本文详细介绍了如何在Cocos2d-win32Application项目中集成VLC播放器,包括配置Visual Studio 2010、创建MoviePlayer类及其相关方法,并整合到HelloWorldScene的初始化流程中。

原文地址链接: http://www.cnblogs.com/evan-cai/
打开Visual Studio 2010,新建一个Cocos2d-win32 Application项目,我这里叫Cocos2dPlayer,配置好整个项目,直到可以编译通过且能运行(如何配置可以参考网上很多帖子教程,在此就不多说,见谅)。另外还要加上vlc头文件、库文件和动态链接库文件,我是直接下载vlc播放器的安装版本然后在sdk目录中把 vlc 文件夹拷贝到Visual Studio 2010的VC\include目录下,库文件和动态链接库文件需要放在本项目的Debug.win32和Release.win32目录下。如果编译出错,需要把 vlc 文件夹下的 plugins 文件夹也拷到Debug.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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值