[totem-pl-parser] lines: Add support for EXTVLCOPT:audio-track-id in m3u files



commit d2caf76e0646f29ee8edcc89627398d8363dd327
Author: Bastien Nocera <hadess hadess net>
Date:   Sun Feb 8 15:01:40 2015 +0100

    lines: Add support for EXTVLCOPT:audio-track-id in m3u files
    
    As supported by VLC, and used by the Freebox Radio playlist:
    http://play.with.free.fr/index.php/radios-freebox-sur-la-freebox-revolution/

 plparse/tests/Makefile.am        |    3 +-
 plparse/tests/parser.c           |   11 ++++++
 plparse/tests/radios-freebox.m3u |    5 +++
 plparse/totem-pl-parser-lines.c  |   64 +++++++++++++++++++++++++++++--------
 plparse/totem-pl-parser.c        |    4 ++
 plparse/totem-pl-parser.h        |    7 ++++
 6 files changed, 79 insertions(+), 15 deletions(-)
---
diff --git a/plparse/tests/Makefile.am b/plparse/tests/Makefile.am
index 3317fcb..8aae89d 100644
--- a/plparse/tests/Makefile.am
+++ b/plparse/tests/Makefile.am
@@ -74,6 +74,7 @@ EXTRA_DIST =                  \
        empty-feed.xml          \
        no-url-podcast.xml      \
        xml-base.xspf           \
-       radioclasica.mp3.m3u
+       radioclasica.mp3.m3u    \
+       radios-freebox.m3u
 
 -include $(top_srcdir)/git.mk
diff --git a/plparse/tests/parser.c b/plparse/tests/parser.c
index 0997c07..7e7db30 100644
--- a/plparse/tests/parser.c
+++ b/plparse/tests/parser.c
@@ -535,6 +535,16 @@ test_itms_parsing (void)
 }
 
 static void
+test_m3u_audio_track (void)
+{
+       char *uri;
+
+       uri = get_relative_uri (TEST_SRCDIR "radios-freebox.m3u");
+       g_assert_cmpstr (parser_test_get_entry_field (uri, TOTEM_PL_PARSER_FIELD_AUDIO_TRACK), ==, "1");
+       g_free (uri);
+}
+
+static void
 test_pl_content_type (void)
 {
        char *uri;
@@ -1253,6 +1263,7 @@ main (int argc, char *argv[])
                g_test_add_func ("/parser/resolution", test_resolution);
                g_test_add_func ("/parser/parsability", test_parsability);
                g_test_add_func ("/parser/image_link", test_image_link);
+               g_test_add_func ("/parser/m3u_audio_track", test_m3u_audio_track);
                g_test_add_func ("/parser/no_url_podcast", test_no_url_podcast);
                g_test_add_func ("/parser/xml_is_text_plain", test_xml_is_text_plain);
                g_test_add_func ("/parser/compressed_content_encoding", test_compressed_content_encoding);
diff --git a/plparse/tests/radios-freebox.m3u b/plparse/tests/radios-freebox.m3u
new file mode 100644
index 0000000..cd1d31d
--- /dev/null
+++ b/plparse/tests/radios-freebox.m3u
@@ -0,0 +1,5 @@
+#EXTINF:0,10001 - Europe 1
+#EXTVLCOPT:ts-es-id-pid
+#EXTVLCOPT:no-video
+#EXTVLCOPT:audio-track-id=1001
+rtsp://mafreebox.freebox.fr/fbxtv_pub/stream?namespace=1&service=100004
diff --git a/plparse/totem-pl-parser-lines.c b/plparse/totem-pl-parser-lines.c
index 0731523..883dae9 100644
--- a/plparse/totem-pl-parser-lines.c
+++ b/plparse/totem-pl-parser-lines.c
@@ -23,6 +23,7 @@
 #include "config.h"
 
 #include <string.h>
+#include <stdlib.h>
 #include <glib.h>
 
 #ifndef TOTEM_PL_PARSER_MINI
@@ -41,7 +42,7 @@
 #ifndef TOTEM_PL_PARSER_MINI
 
 #define EXTINF "#EXTINF:"
-#define EXTVLCOPT "#EXTVLCOPT"
+#define EXTVLCOPT_AUDIOTRACK "#EXTVLCOPT:audio-track-id="
 
 static char *
 totem_pl_parser_uri_to_dos (const char *uri, GFile *output)
@@ -357,6 +358,23 @@ totem_pl_parser_get_extinfo_length (const char *extinfo)
        return res;
 }
 
+static char *
+totem_pl_parser_get_extvlcopt_audio_track (const char *line)
+{
+       int id;
+       char *end;
+
+       if (line == NULL)
+               return NULL;
+       id = strtol (line + strlen (EXTVLCOPT_AUDIOTRACK), &end, 10);
+       if (*end != '\0')
+               return NULL;
+       /* Bizarre VLC quirk? */
+       if (id > 1000)
+               id = id - 1000;
+       return g_strdup_printf ("%d", id);
+}
+
 TotemPlParserResult
 totem_pl_parser_add_m3u (TotemPlParser *parser,
                         GFile *file,
@@ -369,7 +387,7 @@ totem_pl_parser_add_m3u (TotemPlParser *parser,
        gsize size;
        guint i, num_lines;
        gboolean dos_mode = FALSE;
-       const char *extinfo;
+       const char *extinfo, *extvlcopt_audiotrack;
        char *pl_uri;
 
        if (g_file_load_contents (file, NULL, &contents, &size, NULL, NULL) == FALSE)
@@ -397,6 +415,7 @@ totem_pl_parser_add_m3u (TotemPlParser *parser,
 
        /* is non-NULL if there's an EXTINF on a preceding line */
        extinfo = NULL;
+       extvlcopt_audiotrack = NULL;
 
        /* figure out whether we're a unix m3u or dos m3u */
        if (strstr(contents, "\x0d")) {
@@ -421,6 +440,7 @@ totem_pl_parser_add_m3u (TotemPlParser *parser,
                const char *line;
                char *length;
                gint64 length_num = 0;
+               char *audio_track;
 
                line = lines[i];
 
@@ -437,6 +457,8 @@ totem_pl_parser_add_m3u (TotemPlParser *parser,
                if (line[0] == '#') {
                        if (extinfo == NULL && g_str_has_prefix (line, EXTINF) != FALSE)
                                extinfo = line;
+                       if (extvlcopt_audiotrack == NULL && g_str_has_prefix (line, EXTVLCOPT_AUDIOTRACK) != 
FALSE)
+                               extvlcopt_audiotrack = line;
                        continue;
                }
 
@@ -445,6 +467,8 @@ totem_pl_parser_add_m3u (TotemPlParser *parser,
                        length_num = totem_pl_parser_parse_duration (length, 
totem_pl_parser_is_debugging_enabled (parser));
                g_free (length);
 
+               audio_track = totem_pl_parser_get_extvlcopt_audio_track (extvlcopt_audiotrack);
+
                /* Either it's a URI, or it has a proper path ... */
                if (strstr(line, "://") != NULL
                                || line[0] == G_DIR_SEPARATOR) {
@@ -453,11 +477,13 @@ totem_pl_parser_add_m3u (TotemPlParser *parser,
                        uri = g_file_new_for_commandline_arg (line);
                        if (length_num < 0 ||
                            totem_pl_parser_parse_internal (parser, uri, NULL, parse_data) != 
TOTEM_PL_PARSER_RESULT_SUCCESS) {
-                               totem_pl_parser_add_one_uri (parser, line,
-                                               totem_pl_parser_get_extinfo_title (extinfo));
+                               totem_pl_parser_add_uri (parser,
+                                                        TOTEM_PL_PARSER_FIELD_URI, line,
+                                                        TOTEM_PL_PARSER_FIELD_TITLE, 
totem_pl_parser_get_extinfo_title (extinfo),
+                                                        TOTEM_PL_PARSER_FIELD_AUDIO_TRACK, audio_track,
+                                                        NULL);
                        }
                        g_object_unref (uri);
-                       extinfo = NULL;
                } else if (g_ascii_isalpha (line[0]) != FALSE
                           && g_str_has_prefix (line + 1, ":\\")) {
                        /* Path relative to a drive on Windows, we need to use
@@ -467,10 +493,12 @@ totem_pl_parser_add_m3u (TotemPlParser *parser,
                        lines[i] = g_strdelimit (lines[i], "\\", '/');
                        /* + 2, skip drive letter */
                        uri = g_file_get_child (base_file, line + 2);
-                       totem_pl_parser_add_one_file (parser, uri,
-                                                    totem_pl_parser_get_extinfo_title (extinfo));
+                       totem_pl_parser_add_uri (parser,
+                                                TOTEM_PL_PARSER_FIELD_URI, uri,
+                                                TOTEM_PL_PARSER_FIELD_TITLE, 
totem_pl_parser_get_extinfo_title (extinfo),
+                                                TOTEM_PL_PARSER_FIELD_AUDIO_TRACK, audio_track,
+                                                NULL);
                        g_object_unref (uri);
-                       extinfo = NULL;
                } else if (line[0] == '\\' && line[1] == '\\') {
                        /* ... Or it's in the windows smb form
                         * (\\machine\share\filename), Note drive names
@@ -481,9 +509,11 @@ totem_pl_parser_add_m3u (TotemPlParser *parser,
                        lines[i] = g_strdelimit (lines[i], "\\", '/');
                        tmpuri = g_strjoin (NULL, "smb:", line, NULL);
 
-                       totem_pl_parser_add_one_uri (parser, tmpuri,
-                                       totem_pl_parser_get_extinfo_title (extinfo));
-                       extinfo = NULL;
+                       totem_pl_parser_add_uri (parser,
+                                                TOTEM_PL_PARSER_FIELD_URI, tmpuri,
+                                                TOTEM_PL_PARSER_FIELD_TITLE, 
totem_pl_parser_get_extinfo_title (extinfo),
+                                                TOTEM_PL_PARSER_FIELD_AUDIO_TRACK, audio_track,
+                                                NULL);
 
                        g_free (tmpuri);
                } else {
@@ -497,11 +527,17 @@ totem_pl_parser_add_m3u (TotemPlParser *parser,
                                lines[i] = g_strdelimit (lines[i], "\\", '/');
                        uri = g_file_get_child (_base_file, line);
                        g_object_unref (_base_file);
-                       totem_pl_parser_add_one_file (parser, uri,
-                                                    totem_pl_parser_get_extinfo_title (extinfo));
+                       totem_pl_parser_add_uri (parser,
+                                                TOTEM_PL_PARSER_FIELD_URI, uri,
+                                                TOTEM_PL_PARSER_FIELD_TITLE, 
totem_pl_parser_get_extinfo_title (extinfo),
+                                                TOTEM_PL_PARSER_FIELD_AUDIO_TRACK, audio_track,
+                                                NULL);
                        g_object_unref (uri);
-                       extinfo = NULL;
                }
+               extinfo = NULL;
+               extvlcopt_audiotrack = NULL;
+
+               g_free (audio_track);
        }
 
        g_strfreev (lines);
diff --git a/plparse/totem-pl-parser.c b/plparse/totem-pl-parser.c
index bf46286..2f4250d 100644
--- a/plparse/totem-pl-parser.c
+++ b/plparse/totem-pl-parser.c
@@ -571,6 +571,10 @@ totem_pl_parser_class_init (TotemPlParserClass *klass)
                                     "Whether the track is playing", NULL,
                                     G_PARAM_READABLE & G_PARAM_WRITABLE);
        g_param_spec_pool_insert (totem_pl_parser_pspec_pool, pspec, TOTEM_TYPE_PL_PARSER);
+       pspec = g_param_spec_string ("audio-track", "audio-track",
+                                    "The default audio-track to play", NULL,
+                                    G_PARAM_READABLE & G_PARAM_WRITABLE);
+       g_param_spec_pool_insert (totem_pl_parser_pspec_pool, pspec, TOTEM_TYPE_PL_PARSER);
 }
 
 static void
diff --git a/plparse/totem-pl-parser.h b/plparse/totem-pl-parser.h
index 0a71731..924fc4c 100644
--- a/plparse/totem-pl-parser.h
+++ b/plparse/totem-pl-parser.h
@@ -265,6 +265,13 @@ typedef struct {
  * used when saving the state of an on-going playlist.
  **/
 #define TOTEM_PL_PARSER_FIELD_PLAYING           "playing"
+/**
+ * TOTEM_PL_PARSER_FIELD_AUDIO_TRACK:
+ *
+ * Metadata field for an entry's default audio-track selection. The default
+ * track is defined as NULL. Note that the value is sent as a string.
+ **/
+#define TOTEM_PL_PARSER_FIELD_AUDIO_TRACK       "audio-track"
 
 /**
  * TotemPlParserClass:


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]