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:
parent
cb32ca774e
commit
2b4ce13d7e
campcaster/src
modules/playlistExecutor
include/LiveSupport/PlaylistExecutor
src
products/gLiveSupport/src
|
@ -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;
|
||||
|
|
|
@ -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, };
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue