#include <gst/pbutils/missing-plugins.h>
#include <sys/stat.h>
+#define HTTP_TIMEOUT 10
+
// eServiceFactoryMP3
eServiceFactoryMP3::eServiceFactoryMP3()
extensions.push_back("mp4");
extensions.push_back("mov");
extensions.push_back("m4a");
- extensions.push_back("m2ts");
sc->addServiceFactory(eServiceFactoryMP3::id, this, extensions);
}
{
m_seekTimeout = eTimer::create(eApp);
m_subtitle_sync_timer = eTimer::create(eApp);
+ m_streamingsrc_timeout = 0;
m_stream_tags = 0;
m_currentAudioStream = -1;
m_currentSubtitleStream = 0;
if (!ext)
ext = filename;
- sourceStream sourceinfo;
- sourceinfo.is_video = FALSE;
- sourceinfo.audiotype = atUnknown;
+ m_sourceinfo.is_video = FALSE;
+ m_sourceinfo.audiotype = atUnknown;
if ( (strcasecmp(ext, ".mpeg") && strcasecmp(ext, ".mpg") && strcasecmp(ext, ".vob") && strcasecmp(ext, ".bin") && strcasecmp(ext, ".dat") ) == 0 )
{
- sourceinfo.containertype = ctMPEGPS;
- sourceinfo.is_video = TRUE;
+ m_sourceinfo.containertype = ctMPEGPS;
+ m_sourceinfo.is_video = TRUE;
}
else if ( strcasecmp(ext, ".ts") == 0 )
{
- sourceinfo.containertype = ctMPEGTS;
- sourceinfo.is_video = TRUE;
+ m_sourceinfo.containertype = ctMPEGTS;
+ m_sourceinfo.is_video = TRUE;
}
else if ( strcasecmp(ext, ".mkv") == 0 )
{
- sourceinfo.containertype = ctMKV;
- sourceinfo.is_video = TRUE;
+ m_sourceinfo.containertype = ctMKV;
+ m_sourceinfo.is_video = TRUE;
}
else if ( strcasecmp(ext, ".avi") == 0 || strcasecmp(ext, ".divx") == 0)
{
- sourceinfo.containertype = ctAVI;
- sourceinfo.is_video = TRUE;
+ m_sourceinfo.containertype = ctAVI;
+ m_sourceinfo.is_video = TRUE;
}
else if ( strcasecmp(ext, ".mp4") == 0 || strcasecmp(ext, ".mov") == 0 || strcasecmp(ext, ".m4v") == 0)
{
- sourceinfo.containertype = ctMP4;
- sourceinfo.is_video = TRUE;
+ m_sourceinfo.containertype = ctMP4;
+ m_sourceinfo.is_video = TRUE;
}
else if ( strcasecmp(ext, ".m4a") == 0 )
{
- sourceinfo.containertype = ctMP4;
- sourceinfo.audiotype = atAAC;
+ m_sourceinfo.containertype = ctMP4;
+ m_sourceinfo.audiotype = atAAC;
}
else if ( strcasecmp(ext, ".mp3") == 0 )
- sourceinfo.audiotype = atMP3;
+ m_sourceinfo.audiotype = atMP3;
else if ( (strncmp(filename, "/autofs/", 8) || strncmp(filename+strlen(filename)-13, "/track-", 7) || strcasecmp(ext, ".wav")) == 0 )
- sourceinfo.containertype = ctCDA;
+ m_sourceinfo.containertype = ctCDA;
if ( strcasecmp(ext, ".dat") == 0 )
{
- sourceinfo.containertype = ctVCD;
- sourceinfo.is_video = TRUE;
+ m_sourceinfo.containertype = ctVCD;
+ m_sourceinfo.is_video = TRUE;
}
- if ( (strncmp(filename, "http://", 7)) == 0 || (strncmp(filename, "udp://", 6)) == 0 || (strncmp(filename, "rtp://", 6)) == 0 || (strncmp(filename, "https://", 8)) == 0 || (strncmp(filename, "mms://", 6)) == 0 || (strncmp(filename, "rtsp://", 7)) == 0 )
- sourceinfo.is_streaming = TRUE;
+ if ( (strncmp(filename, "http://", 7)) == 0 || (strncmp(filename, "udp://", 6)) == 0 || (strncmp(filename, "rtp://", 6)) == 0 || (strncmp(filename, "https://", 8)) == 0 || (strncmp(filename, "mms://", 6)) == 0 || (strncmp(filename, "rtsp://", 7)) == 0 || (strncmp(filename, "rtspt://", 7)) == 0 )
+ m_sourceinfo.is_streaming = TRUE;
gchar *uri;
- if ( sourceinfo.is_streaming )
+ if ( m_sourceinfo.is_streaming )
{
uri = g_strdup_printf ("%s", filename);
+ m_streamingsrc_timeout = eTimer::create(eApp);;
+ CONNECT(m_streamingsrc_timeout->timeout, eServiceMP3::sourceTimeout);
+
+ std::string config_str;
+ if( ePythonConfigQuery::getConfigValue("config.mediaplayer.useAlternateUserAgent", config_str) == 0 )
+ {
+ if ( config_str == "True" )
+ ePythonConfigQuery::getConfigValue("config.mediaplayer.alternateUserAgent", m_useragent);
+ }
+ if ( m_useragent.length() == 0 )
+ m_useragent = "Dream Multimedia Dreambox Enigma2 Mediaplayer";
}
- else if ( sourceinfo.containertype == ctCDA )
+ else if ( m_sourceinfo.containertype == ctCDA )
{
int i_track = atoi(filename+18);
uri = g_strdup_printf ("cdda://%i", i_track);
}
- else if ( sourceinfo.containertype == ctVCD )
+ else if ( m_sourceinfo.containertype == ctVCD )
{
int fd = open(filename,O_RDONLY);
char tmp[128*1024];
if ( ret == -1 ) // this is a "REAL" VCD
uri = g_strdup_printf ("vcd://");
else
- uri = g_strdup_printf ("file://%s", filename);
+ uri = g_filename_to_uri(filename, NULL, NULL);
}
else
- uri = g_strdup_printf ("file://%s", filename);
+ uri = g_filename_to_uri(filename, NULL, NULL);
eDebug("eServiceMP3::playbin2 uri=%s", uri);
else
{
m_subs_to_pull_handler_id = g_signal_connect (subsink, "new-buffer", G_CALLBACK (gstCBsubtitleAvail), this);
+ g_object_set (G_OBJECT (subsink), "caps", gst_caps_from_string("text/plain; text/x-plain; text/x-pango-markup"), NULL);
g_object_set (G_OBJECT (m_gst_playbin), "text-sink", subsink, NULL);
}
struct stat buffer;
if (stat(srt_filename, &buffer) == 0)
{
- std::string suburi = "file://" + (std::string)srt_filename;
- eDebug("eServiceMP3::subtitle uri: %s",suburi.c_str());
- g_object_set (G_OBJECT (m_gst_playbin), "suburi", suburi.c_str(), NULL);
+ eDebug("eServiceMP3::subtitle uri: %s", g_filename_to_uri(srt_filename, NULL, NULL));
+ g_object_set (G_OBJECT (m_gst_playbin), "suburi", g_filename_to_uri(srt_filename, NULL, NULL), NULL);
subtitleStream subs;
subs.type = stSRT;
subs.language_code = std::string("und");
m_subtitleStreams.push_back(subs);
}
+ if ( m_sourceinfo.is_streaming )
+ {
+ g_signal_connect (G_OBJECT (m_gst_playbin), "notify::source", G_CALLBACK (gstHTTPSourceSetAgent), this);
+ }
} else
{
m_event((iPlayableService*)this, evUser+12);
return 0;
}
+void eServiceMP3::sourceTimeout()
+{
+ eDebug("eServiceMP3::http source timeout! issuing eof...");
+ m_event((iPlayableService*)this, evEOF);
+}
+
RESULT eServiceMP3::stop()
{
ASSERT(m_state != stIdle);
} break;
case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
{
+ if ( m_sourceinfo.is_streaming && m_streamingsrc_timeout )
+ m_streamingsrc_timeout->stop();
} break;
case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
{
// g_free (g_type);
}
m_event((iPlayableService*)this, evUpdatedEventInfo);
+ break;
}
case GST_MESSAGE_ELEMENT:
{
gst_message_parse_buffering(msg, &(m_bufferInfo.bufferPercent));
gst_message_parse_buffering_stats(msg, &mode, &(m_bufferInfo.avgInRate), &(m_bufferInfo.avgOutRate), &(m_bufferInfo.bufferingLeft));
m_event((iPlayableService*)this, evBuffering);
+ break;
+ }
+ case GST_MESSAGE_STREAM_STATUS:
+ {
+ GstStreamStatusType type;
+ GstElement *owner;
+ gst_message_parse_stream_status (msg, &type, &owner);
+ if ( type == GST_STREAM_STATUS_TYPE_CREATE && m_sourceinfo.is_streaming )
+ {
+ if ( GST_IS_PAD(source) )
+ owner = gst_pad_get_parent_element(GST_PAD(source));
+ else if ( GST_IS_ELEMENT(source) )
+ owner = GST_ELEMENT(source);
+ else
+ owner = 0;
+ if ( owner )
+ {
+ GstElementFactory *factory = gst_element_get_factory(GST_ELEMENT(owner));
+ const gchar *name = gst_plugin_feature_get_name(GST_PLUGIN_FEATURE(factory));
+ if (!strcmp(name, "souphttpsrc"))
+ {
+ m_streamingsrc_timeout->start(HTTP_TIMEOUT*1000, true);
+ g_object_set (G_OBJECT (owner), "timeout", HTTP_TIMEOUT, NULL);
+ eDebug("eServiceMP3::GST_STREAM_STATUS_TYPE_CREATE -> setting timeout on %s to %is", name, HTTP_TIMEOUT);
+ }
+
+ }
+ if ( GST_IS_PAD(source) )
+ gst_object_unref(owner);
+ }
+ break;
}
default:
break;
return GST_BUS_PASS;
}
+void eServiceMP3::gstHTTPSourceSetAgent(GObject *object, GParamSpec *unused, gpointer user_data)
+{
+ eServiceMP3 *_this = (eServiceMP3*)user_data;
+ GstElement *source;
+ g_object_get(_this->m_gst_playbin, "source", &source, NULL);
+ g_object_set (G_OBJECT (source), "user-agent", _this->m_useragent.c_str(), NULL);
+ gst_object_unref(source);
+}
+
audiotype_t eServiceMP3::gstCheckAudioPad(GstStructure* structure)
{
if (!structure)