mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 09:10:36 +00:00
hlsdemux: Always use the redirect target to resolve relative URIs
But redownload the playlists from the original URI if it's not a permanent redirect.
This commit is contained in:
parent
8372fa6ecc
commit
2f39a3d711
3 changed files with 46 additions and 26 deletions
|
@ -105,7 +105,7 @@ static gboolean gst_hls_demux_update_playlist (GstHLSDemux * demux,
|
||||||
gboolean update, GError ** err);
|
gboolean update, GError ** err);
|
||||||
static void gst_hls_demux_reset (GstHLSDemux * demux, gboolean dispose);
|
static void gst_hls_demux_reset (GstHLSDemux * demux, gboolean dispose);
|
||||||
static gboolean gst_hls_demux_set_location (GstHLSDemux * demux,
|
static gboolean gst_hls_demux_set_location (GstHLSDemux * demux,
|
||||||
const gchar * uri);
|
const gchar * uri, const gchar * base_uri);
|
||||||
static gchar *gst_hls_src_buf_to_utf8_playlist (GstBuffer * buf);
|
static gchar *gst_hls_src_buf_to_utf8_playlist (GstBuffer * buf);
|
||||||
|
|
||||||
static gboolean gst_hls_demux_change_playlist (GstHLSDemux * demux,
|
static gboolean gst_hls_demux_change_playlist (GstHLSDemux * demux,
|
||||||
|
@ -572,7 +572,6 @@ gst_hls_demux_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
|
||||||
GstHLSDemux *demux;
|
GstHLSDemux *demux;
|
||||||
GstQuery *query;
|
GstQuery *query;
|
||||||
gboolean ret;
|
gboolean ret;
|
||||||
gchar *uri;
|
|
||||||
|
|
||||||
demux = GST_HLS_DEMUX (parent);
|
demux = GST_HLS_DEMUX (parent);
|
||||||
|
|
||||||
|
@ -592,18 +591,19 @@ gst_hls_demux_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
|
||||||
ret = gst_pad_peer_query (demux->sinkpad, query);
|
ret = gst_pad_peer_query (demux->sinkpad, query);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
gboolean permanent;
|
gboolean permanent;
|
||||||
|
gchar *uri, *redirect_uri;
|
||||||
|
|
||||||
gst_query_parse_uri_redirection (query, &uri);
|
gst_query_parse_uri (query, &uri);
|
||||||
|
gst_query_parse_uri_redirection (query, &redirect_uri);
|
||||||
gst_query_parse_uri_redirection_permanent (query, &permanent);
|
gst_query_parse_uri_redirection_permanent (query, &permanent);
|
||||||
|
|
||||||
/* Only use the redirect target for permanent redirects */
|
if (permanent) {
|
||||||
if (!permanent || uri == NULL) {
|
gst_hls_demux_set_location (demux, redirect_uri, redirect_uri);
|
||||||
g_free (uri);
|
} else {
|
||||||
gst_query_parse_uri (query, &uri);
|
gst_hls_demux_set_location (demux, uri, redirect_uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_hls_demux_set_location (demux, uri);
|
|
||||||
g_free (uri);
|
g_free (uri);
|
||||||
|
g_free (redirect_uri);
|
||||||
}
|
}
|
||||||
gst_query_unref (query);
|
gst_query_unref (query);
|
||||||
|
|
||||||
|
@ -1291,7 +1291,7 @@ gst_hls_demux_reset (GstHLSDemux * demux, gboolean dispose)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dispose) {
|
if (!dispose) {
|
||||||
demux->client = gst_m3u8_client_new ("");
|
demux->client = gst_m3u8_client_new ("", NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_segment_init (&demux->segment, GST_FORMAT_TIME);
|
gst_segment_init (&demux->segment, GST_FORMAT_TIME);
|
||||||
|
@ -1324,12 +1324,14 @@ gst_hls_demux_reset (GstHLSDemux * demux, gboolean dispose)
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_hls_demux_set_location (GstHLSDemux * demux, const gchar * uri)
|
gst_hls_demux_set_location (GstHLSDemux * demux, const gchar * uri,
|
||||||
|
const gchar * base_uri)
|
||||||
{
|
{
|
||||||
if (demux->client)
|
if (demux->client)
|
||||||
gst_m3u8_client_free (demux->client);
|
gst_m3u8_client_free (demux->client);
|
||||||
demux->client = gst_m3u8_client_new (uri);
|
demux->client = gst_m3u8_client_new (uri, base_uri);
|
||||||
GST_INFO_OBJECT (demux, "Changed location: %s", uri);
|
GST_INFO_OBJECT (demux, "Changed location: %s (base uri: %s)", uri,
|
||||||
|
GST_STR_NULL (base_uri));
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1489,7 +1491,6 @@ gst_hls_demux_update_playlist (GstHLSDemux * demux, gboolean update,
|
||||||
GstBuffer *buf;
|
GstBuffer *buf;
|
||||||
gchar *playlist;
|
gchar *playlist;
|
||||||
gboolean updated = FALSE;
|
gboolean updated = FALSE;
|
||||||
|
|
||||||
const gchar *uri = gst_m3u8_client_get_current_uri (demux->client);
|
const gchar *uri = gst_m3u8_client_get_current_uri (demux->client);
|
||||||
|
|
||||||
download =
|
download =
|
||||||
|
@ -1499,6 +1500,19 @@ gst_hls_demux_update_playlist (GstHLSDemux * demux, gboolean update,
|
||||||
if (download == NULL)
|
if (download == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
/* Set the base URI of the playlist to the redirect target if any */
|
||||||
|
GST_M3U8_CLIENT_LOCK (demux->client);
|
||||||
|
g_free (demux->client->current->uri);
|
||||||
|
g_free (demux->client->current->base_uri);
|
||||||
|
if (download->redirect_permanent) {
|
||||||
|
demux->client->current->uri = g_strdup (download->redirect_uri);
|
||||||
|
demux->client->current->base_uri = NULL;
|
||||||
|
} else {
|
||||||
|
demux->client->current->uri = g_strdup (download->uri);
|
||||||
|
demux->client->current->base_uri = g_strdup (download->redirect_uri);
|
||||||
|
}
|
||||||
|
GST_M3U8_CLIENT_UNLOCK (demux->client);
|
||||||
|
|
||||||
buf = gst_fragment_get_buffer (download);
|
buf = gst_fragment_get_buffer (download);
|
||||||
playlist = gst_hls_src_buf_to_utf8_playlist (buf);
|
playlist = gst_hls_src_buf_to_utf8_playlist (buf);
|
||||||
g_object_unref (download);
|
g_object_unref (download);
|
||||||
|
|
|
@ -50,13 +50,15 @@ gst_m3u8_new (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_m3u8_set_uri (GstM3U8 * self, gchar * uri)
|
gst_m3u8_set_uri (GstM3U8 * self, gchar * uri, gchar * base_uri)
|
||||||
{
|
{
|
||||||
g_return_if_fail (self != NULL);
|
g_return_if_fail (self != NULL);
|
||||||
|
|
||||||
if (self->uri)
|
g_free (self->uri);
|
||||||
g_free (self->uri);
|
|
||||||
self->uri = uri;
|
self->uri = uri;
|
||||||
|
|
||||||
|
g_free (self->base_uri);
|
||||||
|
self->base_uri = base_uri;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -65,6 +67,7 @@ gst_m3u8_free (GstM3U8 * self)
|
||||||
g_return_if_fail (self != NULL);
|
g_return_if_fail (self != NULL);
|
||||||
|
|
||||||
g_free (self->uri);
|
g_free (self->uri);
|
||||||
|
g_free (self->base_uri);
|
||||||
g_free (self->codecs);
|
g_free (self->codecs);
|
||||||
g_free (self->key);
|
g_free (self->key);
|
||||||
|
|
||||||
|
@ -322,7 +325,7 @@ gst_m3u8_update (GstM3U8 * self, gchar * data, gboolean * updated)
|
||||||
goto next_line;
|
goto next_line;
|
||||||
}
|
}
|
||||||
|
|
||||||
data = uri_join (self->uri, data);
|
data = uri_join (self->base_uri ? self->base_uri : self->uri, data);
|
||||||
if (data == NULL)
|
if (data == NULL)
|
||||||
goto next_line;
|
goto next_line;
|
||||||
|
|
||||||
|
@ -333,7 +336,7 @@ gst_m3u8_update (GstM3U8 * self, gchar * data, gboolean * updated)
|
||||||
gst_m3u8_free (list);
|
gst_m3u8_free (list);
|
||||||
g_free (data);
|
g_free (data);
|
||||||
} else {
|
} else {
|
||||||
gst_m3u8_set_uri (list, data);
|
gst_m3u8_set_uri (list, data, NULL);
|
||||||
self->lists = g_list_append (self->lists, list);
|
self->lists = g_list_append (self->lists, list);
|
||||||
}
|
}
|
||||||
list = NULL;
|
list = NULL;
|
||||||
|
@ -427,12 +430,12 @@ gst_m3u8_update (GstM3U8 * self, gchar * data, gboolean * updated)
|
||||||
if (uri[0] == '"')
|
if (uri[0] == '"')
|
||||||
uri += 1;
|
uri += 1;
|
||||||
|
|
||||||
uri = uri_join (self->uri, uri);
|
uri = uri_join (self->base_uri ? self->base_uri : self->uri, uri);
|
||||||
g_free (urip);
|
g_free (urip);
|
||||||
|
|
||||||
if (uri == NULL)
|
if (uri == NULL)
|
||||||
continue;
|
continue;
|
||||||
gst_m3u8_set_uri (new_list, uri);
|
gst_m3u8_set_uri (new_list, uri, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -484,7 +487,8 @@ gst_m3u8_update (GstM3U8 * self, gchar * data, gboolean * updated)
|
||||||
if (key[0] == '"')
|
if (key[0] == '"')
|
||||||
key += 1;
|
key += 1;
|
||||||
|
|
||||||
self->key = uri_join (self->uri, key);
|
self->key =
|
||||||
|
uri_join (self->base_uri ? self->base_uri : self->uri, key);
|
||||||
g_free (keyp);
|
g_free (keyp);
|
||||||
} else if (g_str_equal (a, "IV")) {
|
} else if (g_str_equal (a, "IV")) {
|
||||||
gchar *ivp = v;
|
gchar *ivp = v;
|
||||||
|
@ -591,7 +595,7 @@ gst_m3u8_update (GstM3U8 * self, gchar * data, gboolean * updated)
|
||||||
}
|
}
|
||||||
|
|
||||||
GstM3U8Client *
|
GstM3U8Client *
|
||||||
gst_m3u8_client_new (const gchar * uri)
|
gst_m3u8_client_new (const gchar * uri, const gchar * base_uri)
|
||||||
{
|
{
|
||||||
GstM3U8Client *client;
|
GstM3U8Client *client;
|
||||||
|
|
||||||
|
@ -604,7 +608,7 @@ gst_m3u8_client_new (const gchar * uri)
|
||||||
client->sequence_position = 0;
|
client->sequence_position = 0;
|
||||||
client->update_failed_count = 0;
|
client->update_failed_count = 0;
|
||||||
g_mutex_init (&client->lock);
|
g_mutex_init (&client->lock);
|
||||||
gst_m3u8_set_uri (client->main, g_strdup (uri));
|
gst_m3u8_set_uri (client->main, g_strdup (uri), g_strdup (base_uri));
|
||||||
|
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,9 @@ typedef struct _GstM3U8Client GstM3U8Client;
|
||||||
|
|
||||||
struct _GstM3U8
|
struct _GstM3U8
|
||||||
{
|
{
|
||||||
gchar *uri;
|
gchar *uri; /* actually downloaded URI */
|
||||||
|
gchar *base_uri; /* URI to use as base for resolving relative URIs.
|
||||||
|
* This will be different to uri in case of redirects */
|
||||||
|
|
||||||
gboolean endlist; /* if ENDLIST has been reached */
|
gboolean endlist; /* if ENDLIST has been reached */
|
||||||
gint version; /* last EXT-X-VERSION */
|
gint version; /* last EXT-X-VERSION */
|
||||||
|
@ -85,7 +87,7 @@ struct _GstM3U8Client
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
GstM3U8Client *gst_m3u8_client_new (const gchar * uri);
|
GstM3U8Client *gst_m3u8_client_new (const gchar * uri, const gchar * base_uri);
|
||||||
void gst_m3u8_client_free (GstM3U8Client * client);
|
void gst_m3u8_client_free (GstM3U8Client * client);
|
||||||
gboolean gst_m3u8_client_update (GstM3U8Client * client, gchar * data);
|
gboolean gst_m3u8_client_update (GstM3U8Client * client, gchar * data);
|
||||||
void gst_m3u8_client_set_current (GstM3U8Client * client, GstM3U8 * m3u8);
|
void gst_m3u8_client_set_current (GstM3U8Client * client, GstM3U8 * m3u8);
|
||||||
|
|
Loading…
Reference in a new issue