植物大战僵尸游戏开发教程专栏地址http://t.csdnimg.cn/8UFMs
VLC库
在Cocos2d-x游戏开发框架中,没有实现windows平台视频播放的功能,需要自定义实现。在本项目中使用vlc库实现windows平台的视频播放功能。
vlc官网:网址
下载完成后,找到所下载文件的sdk目录 ,里面有实现视频播放的库文件。将头文件和库文件配置到项目中,然后使用其播放视频。
代码文件位置
代码文件的位置在Class\Based文件夹中。
VideoPlayer.h
在实现的头文件中引入vlc库的头文件。
#include "Based/vlc/vlc.h"
将用到的库文件进行声明。
#pragma comment (lib, "libvlc.lib")
#pragma comment (lib, "libvlccore.lib")
定义VideoPlayer类实现视频播放,继承Sprite。
class VideoPlayer : public Sprite
{
public:
~VideoPlayer();
static VideoPlayer* instance(void);
bool init(void);
void play(const char* path);
void play();
void stop(void);
void pause(void);
void draw(Renderer* renderer, const Mat4& transform, uint32_t flags);
void changeVideoState();
void setPrecent(const float precent);
float getPrecent();
void setVolume(int volume);
int getVolume() const;
void setVideoTime(const libvlc_time_t time);
libvlc_time_t getVideoTime() const;
protected:
VideoPlayer();
private:
libvlc_instance_t* vlc;
libvlc_media_player_t* vlc_player;
libvlc_media_list_player_t* vlc_list_player;
libvlc_media_list_t* vlc_list;
libvlc_media_t* vlc_media;
libvlc_time_t video_length;
unsigned int width;
unsigned int height;
static VideoPlayer* _instance;
};
VideoPlayer.cpp
构造函数
VideoPlayer::VideoPlayer() :
vlc(0), vlc_player(0), video_length(-1)
{
init();
}
析构函数
VideoPlayer::~VideoPlayer()
{
CCSprite::~CCSprite();
free(videobuf);
libvlc_media_player_stop(vlc_player);
libvlc_media_player_release(vlc_player);
libvlc_release(vlc);
}
instance函数
VideoPlayer* VideoPlayer::instance()
{
if (_instance == nullptr)
_instance = new VideoPlayer();
return _instance;
}
init函数
bool VideoPlayer::init(void)
{
vlc = libvlc_new(0, nullptr);
vlc_player = libvlc_media_player_new(vlc);
Size size = Director::getInstance()->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, nullptr);
libvlc_video_set_format(vlc_player, "RGBA", width, height, width << 2);
Texture2D* texture = new Texture2D();
texture->initWithData(videobuf, sizeof(videobuf), Texture2D::PixelFormat::RGBA8888, width, height, size);
return initWithTexture(texture);
}
play(path)函数
void VideoPlayer::play(const char* path)
{
vlc_list = libvlc_media_list_new(vlc);
vlc_media = libvlc_media_new_path(vlc, path);
libvlc_media_list_add_media(vlc_list, vlc_media);
vlc_list_player = libvlc_media_list_player_new(vlc);
libvlc_media_list_player_set_media_list(vlc_list_player, vlc_list);
libvlc_media_list_player_set_media_player(vlc_list_player, vlc_player);
libvlc_media_list_player_set_playback_mode(vlc_list_player, libvlc_playback_mode_loop);
libvlc_media_list_player_play(vlc_list_player);
}
play()、stop()、pause()函数
void VideoPlayer::play()
{
libvlc_media_player_play(vlc_player);
}
void VideoPlayer::stop(void)
{
libvlc_media_player_stop(vlc_player);
}
void VideoPlayer::pause(void)
{
libvlc_media_player_pause(vlc_player);
}
draw函数
void VideoPlayer::draw(Renderer* renderer, const Mat4& transform, uint32_t flags)
{
CC_PROFILER_START_CATEGORY(kCCProfilerCategorySprite, "CCSprite - draw");
CC_NODE_DRAW_SETUP();
GL::blendFunc(_blendFunc.src, _blendFunc.dst);
if (_texture != NULL)
{
GL::bindTexture2D(_texture->getName());
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (uint8_t*)videobuf);
}
else
{
GL::bindTexture2D(static_cast<GLuint>(0));
}
//
// Attributes
//
GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX);
#define kQuadSize sizeof(_quad.bl)
long offset = (long)&_quad;
// vertex
int diff = offsetof(ccV3F_C4B_T2F, vertices);
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, kQuadSize, (void*)(offset + diff));
// texCoods
diff = offsetof(ccV3F_C4B_T2F, texCoords);
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORD, 2, GL_FLOAT, GL_FALSE, kQuadSize, (void*)(offset + diff));
// color
diff = offsetof(ccV3F_C4B_T2F, colors);
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_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");
}
changeVideoState函数
void VideoPlayer::changeVideoState()
{
switch (libvlc_media_get_state(vlc_media))
{
case libvlc_state_t::libvlc_Playing: pause(); break;
case libvlc_state_t::libvlc_Paused: play(); break;
default: break;
}
}
setVideoTime、getVideoTime函数
void VideoPlayer::setVideoTime(const libvlc_time_t time)
{
libvlc_media_player_set_time(vlc_player, time);
}
libvlc_time_t VideoPlayer::getVideoTime() const
{
return libvlc_media_player_get_time(vlc_player);
}
setPrecent、 getPrecent函数
void VideoPlayer::setPrecent(const float precent)
{
video_length < 0 ? video_length = libvlc_media_get_duration(vlc_media) : video_length;
libvlc_media_player_set_time(vlc_player, static_cast<libvlc_time_t>(video_length * precent));
}
float VideoPlayer::getPrecent()
{
auto videoCurrentTime = libvlc_media_player_get_time(vlc_player);
video_length < 0 ? video_length = libvlc_media_get_duration(vlc_media) : video_length;
if (videoCurrentTime != -1 && video_length != -1)
{
return videoCurrentTime * 1.0f / video_length * 100;
}
return -1;
}
setVolume、getVolume 函数
void VideoPlayer::setVolume(int volume)
{
if (volume < 0) volume = 0;
if (volume > 100)volume = 100;
libvlc_audio_set_volume(vlc_player, volume);
}
int VideoPlayer::getVolume() const
{
return libvlc_audio_get_volume(vlc_player);
}