fixed crashes when files are missing. all player errors are now considered as non critical so that app can survive and deliver uninterrupted programming

This commit is contained in:
nebojsa 2009-09-22 23:44:24 +00:00
parent cb32ca774e
commit 2b4ce13d7e
7 changed files with 45 additions and 33 deletions
campcaster/src
modules/playlistExecutor
products/gLiveSupport/src

View File

@ -152,7 +152,7 @@ class AudioPlayerInterface
* @see #close
* @see #start
*/
virtual void
virtual bool
open(const std::string fileUrl) throw (std::invalid_argument,
std::runtime_error)
= 0;

View File

@ -131,7 +131,7 @@ public:
delete m_audioDescription;
m_audioDescription = NULL;
}
}
}
void playContext(){
gst_element_set_state (m_pipeline, GST_STATE_PLAYING);
@ -151,6 +151,13 @@ public:
void setParentData(gpointer data){
m_data = data;
}
void forceEOS(){
GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE (m_pipeline));
gst_bus_post (bus, gst_message_new_eos(GST_OBJECT(m_sink)));
gst_object_unref (bus);
}
/*------------------------------------------------------------------------------
* Set the audio device.
*----------------------------------------------------------------------------*/
@ -338,7 +345,6 @@ private:
if(m_audioDescription && m_audioDescription->m_animations.size() > 0){
m_ctrl = gst_controller_new (G_OBJECT (m_volume), "volume", NULL);
if (m_ctrl == NULL) {
std::cout << "prepareAnimations: element not controllable!" << std::endl;
return false;
}
GValue vol = { 0, };

View File

@ -72,31 +72,16 @@ static gboolean my_bus_callback (GstBus *bus, GstMessage *message, gpointer data
GstreamerPlayer* const player = (GstreamerPlayer*) data;
switch (GST_MESSAGE_TYPE (message)) {
//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:
if(player->playNextSmil()){
break;
}
player->close();
// Important: We *must* use an idle function call here, so that the signal handler returns
// before fireOnStopEvent() is executed.
g_idle_add(GstreamerPlayer::fireOnStopEvent, data);
break;
case GST_MESSAGE_ERROR:
// We make sure that we don't send multiple error messages in a row to the GUI
if (!player->m_errorWasRaised) {
GError *gerror;
gchar *debug;
gst_message_parse_error (message, &gerror, &debug);
player->m_errorMessage.reset(new const Glib::ustring(gerror->message));
player->m_errorWasRaised = true;
std::cerr << "gstreamer error: " << gerror->message << std::endl;
g_error_free (gerror);
g_free (debug);
// Important: We *must* use an idle function call here, so that the signal handler returns
// before fireOnStopEvent() is executed.
g_idle_add(GstreamerPlayer::fireOnStopEvent, data);
}
// Important: We *must* use an idle function call here, so that the signal handler returns
// before fireOnStopEvent() is executed.
g_idle_add(GstreamerPlayer::fireOnStopEvent, data);
break;
}
}
@ -245,7 +230,7 @@ GstreamerPlayer :: preload(const std::string fileUrl)
/*------------------------------------------------------------------------------
* Specify which file to play
*----------------------------------------------------------------------------*/
void
bool
GstreamerPlayer :: open(const std::string fileUri)
throw (std::invalid_argument,
std::runtime_error)
@ -275,16 +260,23 @@ GstreamerPlayer :: open(const std::string fileUri)
}
if(!m_open){
m_errorMessage.reset(new const Glib::ustring("GstreamerPlayer :: open failed! Please consult console output for details."));
m_errorWasRaised = true;
fireOnStopEvent(this);
close();
deInitialize();
initialize();
m_playContext->forceEOS();
return false;
}
return true;
}
bool
GstreamerPlayer :: playNextSmil(void) throw ()
{
DEBUG_BLOCK
if(NULL == m_playContext)
{
return false;
}
m_currentPlayLength = m_playContext->getPosition();//this gets the length of the stream that just completed
m_playContext->closeContext();
if(m_smilHandler == NULL){
@ -297,7 +289,13 @@ GstreamerPlayer :: playNextSmil(void) throw (
return false;
}
if(!m_playContext->openSource(audioDescription)){
return false;
m_playContext->stopContext();
m_playContext->closeContext();
m_open = false;
deInitialize();
initialize();
m_playContext->forceEOS();
return true;
}
m_smilOffset += m_currentPlayLength;
m_playContext->playContext();

View File

@ -285,7 +285,7 @@ public:
* @see #close
* @see #start
*/
virtual void
virtual bool
open(const std::string fileUrl) throw (std::invalid_argument,
std::runtime_error);

View File

@ -1288,7 +1288,7 @@ GLiveSupport :: preload(Ptr<const Playable>::Ref playable)
/*------------------------------------------------------------------------------
* Play a Playable object using the output audio player.
*----------------------------------------------------------------------------*/
void
bool
LiveSupport :: GLiveSupport ::
GLiveSupport :: playOutputAudio(Ptr<Playable>::Ref playable)
throw (std::logic_error,
@ -1298,7 +1298,10 @@ GLiveSupport :: playOutputAudio(Ptr<Playable>::Ref playable)
switch (playable->getType()) {
case Playable::AudioClipType:
outputItemPlayingNow = acquireAudioClip(playable->getId());
outputPlayer->open(*outputItemPlayingNow->getUri());
if(false == outputPlayer->open(*outputItemPlayingNow->getUri()))
{
return false;
}
outputPlayer->start();
std::cerr << "gLiveSupport: Live Mode playing audio clip '"
<< *playable->getTitle()
@ -1341,6 +1344,7 @@ GLiveSupport :: playOutputAudio(Ptr<Playable>::Ref playable)
}
outputPlayerIsPaused = false;
return true;
}

View File

@ -990,7 +990,7 @@ class GLiveSupport : public LocalizedConfigurable,
* @exception std::logic_error in case of audio player errors.
* @exception std::runtime_error in case of audio player errors.
*/
virtual void
virtual bool
playOutputAudio(Ptr<Playable>::Ref playable)
throw (std::logic_error,
std::runtime_error);

View File

@ -411,7 +411,11 @@ LiveModeWindow :: onOutputPlay(void) throw ()
if (playable) {
try {
gLiveSupport->playOutputAudio(playable);
if(false == gLiveSupport->playOutputAudio(playable))
{
treeView->removeItem(itemPlayed);
return;
}
gLiveSupport->setNowPlaying(playable);
treeView->removeItem(itemPlayed);