I finally could connect the video to a cocos2d-x node. Here’s the thing. You have to modify a bit some internals of cocos2d-x.
Download the cocos2d-x from out of the box. You have to modify cocos2dx/platform/blackberry/CCEGLView.cpp to include this snippet (in bold) at the end of the CCEGLView::initGL() function.
bool CCEGLView::initGL()
{
//...
m_obScreenSize.width = width;
m_obScreenSize.height = height;
// Set vsync.
// eglSwapInterval(m_eglDisplay, screenSwapInterval);
if (screen_create_window_group(m_screenWindow, "videowindowgroup") != 0) { //Add
return false; //these
} //lines
return true;
}
Have a node subclass with this code:
#include
#include
#include
#include
#include
#include "VideoScene.h"
USING_NS_CC;
// on "init" you need to initialize your instance
bool VideoScene::init()
{
int rc;
I18n::init();
if ( !CCLayer::init() )
{
return false;
}
CCSize size = CCDirector::sharedDirector()->getWinSize();
// I/O devices
static char *audio_device_url = (char *)"audio:default";
static char video_device_url[PATH_MAX];
rc = snprintf(video_device_url, PATH_MAX, "screen:?winid=%s&wingrp=%s", "videowindowgroup", "videowindowgroup");
if (rc >= PATH_MAX) {
fprintf(stderr, "URL too long\n");
}
// Name of video context...with a random number appended.
static char video_context_name[PATH_MAX];
rc = snprintf(video_context_name, PATH_MAX, "spdvideocontext");
if (rc >= PATH_MAX) {
fprintf(stderr, "Video context name too long\n");
}
/*
* Configure mm-renderer.
*/
mmr_connection = mmr_connect(NULL);
if (mmr_connection == NULL) {
return false;
}
mmr_context = mmr_context_create(mmr_connection, video_context_name, 0, S_IRWXU|S_IRWXG|S_IRWXO);
if (mmr_context == NULL) {
return false;
}
/*
* Configure video and audio output.
*/
video_device_output_id = mmr_output_attach(mmr_context, video_device_url, "video");
if (video_device_output_id == -1) {
return false;
}
audio_device_output_id = mmr_output_attach(mmr_context, audio_device_url, "audio");
if (audio_device_output_id == -1) {
return false;
}
// Build up the path where our bundled resource is.
char cwd[PATH_MAX];
char media_file[PATH_MAX];
getcwd(cwd,PATH_MAX);
rc = snprintf(media_file, PATH_MAX, "file://%s/%s", cwd, CCFileUtils::sharedFileUtils()->fullPathFromRelativePath("yourvideo.mp4"));
if ((rc == -1) || (rc >= PATH_MAX)) {
return false;
}
/*
* Attach the input media.
*/
if (mmr_input_attach(mmr_context, media_file, "track") != 0) {
return false;
}
int video_speed = 1000;
/*
* Set the speed to 1 to play the video initially
*/
if (mmr_speed_set(mmr_context, video_speed) != 0) {
return EXIT_FAILURE;
}
/*
* Change to the play state, although speed is zero
*/
if (mmr_play(mmr_context) != 0) {
return false;
}
return true;
}
CCScene* VideoScene::scene()
{
// 'scene' is an autorelease object
CCScene *scene = CCScene::create();
// 'layer' is an autorelease object
VideoScene *layer = VideoScene::create();
// add layer as a child to scene
scene->addChild(layer);
// return the scene
return scene;
}
void VideoScene::draw() {
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); //Video is behing OpenGL context
}
This is the corresponding header:
#ifndef VIDEOSCENE_H_
#define VIDEOSCENE_H_
#include
#include "cocos2d.h"
class VideoScene: public cocos2d::CCLayer {
public:
// Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
virtual bool init();
// there's no 'id' in cpp, so we recommand to return the exactly class pointer
static cocos2d::CCScene* scene();
virtual void draw();
// implement the "static node()" method manually
CREATE_FUNC(VideoScene);
// Renderer variables
mmr_connection_t* mmr_connection;
mmr_context_t* mmr_context;
// I/O variables
int video_device_output_id;
int audio_device_output_id;
};
#endif /* VIDEOSCENE_H_ */
You are free to move the “videowindowgroup” to a #include if you want to prevent repeating the string everywhere. You should also use the BB event system to capture when the video finishes playing, but that’s outside of this post