Forums » C++ Framework » Playing video on BlackBerry »
| Ciro Duran | Playing video on BlackBerry | ||||
|---|---|---|---|---|---|
|
Added by Ciro Duran 8 months ago
Hi everyone, I'm implementing video playback on a game that uses cocos2d-x on the PlayBook. I am aware that the native SDK has an API to play video on the BB graphical context. You can look at the site where everything is explained step by step - https://developer.blackberry.com/native/documentation/Video_playback_overview_1935223_11.html - and there is also an example bundled with the Momentics IDE. But I'm not sure where to start integrating this API inside cocos2d-x. Would I need to subclass a CCNode to incorporate the video playback routines? I'm not sure if the context the RIM screen API points to is the same OpenGL context that cocos2d-x uses. I'm a bit kinda lost on this, so maybe if you could point me in the right direction to start implementing this I would really appreciate it :-) Thanks! My site: http://www.ciroduran.com - Cocos2d-html5 course in Spanish: http://www.elchiguireliterario.com/series/cocos2d-html5-tutorial/ |
||||
| Ciro Duran | RE: Playing video on BlackBerry | ||||
|
Added by Ciro Duran 8 months ago
An update on this issue. Just to make it clear, I'm working with cocos2d-2.0-x-2.0.2. I integrated the VideoWindow example code on cocos2dx, and I'm getting somewhere to play video, but I'm having a problem with the multimedia renderer, which won't allow to attach an input of the video I'm trying to play. I also had to modify the blackberry CCEGLView object to make it expose the m_screenWindow property. This is the init() function of the extended CCLayer that will play the video. The problem I'm having now with this code is that the mmr_input_attach function fails with a MMR_ERROR_UNKNOWN error code, which has quickly exhausted my options regarding on how to solve this issue. The CCEGLView object has only been modified to add the getScreenWindow() function which only returns the otherwise private m_screenWindow property. Thanks for helping!
// 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();
srand(time(0));
app_id = rand();
// 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=spdintrowindowgroup&wingrp=spdintrowindowgroup");
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, "spdintrocontextname");
if (rc >= PATH_MAX) {
fprintf(stderr, "Video context name too long\n");
}
// Window group name...with the same random number appended.
static char window_group_name[PATH_MAX];
rc = snprintf(window_group_name, PATH_MAX, "spdintrowindowgroup");
if (rc >= PATH_MAX) {
fprintf(stderr, "Video context name too long\n");
}
// Video file bundled with our app
static const char *video_file_relative_path = "app/native/Resources/intro.mp4";
/* Create the window group for our window, this is important, as we pass the group name
* to MMR which uses it to 'parent' it's CHILD_WINDOW which contains the video
*/
if (screen_create_window_group(CCEGLView::sharedOpenGLView()->getScreenWindow(), window_group_name) != 0) {
return false;
}
/*
* 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, video_file_relative_path);
if ((rc == -1) || (rc >= PATH_MAX)) {
return false;
}
/*
* Attach the input media.
*/
if (mmr_input_attach(mmr_context, media_file, "track") != 0) {
const mmr_error_info_t *mmr_error_code = mmr_error_info(mmr_context);
printf("%d\n", *mmr_error_code);
return false;
}
int video_speed = 1;
/*
* Set the speed to 0 to pause the video initially
*/
if (mmr_speed_set(mmr_context, video_speed) != 0) {
return false;
}
/*
* Change to the play state, although speed is zero
*/
if (mmr_play(mmr_context) != 0) {
return false;
}
return true;
}
My site: http://www.ciroduran.com - Cocos2d-html5 course in Spanish: http://www.elchiguireliterario.com/series/cocos2d-html5-tutorial/ |
||||
| Ciro Duran | RE: Playing video on BlackBerry [SOLVED] | ||||
|
Added by Ciro Duran 8 months ago
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 <mm/renderer.h>
#include <bps/navigator.h>
#include <bps/screen.h>
#include <unistd.h>
#include <bps/bps.h>
#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 <mm/renderer.h>
#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 :-) My site: http://www.ciroduran.com - Cocos2d-html5 course in Spanish: http://www.elchiguireliterario.com/series/cocos2d-html5-tutorial/ |
||||
| sergio migueis | RE: Playing video on BlackBerry | ||||
|
Added by sergio migueis 7 months ago
Im exchangin message with the creator of this thread in the blacberry foruns... PS: im using cocos2d-x 2.0.3; |
||||
| German Martinez | RE: Playing video on BlackBerry | ||||
|
Added by German Martinez about 1 month ago
Hi: Change the value of
to
and after that compile and run your game and you'll be able to watch the video on screen. |
(1-4/4)