added file id to smil and implemented XML-RPC callback for playback start
This commit is contained in:
parent
2b4ce13d7e
commit
9cc4389052
15 changed files with 254 additions and 28 deletions
|
@ -90,6 +90,17 @@ class AudioPlayerEventListener
|
||||||
virtual void
|
virtual void
|
||||||
onStop(Ptr<const Glib::ustring>::Ref errorMessage)
|
onStop(Ptr<const Glib::ustring>::Ref errorMessage)
|
||||||
throw () = 0;
|
throw () = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Catch the event when playback started.
|
||||||
|
* Every time player plays a new file, it sends this event at the beginning.
|
||||||
|
* App should use this to synchronize playback
|
||||||
|
*
|
||||||
|
* @param id represents the file that just started
|
||||||
|
*/
|
||||||
|
virtual void
|
||||||
|
onStart(gint64 id)
|
||||||
|
throw () = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -153,9 +153,8 @@ class AudioPlayerInterface
|
||||||
* @see #start
|
* @see #start
|
||||||
*/
|
*/
|
||||||
virtual bool
|
virtual bool
|
||||||
open(const std::string fileUrl) throw (std::invalid_argument,
|
open(const std::string fileUrl, gint64 id)
|
||||||
std::runtime_error)
|
throw (std::invalid_argument, std::runtime_error) = 0;
|
||||||
= 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tell if the audio player has been openned.
|
* Tell if the audio player has been openned.
|
||||||
|
|
|
@ -73,8 +73,8 @@ static gboolean my_bus_callback (GstBus *bus, GstMessage *message, gpointer data
|
||||||
|
|
||||||
switch (GST_MESSAGE_TYPE (message)) {
|
switch (GST_MESSAGE_TYPE (message)) {
|
||||||
//we shall handle errors as non critical events as we should not stop playback in any case
|
//we shall handle errors as non critical events as we should not stop playback in any case
|
||||||
case GST_MESSAGE_EOS:
|
|
||||||
case GST_MESSAGE_ERROR:
|
case GST_MESSAGE_ERROR:
|
||||||
|
case GST_MESSAGE_EOS:
|
||||||
if(player->playNextSmil()){
|
if(player->playNextSmil()){
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -210,6 +210,28 @@ GstreamerPlayer :: fireOnStopEvent(gpointer self) throw ()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Send the onStart event to all attached listeners.
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
gboolean
|
||||||
|
GstreamerPlayer :: fireOnStartEvent(gpointer self) throw ()
|
||||||
|
{
|
||||||
|
DEBUG_BLOCK
|
||||||
|
|
||||||
|
|
||||||
|
GstreamerPlayer* const player = (GstreamerPlayer*) self;
|
||||||
|
|
||||||
|
ListenerVector::iterator it = player->m_listeners.begin();
|
||||||
|
ListenerVector::iterator end = player->m_listeners.end();
|
||||||
|
while (it != end) {
|
||||||
|
(*it)->onStart(player->m_Id);
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
|
||||||
|
// false == Don't call this idle function again
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
/*------------------------------------------------------------------------------
|
||||||
* Preload a file, to speed up the subsequent open() call.
|
* Preload a file, to speed up the subsequent open() call.
|
||||||
|
@ -231,9 +253,8 @@ GstreamerPlayer :: preload(const std::string fileUrl)
|
||||||
* Specify which file to play
|
* Specify which file to play
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
bool
|
bool
|
||||||
GstreamerPlayer :: open(const std::string fileUri)
|
GstreamerPlayer :: open(const std::string fileUri, gint64 id)
|
||||||
throw (std::invalid_argument,
|
throw (std::invalid_argument, std::runtime_error)
|
||||||
std::runtime_error)
|
|
||||||
{
|
{
|
||||||
DEBUG_BLOCK
|
DEBUG_BLOCK
|
||||||
|
|
||||||
|
@ -254,9 +275,13 @@ GstreamerPlayer :: open(const std::string fileUri)
|
||||||
m_smilHandler = new SmilHandler();
|
m_smilHandler = new SmilHandler();
|
||||||
m_smilHandler->openSmilFile(fileUri.c_str());
|
m_smilHandler->openSmilFile(fileUri.c_str());
|
||||||
AudioDescription *audioDescription = m_smilHandler->getNext();
|
AudioDescription *audioDescription = m_smilHandler->getNext();
|
||||||
|
m_Id = audioDescription->m_Id;
|
||||||
m_open=m_playContext->openSource(audioDescription);
|
m_open=m_playContext->openSource(audioDescription);
|
||||||
|
m_url = (const char*) audioDescription->m_src;
|
||||||
}else{
|
}else{
|
||||||
m_open=m_playContext->openSource(fileUri.c_str());
|
m_open=m_playContext->openSource(fileUri.c_str());
|
||||||
|
m_url = fileUri;
|
||||||
|
m_Id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!m_open){
|
if(!m_open){
|
||||||
|
@ -266,6 +291,7 @@ GstreamerPlayer :: open(const std::string fileUri)
|
||||||
m_playContext->forceEOS();
|
m_playContext->forceEOS();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
g_idle_add(GstreamerPlayer::fireOnStartEvent, this);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,6 +323,9 @@ GstreamerPlayer :: playNextSmil(void) throw (
|
||||||
m_playContext->forceEOS();
|
m_playContext->forceEOS();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
m_Id = audioDescription->m_Id;
|
||||||
|
m_url = (const char*) audioDescription->m_src;
|
||||||
|
g_idle_add(GstreamerPlayer::fireOnStartEvent, this);
|
||||||
m_smilOffset += m_currentPlayLength;
|
m_smilOffset += m_currentPlayLength;
|
||||||
m_playContext->playContext();
|
m_playContext->playContext();
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -122,14 +122,10 @@ class GstreamerPlayer : virtual public Configurable,
|
||||||
* The audio device to play on.
|
* The audio device to play on.
|
||||||
*/
|
*/
|
||||||
std::string m_audioDevice;
|
std::string m_audioDevice;
|
||||||
|
|
||||||
/**
|
|
||||||
* The URL of the preloaded file. Empty if nothing is preloaded.
|
|
||||||
*/
|
|
||||||
std::string m_preloadUrl;
|
|
||||||
|
|
||||||
gint64 m_smilOffset;
|
gint64 m_smilOffset;
|
||||||
gint64 m_currentPlayLength;
|
gint64 m_currentPlayLength;
|
||||||
|
gint64 m_Id;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -164,6 +160,12 @@ public:
|
||||||
static gboolean
|
static gboolean
|
||||||
fireOnStopEvent(gpointer self) throw ();
|
fireOnStopEvent(gpointer self) throw ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send the onStart event to all attached listeners.
|
||||||
|
*/
|
||||||
|
static gboolean
|
||||||
|
fireOnStartEvent(gpointer self) throw ();
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
|
@ -286,8 +288,8 @@ public:
|
||||||
* @see #start
|
* @see #start
|
||||||
*/
|
*/
|
||||||
virtual bool
|
virtual bool
|
||||||
open(const std::string fileUrl) throw (std::invalid_argument,
|
open(const std::string fileUrl, gint64 id)
|
||||||
std::runtime_error);
|
throw (std::invalid_argument, std::runtime_error);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tell if the object is currently opened (has a file source to
|
* Tell if the object is currently opened (has a file source to
|
||||||
|
|
|
@ -84,11 +84,9 @@ public:
|
||||||
m_begin(0),
|
m_begin(0),
|
||||||
m_end(0)
|
m_end(0)
|
||||||
{
|
{
|
||||||
// std::cout << "AnimationDescription created!" << std::endl;
|
|
||||||
}
|
}
|
||||||
~AnimationDescription()
|
~AnimationDescription()
|
||||||
{
|
{
|
||||||
// std::cout << "AnimationDescription destroyed!" << std::endl;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -101,19 +99,19 @@ public:
|
||||||
gint64 m_begin;
|
gint64 m_begin;
|
||||||
gint64 m_clipBegin;
|
gint64 m_clipBegin;
|
||||||
gint64 m_clipEnd;
|
gint64 m_clipEnd;
|
||||||
|
gint64 m_Id;
|
||||||
std::vector<AnimationDescription*> m_animations;
|
std::vector<AnimationDescription*> m_animations;
|
||||||
|
|
||||||
AudioDescription():
|
AudioDescription():
|
||||||
m_src(NULL),
|
m_src(NULL),
|
||||||
m_begin(0),
|
m_begin(0),
|
||||||
m_clipBegin(0),
|
m_clipBegin(0),
|
||||||
m_clipEnd(0)
|
m_clipEnd(0),
|
||||||
|
m_Id(0)
|
||||||
{
|
{
|
||||||
// std::cout << "AudioDescription created!" << std::endl;
|
|
||||||
}
|
}
|
||||||
~AudioDescription()
|
~AudioDescription()
|
||||||
{
|
{
|
||||||
// std::cout << "AudioDescription destroyed!" << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void release()
|
void release()
|
||||||
|
@ -287,6 +285,7 @@ private:
|
||||||
gchar * begin = 0;
|
gchar * begin = 0;
|
||||||
gchar * clipBegin = 0;
|
gchar * clipBegin = 0;
|
||||||
gchar * clipEnd = 0;
|
gchar * clipEnd = 0;
|
||||||
|
gchar * idStr = 0;
|
||||||
|
|
||||||
/* handle the attributes */
|
/* handle the attributes */
|
||||||
for (attr = ((xmlElement*)audio)->attributes; attr; attr = (xmlAttribute*) attr->next) {
|
for (attr = ((xmlElement*)audio)->attributes; attr; attr = (xmlAttribute*) attr->next) {
|
||||||
|
@ -296,6 +295,10 @@ private:
|
||||||
if ((node = attr->children) && node->type == XML_TEXT_NODE) {
|
if ((node = attr->children) && node->type == XML_TEXT_NODE) {
|
||||||
src = (gchar*) node->content;
|
src = (gchar*) node->content;
|
||||||
}
|
}
|
||||||
|
} else if (!strcmp((const char*)attr->name, "id")) {
|
||||||
|
if ((node = attr->children) && node->type == XML_TEXT_NODE) {
|
||||||
|
idStr = (gchar*) node->content;
|
||||||
|
}
|
||||||
} else if (!strcmp((const char*)attr->name, "begin")) {
|
} else if (!strcmp((const char*)attr->name, "begin")) {
|
||||||
if ((node = attr->children) && node->type == XML_TEXT_NODE) {
|
if ((node = attr->children) && node->type == XML_TEXT_NODE) {
|
||||||
begin = (gchar*) node->content;
|
begin = (gchar*) node->content;
|
||||||
|
@ -328,6 +331,11 @@ private:
|
||||||
audioDescription->m_begin = su_smil_clock_value_to_nanosec(begin);
|
audioDescription->m_begin = su_smil_clock_value_to_nanosec(begin);
|
||||||
audioDescription->m_clipBegin = su_smil_clock_value_to_nanosec(clipBegin);
|
audioDescription->m_clipBegin = su_smil_clock_value_to_nanosec(clipBegin);
|
||||||
audioDescription->m_clipEnd = su_smil_clock_value_to_nanosec(clipEnd);
|
audioDescription->m_clipEnd = su_smil_clock_value_to_nanosec(clipEnd);
|
||||||
|
if(idStr)
|
||||||
|
{
|
||||||
|
std::stringstream idReader(idStr);
|
||||||
|
idReader >> audioDescription->m_Id;
|
||||||
|
}
|
||||||
// now handle the possible animate elements inside this audio element
|
// now handle the possible animate elements inside this audio element
|
||||||
for (node = audio->children; node; node = node->next) {
|
for (node = audio->children; node; node = node->next) {
|
||||||
if (node->type == XML_ELEMENT_NODE) {
|
if (node->type == XML_ELEMENT_NODE) {
|
||||||
|
|
|
@ -146,6 +146,11 @@ const std::string smilPlayableNodeName = "audio";
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
const std::string smilPlayableUriAttrName = "src";
|
const std::string smilPlayableUriAttrName = "src";
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* The name of the attribute containing the Id of the Playable element.
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
const std::string smilPlayableIdAttrName = "id";
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
/*------------------------------------------------------------------------------
|
||||||
* The name of the attribute containing the relative offset of the element.
|
* The name of the attribute containing the relative offset of the element.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
|
@ -1591,9 +1596,13 @@ WebStorageClient :: acquirePlaylist(Ptr<const UniqueId>::Ref id,
|
||||||
|
|
||||||
switch (plElement->getType()) {
|
switch (plElement->getType()) {
|
||||||
case PlaylistElement::AudioClipType :
|
case PlaylistElement::AudioClipType :
|
||||||
|
{
|
||||||
url.reset(new std::string(
|
url.reset(new std::string(
|
||||||
contentElement[getPlaylistUrlParamName]));
|
contentElement[getPlaylistUrlParamName]));
|
||||||
playable = plElement->getAudioClip();
|
playable = plElement->getAudioClip();
|
||||||
|
Ptr<Playable>::Ref audioClip = playable;
|
||||||
|
subPlaylistId = audioClip->getId();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case PlaylistElement::PlaylistType :
|
case PlaylistElement::PlaylistType :
|
||||||
subPlaylistId = plElement->getPlaylist()->getId();
|
subPlaylistId = plElement->getPlaylist()->getId();
|
||||||
|
@ -1612,6 +1621,9 @@ WebStorageClient :: acquirePlaylist(Ptr<const UniqueId>::Ref id,
|
||||||
smilPlayableNode->set_attribute(
|
smilPlayableNode->set_attribute(
|
||||||
smilPlayableUriAttrName,
|
smilPlayableUriAttrName,
|
||||||
*url );
|
*url );
|
||||||
|
smilPlayableNode->set_attribute(
|
||||||
|
smilPlayableIdAttrName,
|
||||||
|
*subPlaylistId->toDecimalString() );
|
||||||
smilPlayableNode->set_attribute(
|
smilPlayableNode->set_attribute(
|
||||||
smilRelativeOffsetAttrName,
|
smilRelativeOffsetAttrName,
|
||||||
*TimeConversion::timeDurationToSmilString(
|
*TimeConversion::timeDurationToSmilString(
|
||||||
|
|
|
@ -211,6 +211,14 @@ CuePlayer :: onStop(Ptr<const Glib::ustring>::Ref errorMessage) throw ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Event handler for the "cue audio player has started" event.
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
CuePlayer :: onStart(gint64 id) throw ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
/*------------------------------------------------------------------------------
|
||||||
* Set the state of the widget.
|
* Set the state of the widget.
|
||||||
|
|
|
@ -175,6 +175,15 @@ class CuePlayer : public GuiComponent,
|
||||||
onStop(Ptr<const Glib::ustring>::Ref errorMessage
|
onStop(Ptr<const Glib::ustring>::Ref errorMessage
|
||||||
= Ptr<const Glib::ustring>::Ref())
|
= Ptr<const Glib::ustring>::Ref())
|
||||||
throw ();
|
throw ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event handler for the "cue audio player has started" event.
|
||||||
|
*
|
||||||
|
* @param fileName
|
||||||
|
*/
|
||||||
|
virtual void
|
||||||
|
onStart(gint64 id)
|
||||||
|
throw ();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1298,7 +1298,7 @@ GLiveSupport :: playOutputAudio(Ptr<Playable>::Ref playable)
|
||||||
switch (playable->getType()) {
|
switch (playable->getType()) {
|
||||||
case Playable::AudioClipType:
|
case Playable::AudioClipType:
|
||||||
outputItemPlayingNow = acquireAudioClip(playable->getId());
|
outputItemPlayingNow = acquireAudioClip(playable->getId());
|
||||||
if(false == outputPlayer->open(*outputItemPlayingNow->getUri()))
|
if(false == outputPlayer->open(*outputItemPlayingNow->getUri(), (gint64)outputItemPlayingNow->getId()->getId()))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1310,7 +1310,7 @@ GLiveSupport :: playOutputAudio(Ptr<Playable>::Ref playable)
|
||||||
|
|
||||||
case Playable::PlaylistType:
|
case Playable::PlaylistType:
|
||||||
outputItemPlayingNow = acquirePlaylist(playable->getId());
|
outputItemPlayingNow = acquirePlaylist(playable->getId());
|
||||||
outputPlayer->open(*outputItemPlayingNow->getUri());
|
outputPlayer->open(*outputItemPlayingNow->getUri(), (gint64)outputItemPlayingNow->getId()->getId());
|
||||||
outputPlayer->start();
|
outputPlayer->start();
|
||||||
std::cerr << "gLiveSupport: Live Mode playing playlist '"
|
std::cerr << "gLiveSupport: Live Mode playing playlist '"
|
||||||
<< *playable->getTitle()
|
<< *playable->getTitle()
|
||||||
|
@ -1414,6 +1414,17 @@ GLiveSupport :: onStop(Ptr<const Glib::ustring>::Ref errorMessage)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Event handler for the "output audio player has started" event.
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
LiveSupport :: GLiveSupport ::
|
||||||
|
GLiveSupport :: onStart(gint64 id)
|
||||||
|
throw ()
|
||||||
|
{
|
||||||
|
masterPanel->setCurrentInnerPlayable(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
/*------------------------------------------------------------------------------
|
||||||
* Play a Playable object using the cue audio player.
|
* Play a Playable object using the cue audio player.
|
||||||
|
@ -1432,7 +1443,7 @@ GLiveSupport :: playCueAudio(Ptr<Playable>::Ref playable)
|
||||||
switch (playable->getType()) {
|
switch (playable->getType()) {
|
||||||
case Playable::AudioClipType:
|
case Playable::AudioClipType:
|
||||||
cueItemPlayingNow = acquireAudioClip(playable->getId());
|
cueItemPlayingNow = acquireAudioClip(playable->getId());
|
||||||
cuePlayer->open(*cueItemPlayingNow->getUri());
|
cuePlayer->open(*cueItemPlayingNow->getUri(), (gint64)cueItemPlayingNow->getId()->getId());
|
||||||
cuePlayer->start();
|
cuePlayer->start();
|
||||||
std::cerr << "gLiveSupport: Cue playing audio clip '"
|
std::cerr << "gLiveSupport: Cue playing audio clip '"
|
||||||
<< *playable->getTitle()
|
<< *playable->getTitle()
|
||||||
|
@ -1441,7 +1452,7 @@ GLiveSupport :: playCueAudio(Ptr<Playable>::Ref playable)
|
||||||
|
|
||||||
case Playable::PlaylistType:
|
case Playable::PlaylistType:
|
||||||
cueItemPlayingNow = acquirePlaylist(playable->getId());
|
cueItemPlayingNow = acquirePlaylist(playable->getId());
|
||||||
cuePlayer->open(*cueItemPlayingNow->getUri());
|
cuePlayer->open(*cueItemPlayingNow->getUri(), (gint64)cueItemPlayingNow->getId()->getId());
|
||||||
cuePlayer->start();
|
cuePlayer->start();
|
||||||
std::cerr << "gLiveSupport: Cue playing playlist '"
|
std::cerr << "gLiveSupport: Cue playing playlist '"
|
||||||
<< *playable->getTitle()
|
<< *playable->getTitle()
|
||||||
|
@ -1758,7 +1769,7 @@ GLiveSupport :: playTestSoundOnCue(Ptr<const Glib::ustring>::Ref oldDevice,
|
||||||
cuePlayer->close();
|
cuePlayer->close();
|
||||||
}
|
}
|
||||||
cuePlayer->setAudioDevice(*newDevice);
|
cuePlayer->setAudioDevice(*newDevice);
|
||||||
cuePlayer->open(*testAudioUrl);
|
cuePlayer->open(*testAudioUrl, (gint64)0);
|
||||||
cuePlayer->start();
|
cuePlayer->start();
|
||||||
Ptr<time_duration>::Ref sleepT(new time_duration(microseconds(10)));
|
Ptr<time_duration>::Ref sleepT(new time_duration(microseconds(10)));
|
||||||
while (cuePlayer->isPlaying()) {
|
while (cuePlayer->isPlaying()) {
|
||||||
|
|
|
@ -1125,6 +1125,15 @@ class GLiveSupport : public LocalizedConfigurable,
|
||||||
= Ptr<const Glib::ustring>::Ref())
|
= Ptr<const Glib::ustring>::Ref())
|
||||||
throw ();
|
throw ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event handler for the "output audio player has started" event.
|
||||||
|
*
|
||||||
|
* @param fileName
|
||||||
|
*/
|
||||||
|
virtual void
|
||||||
|
onStart(gint64 id)
|
||||||
|
throw ();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display the playable item on the master panel as "now playing".
|
* Display the playable item on the master panel as "now playing".
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -411,12 +411,12 @@ LiveModeWindow :: onOutputPlay(void) throw ()
|
||||||
|
|
||||||
if (playable) {
|
if (playable) {
|
||||||
try {
|
try {
|
||||||
|
gLiveSupport->setNowPlaying(playable);
|
||||||
if(false == gLiveSupport->playOutputAudio(playable))
|
if(false == gLiveSupport->playOutputAudio(playable))
|
||||||
{
|
{
|
||||||
treeView->removeItem(itemPlayed);
|
treeView->removeItem(itemPlayed);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
gLiveSupport->setNowPlaying(playable);
|
|
||||||
|
|
||||||
treeView->removeItem(itemPlayed);
|
treeView->removeItem(itemPlayed);
|
||||||
|
|
||||||
|
|
|
@ -559,6 +559,17 @@ class MasterPanelWindow : public GuiWindow
|
||||||
return nowPlayingWidget->getCurrentInnerPlayable();
|
return nowPlayingWidget->getCurrentInnerPlayable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the Playable currently shown in the "now playing" display.
|
||||||
|
*
|
||||||
|
* @return the currently playing item; 0 if nothing is playing.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
setCurrentInnerPlayable (gint64 id) throw ()
|
||||||
|
{
|
||||||
|
nowPlayingWidget->setCurrentInnerPlayable(id);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Upload a Playable object to the network hub.
|
* Upload a Playable object to the network hub.
|
||||||
* And display it in the Transports tab of the Search Window.
|
* And display it in the Transports tab of the Search Window.
|
||||||
|
|
|
@ -141,6 +141,20 @@ NowPlaying :: setStyle (Gtk::Label * label,
|
||||||
label->set_attributes(attributeList);
|
label->set_attributes(attributeList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NowPlaying :: setCurrentInnerPlayable (gint64 id) throw ()
|
||||||
|
{
|
||||||
|
playableMutex.lock();
|
||||||
|
if((gint64)currentInnerPlayable->getId()->getId() != id)
|
||||||
|
{
|
||||||
|
//we are not playing a correct file, must have had an error - adjust the playlist
|
||||||
|
std::cout << "NowPlaying :: setCurrentInnerPlayable ERROR DETECTED! called = " << id << ", current = " << (gint64)currentInnerPlayable->getId()->getId() << std::endl;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
std::cout << "NowPlaying :: setCurrentInnerPlayable CORRECT!" << std::endl;
|
||||||
|
}
|
||||||
|
playableMutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
/*------------------------------------------------------------------------------
|
||||||
* Set the title etc. of the playable shown in the widget.
|
* Set the title etc. of the playable shown in the widget.
|
||||||
|
@ -162,8 +176,99 @@ NowPlaying :: setPlayable (Ptr<Playable>::Ref playable) throw ()
|
||||||
isActive = true;
|
isActive = true;
|
||||||
isPaused = false;
|
isPaused = false;
|
||||||
resetRemainsTimeState();
|
resetRemainsTimeState();
|
||||||
onUpdateTime();
|
|
||||||
|
remainsTimeCounter++;
|
||||||
|
if (remainsTimeCounter == 2*blinkingConstant) {
|
||||||
|
remainsTimeCounter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ptr<time_duration>::Ref elapsed;
|
||||||
|
try {
|
||||||
|
elapsed = gLiveSupport->getOutputAudioPosition();
|
||||||
|
} catch (std::logic_error &e) {
|
||||||
|
elapsed.reset(new time_duration(microseconds(0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ptr<time_duration>::Ref totalLength
|
||||||
|
= TimeConversion::roundToNearestSecond(
|
||||||
|
playable->getPlaylength());
|
||||||
|
Ptr<time_duration>::Ref remains(new time_duration(
|
||||||
|
*totalLength - *elapsed));
|
||||||
|
switch (remainsTimeState) {
|
||||||
|
case TIME_GREEN :
|
||||||
|
if (*remains <= seconds(20)) {
|
||||||
|
remainsTimeState = TIME_YELLOW;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TIME_YELLOW :
|
||||||
|
if (*remains <= seconds(10)) {
|
||||||
|
remainsTimeState = TIME_RED;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TIME_RED :
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
setRemainsTimeColor(remainsTimeState);
|
||||||
|
|
||||||
|
Ptr<Playable>::Ref innerPlayable = playable;
|
||||||
|
Ptr<time_duration>::Ref innerElapsed = elapsed;
|
||||||
|
Ptr<time_duration>::Ref innerRemains = remains;
|
||||||
|
Glib::ustring playlistInfo;
|
||||||
|
bool isFirst = true;
|
||||||
|
|
||||||
|
while (innerPlayable->getType() == Playable::PlaylistType) {
|
||||||
|
if (isFirst) {
|
||||||
|
isFirst = false;
|
||||||
|
} else {
|
||||||
|
playlistInfo += " >>> ";
|
||||||
|
}
|
||||||
|
playlistInfo += *innerPlayable->getTitle();
|
||||||
|
playlistInfo += " [";
|
||||||
|
playlistInfo += *TimeConversion::timeDurationToHhMmSsString(innerRemains);
|
||||||
|
playlistInfo += "/";
|
||||||
|
playlistInfo += *TimeConversion::timeDurationToHhMmSsString(innerPlayable->getPlaylength());
|
||||||
|
playlistInfo += "]";
|
||||||
|
|
||||||
|
Ptr<PlaylistElement>::Ref element = innerPlayable->getPlaylist()->findAtOffset(elapsed);
|
||||||
|
if (!element) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
innerPlayable = element->getPlayable();
|
||||||
|
*innerElapsed -= *element->getRelativeOffset();
|
||||||
|
*innerRemains = *TimeConversion::roundToNearestSecond(
|
||||||
|
innerPlayable->getPlaylength()) - *innerElapsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
playlistLabel->set_text(playlistInfo);
|
||||||
|
|
||||||
|
titleLabel->set_text(*innerPlayable->getTitle());
|
||||||
|
|
||||||
|
Ptr<Glib::ustring>::Ref
|
||||||
|
creator = innerPlayable->getMetadata("dc:creator");
|
||||||
|
if (creator) {
|
||||||
|
creatorLabel->set_text(*creator);
|
||||||
|
} else {
|
||||||
|
creatorLabel->set_text("");
|
||||||
|
}
|
||||||
|
|
||||||
|
elapsedTimeLabel->set_text(*TimeConversion::timeDurationToHhMmSsString(innerElapsed ));
|
||||||
|
remainsTimeLabel->set_text(*TimeConversion::timeDurationToHhMmSsString(innerRemains ));
|
||||||
|
|
||||||
|
long elapsedMilliSec = innerElapsed->total_milliseconds();
|
||||||
|
long totalMilliSec = elapsedMilliSec
|
||||||
|
+ innerRemains->total_milliseconds();
|
||||||
|
double fraction = double(elapsedMilliSec) / double(totalMilliSec);
|
||||||
|
if (fraction < 0.0) {
|
||||||
|
fraction = 0.0; // can't happen afaik
|
||||||
|
}
|
||||||
|
if (fraction > 1.0) {
|
||||||
|
fraction = 1.0; // can and does happen!
|
||||||
|
}
|
||||||
|
progressBar->set_fraction(fraction);
|
||||||
|
|
||||||
|
currentInnerPlayable = innerPlayable;
|
||||||
} else {
|
} else {
|
||||||
if (isActive && !isPaused) {
|
if (isActive && !isPaused) {
|
||||||
playButton->set_label(playStockImageName);
|
playButton->set_label(playStockImageName);
|
||||||
|
|
|
@ -290,6 +290,18 @@ class NowPlaying : public GuiComponent
|
||||||
return currentInnerPlayable;
|
return currentInnerPlayable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the Playable object which is playing now.
|
||||||
|
* If a playlist is playing, does not return the playlist, but
|
||||||
|
* the audio clip inside the playlist (possibly several levels deep).
|
||||||
|
*
|
||||||
|
* This is used by GLiveSupport::substituteRdsData().
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
setCurrentInnerPlayable (gint64 id) throw ();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Change the user interface language of the widget.
|
* Change the user interface language of the widget.
|
||||||
*
|
*
|
||||||
|
|
|
@ -158,7 +158,7 @@ PlaylistEvent :: start(void) throw ()
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
audioPlayer->open(*playlist->getUri());
|
audioPlayer->open(*playlist->getUri(), (gint64)playlist->getId()->getId());
|
||||||
audioPlayer->start();
|
audioPlayer->start();
|
||||||
|
|
||||||
playLog->addPlayLogEntry(playlist->getId(), TimeConversion::now());
|
playLog->addPlayLogEntry(playlist->getId(), TimeConversion::now());
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue