[vlc-devel] [PATCH] Playlist demuxer called BITPLS.c.

Marijn Swenne marijn.swenne at gmail.com
Thu May 20 20:49:09 CEST 2010


Functionality is ment to be no different from PLS.c
Patch is only a personal prove of concept for adding a playlist demuxer.
---
 modules/demux/playlist/Modules.am |    1 +
 modules/demux/playlist/bitpls.c   |  239 +++++++++++++++++++++++++++++++++++++
 modules/demux/playlist/playlist.c |   43 +++----
 modules/demux/playlist/playlist.h |    3 +
 po/POTFILES.in                    |    1 +
 5 files changed, 260 insertions(+), 27 deletions(-)
 create mode 100644 modules/demux/playlist/bitpls.c

diff --git a/modules/demux/playlist/Modules.am b/modules/demux/playlist/Modules.am
index 2387c24..cea6c2e 100644
--- a/modules/demux/playlist/Modules.am
+++ b/modules/demux/playlist/Modules.am
@@ -10,6 +10,7 @@ SOURCES_playlist = \
 	playlist.c \
 	playlist.h \
 	pls.c \
+	bitpls.c \
 	podcast.c \
 	qtl.c \
 	ram.c \
diff --git a/modules/demux/playlist/bitpls.c b/modules/demux/playlist/bitpls.c
new file mode 100644
index 0000000..b5a8e19
--- /dev/null
+++ b/modules/demux/playlist/bitpls.c
@@ -0,0 +1,239 @@
+/*****************************************************************************
+ * pls.c : PLS playlist format import
+ *****************************************************************************
+ * Copyright (C) 2004 the VideoLAN team
+ * $Id$
+ *
+ * Authors: Clément Stenac <zorglub at videolan.org>
+ * Authors: Sigmund Augdal Helberg <dnumgis at videolan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <vlc_common.h>
+#include <vlc_demux.h>
+
+#include "playlist.h"
+
+struct demux_sys_t
+{
+    char *psz_prefix;
+};
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static int Demux( demux_t *p_demux);
+static int Control( demux_t *p_demux, int i_query, va_list args );
+
+/*****************************************************************************
+ * Import_BITPLS: main import function
+ *****************************************************************************/
+int Import_BITPLS( vlc_object_t *p_this )
+{
+    demux_t *p_demux = (demux_t *)p_this;
+    const uint8_t *p_peek;
+    CHECK_PEEK( p_peek, 10 );
+
+    if( POKE( p_peek, "[bittorrentplaylist]", 10 ) ||
+
+	demux_IsPathExtension( p_demux, ".bitpls" )   || demux_IsForced( p_demux, "bitpls" ) )
+    {
+        ;
+    }
+    else return VLC_EGENERIC;
+
+    STANDARD_DEMUX_INIT_MSG(  "found valid BITPLS playlist file");
+    p_demux->p_sys->psz_prefix = FindPrefix( p_demux );
+
+    return VLC_SUCCESS;
+}
+
+/*****************************************************************************
+ * Deactivate: frees unused data
+ *****************************************************************************/
+void Close_BITPLS( vlc_object_t *p_this )
+{
+    demux_t *p_demux = (demux_t *)p_this;
+    free( p_demux->p_sys->psz_prefix );
+    free( p_demux->p_sys );
+}
+
+static int Demux( demux_t *p_demux )
+{
+    mtime_t        i_duration = -1;
+    char          *psz_name = NULL;
+    char          *psz_line;
+    char          *psz_mrl = NULL;
+    char          *psz_mrl_orig = NULL;
+    char          *psz_key;
+    char          *psz_value;
+    int            i_item = -1;
+    int            i_new_item = 0;
+    int            i_key_length;
+    input_item_t *p_input;
+
+    input_item_t *p_current_input = GetCurrentItem(p_demux);
+
+    while( ( psz_line = stream_ReadLine( p_demux->s ) ) )
+    {
+        if( !strncasecmp( psz_line, "[bittorrentplaylist]", sizeof("[bittorrentplaylist]")-1 ) )
+        {
+            free( psz_line );
+            continue;
+        }
+        psz_key = psz_line;
+        psz_value = strchr( psz_line, '=' );
+        if( psz_value )
+        {
+            *psz_value='\0';
+            psz_value++;
+        }
+        else
+        {
+            msg_Warn( p_demux, "invalid line in bitpls file" );
+            free( psz_line );
+            continue;
+        }
+        if( !strcasecmp( psz_key, "version" ) )
+        {
+            msg_Dbg( p_demux, "bitpls file version: %s", psz_value );
+            free( psz_line );
+            continue;
+        }
+        if( !strcasecmp( psz_key, "numberofentries" ) )
+        {
+            msg_Dbg( p_demux, "bitpls should have %d entries", atoi(psz_value) );
+            free( psz_line);
+            continue;
+        }
+        /* find the number part of of file1, title1 or length1 etc */
+        i_key_length = strlen( psz_key );
+        if( i_key_length >= 4 ) /* Ref1 type case */
+        {
+            i_new_item = atoi( psz_key + 3 );
+            if( i_new_item == 0 && i_key_length >= 5 ) /* file1 type case */
+            {
+                i_new_item = atoi( psz_key + 4 );
+                if( i_new_item == 0 && i_key_length >= 6 ) /* title1 type case */
+                {
+                    i_new_item = atoi( psz_key + 5 );
+                    if( i_new_item == 0 && i_key_length >= 7 ) /* length1 type case */
+                    {
+                        i_new_item = atoi( psz_key + 6 );
+                    }
+                }
+            }
+        }
+        if( i_new_item == 0 )
+        {
+            msg_Warn( p_demux, "couldn't find number of items" );
+            free( psz_line );
+            continue;
+        }
+        if( i_item == -1 )
+        {
+            i_item = i_new_item;
+        }
+        /* we found a new item, insert the previous */
+        if( i_item != i_new_item )
+        {
+            if( psz_mrl )
+            {
+                p_input = input_item_New( p_demux, psz_mrl, psz_name );
+                input_item_CopyOptions( p_current_input, p_input );
+                input_item_AddSubItem( p_current_input, p_input );
+                vlc_gc_decref( p_input );
+            }
+            else
+            {
+                msg_Warn( p_demux, "no file= part found for item %d", i_item );
+            }
+            free( psz_name );
+            psz_name = NULL;
+            i_duration = -1;
+            i_item = i_new_item;
+            i_new_item = 0;
+        }
+        if( !strncasecmp( psz_key, "file", sizeof("file") -1 ) ||
+            !strncasecmp( psz_key, "Ref", sizeof("Ref") -1 ) )
+        {
+            free( psz_mrl_orig );
+            psz_mrl_orig =
+            psz_mrl = ProcessMRL( psz_value, p_demux->p_sys->psz_prefix );
+
+            if( !strncasecmp( psz_key, "Ref", sizeof("Ref") -1 ) )
+            {
+                if( !strncasecmp( psz_mrl, "http://", sizeof("http://") -1 ) )
+                {
+                    psz_mrl++;
+                    psz_mrl[0] = 'm';
+                    psz_mrl[1] = 'm';
+                    psz_mrl[2] = 's';
+                }
+            }
+        }
+        else if( !strncasecmp( psz_key, "title", sizeof("title") -1 ) )
+        {
+            free( psz_name );
+            psz_name = strdup( psz_value );
+        }
+        else if( !strncasecmp( psz_key, "length", sizeof("length") -1 ) )
+        {
+            i_duration = atoi( psz_value );
+            if( i_duration != -1 )
+            {
+                i_duration *= 1000000;
+            }
+        }
+        else
+        {
+            msg_Warn( p_demux, "unknown key found in pls file: %s", psz_key );
+        }
+        free( psz_line );
+    }
+    /* Add last object */
+    if( psz_mrl )
+    {
+        p_input = input_item_New( p_demux, psz_mrl, psz_name );
+        input_item_CopyOptions( p_current_input, p_input );
+        input_item_AddSubItem( p_current_input, p_input );
+        vlc_gc_decref( p_input );
+        free( psz_mrl_orig );
+        psz_mrl = NULL;
+    }
+    else
+    {
+        msg_Warn( p_demux, "no file= part found for item %d", i_item );
+    }
+    free( psz_name );
+    psz_name = NULL;
+
+    vlc_gc_decref(p_current_input);
+    return 0; /* Needed for correct operation of go back */
+}
+
+static int Control( demux_t *p_demux, int i_query, va_list args )
+{
+    VLC_UNUSED(p_demux); VLC_UNUSED(i_query); VLC_UNUSED(args);
+    return VLC_EGENERIC;
+}
diff --git a/modules/demux/playlist/playlist.c b/modules/demux/playlist/playlist.c
index de14c4a..b3ccfec 100644
--- a/modules/demux/playlist/playlist.c
+++ b/modules/demux/playlist/playlist.c
@@ -31,10 +31,6 @@
 #include <vlc_common.h>
 #include <vlc_plugin.h>
 #include <vlc_demux.h>
-#include <vlc_url.h>
-#ifdef WIN32
-# include <ctype.h>
-#endif
 
 #include "playlist.h"
 
@@ -61,7 +57,8 @@ vlc_module_begin ()
     add_bool( "playlist-autostart", true, NULL,
               AUTOSTART_TEXT, AUTOSTART_LONGTEXT, false )
 
-    add_obsolete_integer( "parent-item" ) /* removed since 1.1.0 */
+    add_integer( "parent-item", 0, NULL, NULL, NULL, true )
+        change_internal ()
 
     add_bool( "playlist-skip-ads", true, NULL,
               SKIP_ADS_TEXT, SKIP_ADS_LONGTEXT, false )
@@ -89,6 +86,12 @@ vlc_module_begin ()
         set_capability( "demux", 10 )
         set_callbacks( Import_PLS, Close_PLS )
     add_submodule ()
+        set_description( N_("BITPLS playlist import") )
+        add_shortcut( "playlist" )
+        add_shortcut( "bitpls-open" )
+        set_capability( "demux", 10 )
+        set_callbacks( Import_BITPLS, Close_BITPLS )
+    add_submodule ()
         set_description( N_("B4S playlist import") )
         add_shortcut( "playlist" )
         add_shortcut( "b4s-open" )
@@ -228,33 +231,19 @@ char *ProcessMRL( const char *psz_mrl, const char *psz_prefix )
      * PB: on some file systems, ':' are valid characters though */
 
     /* Simple cases first */
-    if( !psz_mrl || !*psz_mrl )
-        return NULL;
-    if( !psz_prefix || !*psz_prefix )
-        goto uri;
+    if( !psz_mrl || !*psz_mrl ) return NULL;
+    if( !psz_prefix || !*psz_prefix ) return strdup( psz_mrl );
 
     /* Check if the line specifies an absolute path */
-    /* FIXME: that's wrong if the playlist is not a local file */
-    if( *psz_mrl == DIR_SEP_CHAR )
-        goto uri;
-#ifdef WIN32
-    /* Drive letter (this assumes URL scheme are not a single character) */
-    if( isalpha(psz_mrl[0]) && psz_mrl[1] == ':' )
-        goto uri;
-#endif
-    if( strstr( psz_mrl, "://" ) )
-        return strdup( psz_mrl );
+    if( *psz_mrl == '/' || *psz_mrl == '\\' ) return strdup( psz_mrl );
+
+    /* Check if the line specifies an mrl/url
+     * (and on win32, contains a drive letter) */
+    if( strchr( psz_mrl, ':' ) ) return strdup( psz_mrl );
 
     /* This a relative path, prepend the prefix */
     char *ret;
-    char *postfix = encode_URI_component( psz_mrl );
-    /* FIXME: postfix may not be encoded correctly (esp. slashes) */
-    if( postfix == NULL
-     || asprintf( &ret, "%s%s", psz_prefix, postfix ) == -1 )
+    if( asprintf( &ret, "%s%s", psz_prefix, psz_mrl ) == -1 )
         ret = NULL;
-    free( postfix );
     return ret;
-
-uri:
-    return make_URI( psz_mrl );
 }
diff --git a/modules/demux/playlist/playlist.h b/modules/demux/playlist/playlist.h
index 3c3c807..8890107 100644
--- a/modules/demux/playlist/playlist.h
+++ b/modules/demux/playlist/playlist.h
@@ -41,6 +41,9 @@ void Close_RAM ( vlc_object_t * );
 int Import_PLS ( vlc_object_t * );
 void Close_PLS ( vlc_object_t * );
 
+int Import_BITPLS ( vlc_object_t * );
+void Close_BITPLS ( vlc_object_t * );
+
 int Import_B4S ( vlc_object_t * );
 void Close_B4S ( vlc_object_t * );
 
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 682e964..5047405 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -498,6 +498,7 @@ modules/demux/playlist/m3u.c
 modules/demux/playlist/playlist.c
 modules/demux/playlist/playlist.h
 modules/demux/playlist/pls.c
+modules/demux/playlist/bitpls.c
 modules/demux/playlist/podcast.c
 modules/demux/playlist/qtl.c
 modules/demux/playlist/sgimb.c
-- 
1.7.0.4




More information about the vlc-devel mailing list