Here's a quick and dirty music player I just added to my PlayBook/BB10 version of
Words in Bed.
It's far from complete functionality wise(it doesn't pause when the app goes to sleep, etc.), but should serve as a decent sample to get music playing quickly. With any luck, the rest of the implementation should be fairly trivial.
You'll want to add these libs to your project
mmrndclient
strm
Here's the header for my class
#include <mm/renderer.h>
class MediaPlayer
{
public:
mmr_connection_t* m_pMediaPlayerConnectionHandle;
mmr_context_t* m_pMediaContext;
int m_AudioOutputID;
public:
MediaPlayer();
~MediaPlayer();
void StartUpMediaPlayer();
void ShutdownMediaPlayer();
};
And the class implementation
#include "MediaPlayer.h"
#include <sys/stat.h>
MediaPlayer::MediaPlayer()
{
m_pMediaPlayerConnectionHandle = 0;
m_pMediaContext = 0;
m_AudioOutputID = -1;
}
MediaPlayer::~MediaPlayer()
{
ShutdownMediaPlayer();
}
void MediaPlayer::StartUpMediaPlayer()
{
// todo: pass this in to separate play func and cut this function in half.
const char* audiofiletoplay = "app/native/Data/Audio/WordsInBedRemixMusic.mp3";
char workingdir[PATH_MAX];
char audiofileurl[PATH_MAX];
int ret;
getcwd( workingdir, PATH_MAX );
sprintf( audiofileurl, "file://%s/%s", workingdir, audiofiletoplay );
assert( m_pMediaPlayerConnectionHandle == 0 );
m_pMediaPlayerConnectionHandle = mmr_connect( 0 );
if( m_pMediaPlayerConnectionHandle == 0 )
{
LOGError( LOGTag, "mmr_connect" );
return;
}
mode_t mode = S_IRUSR | S_IXUSR;
m_pMediaContext = mmr_context_create( m_pMediaPlayerConnectionHandle, "mygamemusicplayer", 0, mode );
if( m_pMediaContext == 0 )
{
LOGError( LOGTag, "mmr_context_create" );
return;
}
const char* audiourl = "audio:default";
m_AudioOutputID = mmr_output_attach( m_pMediaContext, audiourl, "audio" );
if( m_AudioOutputID < 0 )
{
LOGError( LOGTag, "mmr_output_attach" );
return;
}
// put it in a list, so we can specify repeat below
ret = mmr_input_attach( m_pMediaContext, audiofileurl, "autolist" );
//ret = mmr_input_attach( m_pMediaContext, audiofileurl, "track" );
if( ret < 0 )
{
const mmr_error_info_t* errorinfo = mmr_error_info( m_pMediaContext );
LOGError( LOGTag, "mmr_input_attach" );
return;
}
strm_dict_t* inputparams = strm_dict_new(); // repeat:all only works with playlists.
if( inputparams )
{
inputparams = strm_dict_set( inputparams, "repeat", "all" );
ret = mmr_input_parameters( m_pMediaContext, inputparams );
if( ret < 0 )
{
LOGError( LOGTag, "mmr_input_parameters" );
// don't care too much if this fails... should just means audio won't loop.
//return;
}
}
ret = mmr_play( m_pMediaContext );
if( ret < 0 )
{
const mmr_error_info_t* errorinfo = mmr_error_info( m_pMediaContext );
LOGError( LOGTag, "mmr_play" );
return;
}
}
void MediaPlayer::ShutdownMediaPlayer()
{
if( m_pMediaContext )
{
mmr_input_detach( m_pMediaContext );
mmr_output_detach( m_pMediaContext, m_AudioOutputID );
m_AudioOutputID = -1;
mmr_context_destroy( m_pMediaContext );
m_pMediaContext = 0;
}
if( m_pMediaPlayerConnectionHandle )
{
mmr_disconnect( m_pMediaPlayerConnectionHandle );
m_pMediaPlayerConnectionHandle = 0;
}
}