[vlc-commits] playlist: Rewrite WPL module
Hugo Beauzée-Luyssen
git at videolan.org
Fri Mar 13 15:21:00 CET 2015
vlc | branch: master | Hugo Beauzée-Luyssen <hugo at beauzee.fr> | Fri Mar 13 15:18:38 2015 +0100| [4d5caefff0b10f6774dfad944b861ec2bfa7d0da] | committer: Hugo Beauzée-Luyssen
playlist: Rewrite WPL module
It is now using our XML parser, and is licensed as GPL
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=4d5caefff0b10f6774dfad944b861ec2bfa7d0da
---
modules/demux/Makefile.am | 1 +
modules/demux/playlist/playlist.c | 5 +
modules/demux/playlist/wpl.c | 213 +++++++++++++++++++++++++++++++++++++
3 files changed, 219 insertions(+)
diff --git a/modules/demux/Makefile.am b/modules/demux/Makefile.am
index b5d2d8a..78dc915 100644
--- a/modules/demux/Makefile.am
+++ b/modules/demux/Makefile.am
@@ -220,6 +220,7 @@ libplaylist_plugin_la_SOURCES = \
demux/playlist/ram.c \
demux/playlist/sgimb.c \
demux/playlist/shoutcast.c \
+ demux/playlist/wpl.c \
demux/playlist/xspf.c \
demux/playlist/directory.c \
demux/playlist/playlist.c demux/playlist/playlist.h
diff --git a/modules/demux/playlist/playlist.c b/modules/demux/playlist/playlist.c
index 92d30aa..07e47e1 100644
--- a/modules/demux/playlist/playlist.c
+++ b/modules/demux/playlist/playlist.c
@@ -136,6 +136,11 @@ vlc_module_begin ()
set_capability( "demux", 10 )
set_callbacks( Import_iTML, Close_iTML )
add_submodule ()
+ set_description( N_("WPL playlist import") )
+ add_shortcut( "playlist", "wpl" )
+ set_capability( "demux", 10 )
+ set_callbacks( Import_WPL, Close_WPL )
+ add_submodule ()
set_description( N_("Directory import") )
add_shortcut( "playlist", "directory" )
set_capability( "demux", 10 )
diff --git a/modules/demux/playlist/wpl.c b/modules/demux/playlist/wpl.c
new file mode 100644
index 0000000..e639799
--- /dev/null
+++ b/modules/demux/playlist/wpl.c
@@ -0,0 +1,213 @@
+/*****************************************************************************
+ * wpl.c : WPL playlist import
+ *****************************************************************************
+ * Copyright (C) 2015 VLC authors and VideoLAN
+ *
+ * Authors: Hugo Beauzée-Luyssen <hugo at beauzee.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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.
+ *****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <vlc_common.h>
+#include <vlc_demux.h>
+#include <vlc_xml.h>
+
+#include "playlist.h"
+
+struct demux_sys_t
+{
+ xml_t* p_xml;
+ xml_reader_t* p_reader;
+ char* psz_prefix;
+};
+
+static void read_head( demux_t* p_demux, input_item_t* p_input )
+{
+ demux_sys_t* p_sys = p_demux->p_sys;
+ const char* psz_name;
+ int i_type;
+
+ do
+ {
+ i_type = xml_ReaderNextNode( p_sys->p_reader, &psz_name );
+ if ( !strcasecmp( psz_name, "meta" ) )
+ {
+ char* psz_attribute_name = NULL;
+ char* psz_attribute_value = NULL;
+ while (!psz_attribute_name || !psz_attribute_value)
+ {
+ const char* psz_attr = NULL;
+ const char* psz_val = NULL;
+ psz_attr = xml_ReaderNextAttr( p_sys->p_reader, &psz_val );
+ if ( !psz_attr || !psz_val )
+ break;
+ if ( !strcasecmp( psz_attr, "name" ) )
+ psz_attribute_name = strdup( psz_val );
+ else if ( !strcasecmp( psz_attr, "content" ) )
+ psz_attribute_value = strdup( psz_val );
+ }
+ printf( "name: %s; value: %s\n", psz_attribute_name, psz_attribute_value );
+ if ( psz_attribute_name && psz_attribute_value )
+ {
+ if ( !strcasecmp( psz_attribute_name, "TotalDuration" ) )
+ input_item_SetDuration( p_input, atoll( psz_attribute_value ) );
+ else if ( !strcasecmp( psz_attribute_name, "Author" ) )
+ input_item_SetPublisher( p_input, psz_attribute_value );
+ else if ( !strcasecmp( psz_attribute_name, "Rating" ) )
+ input_item_SetRating( p_input, psz_attribute_value );
+ else if ( !strcasecmp( psz_attribute_name, "Genre" ) )
+ input_item_SetGenre( p_input, psz_attribute_value );
+ }
+ free( psz_attribute_name );
+ free( psz_attribute_value );
+ }
+ else if ( !strcasecmp( psz_name, "title" ) )
+ {
+ const char* psz_title;
+ int i_type = xml_ReaderNextNode( p_sys->p_reader, &psz_title );
+ if ( i_type == XML_READER_TEXT && psz_title != NULL )
+ input_item_SetTitle( p_input, psz_title );
+ }
+ } while ( i_type != XML_READER_ENDELEM || strcasecmp( psz_name, "head" ) );
+}
+
+static void read_body( demux_t* p_demux, input_item_node_t* p_node )
+{
+ demux_sys_t* p_sys = p_demux->p_sys;
+ const char* psz_name;
+ int i_type;
+
+ i_type = xml_ReaderNextNode( p_sys->p_reader, &psz_name );
+ if ( i_type != XML_READER_STARTELEM || strcasecmp( psz_name, "seq" ) )
+ {
+ msg_Err( p_demux, "Expected opening <seq> tag. Got <%s> with type %d", psz_name, i_type );
+ return;
+ }
+
+ do
+ {
+ i_type = xml_ReaderNextNode( p_sys->p_reader, &psz_name );
+ if ( !strcasecmp( psz_name, "media" ) )
+ {
+ const char* psz_attr = NULL;
+ const char* psz_val = NULL;
+ while ((psz_attr = xml_ReaderNextAttr( p_sys->p_reader, &psz_val )))
+ {
+ if ( !psz_val )
+ continue;
+ if (!strcasecmp( psz_attr, "src" ) )
+ {
+ char* mrl = ProcessMRL( psz_val, p_sys->psz_prefix );
+ if ( unlikely( !mrl ) )
+ return;
+ input_item_t* p_item = input_item_NewExt( mrl, NULL, 0, NULL, 0, -1 );
+ if ( likely( p_item ) )
+ {
+ input_item_node_AppendItem( p_node, p_item );
+ input_item_Release( p_item );
+ }
+ free( mrl );
+ }
+ }
+ }
+ } while ( i_type != XML_READER_ENDELEM || strcasecmp( psz_name, "seq" ) );
+
+ i_type = xml_ReaderNextNode( p_sys->p_reader, &psz_name );
+ if ( i_type != XML_READER_ENDELEM || strcasecmp( psz_name, "body" ) )
+ msg_Err( p_demux, "Expected closing <body> tag. Got: <%s> with type %d", psz_name, i_type );
+}
+
+static int Demux( demux_t* p_demux )
+{
+ const char* psz_name;
+ int i_type;
+
+ demux_sys_t* p_sys = p_demux->p_sys;
+ input_item_t* p_input = GetCurrentItem( p_demux );
+ input_item_node_t* p_node = input_item_node_Create( p_input );
+ p_sys->psz_prefix = FindPrefix( p_demux );
+
+ do
+ {
+ i_type = xml_ReaderNextNode( p_sys->p_reader, &psz_name );
+ if ( i_type == XML_READER_STARTELEM && !strcasecmp( psz_name, "head" ) )
+ read_head( p_demux, p_input );
+ else if ( i_type == XML_READER_STARTELEM && !strcasecmp( psz_name, "body" ) )
+ read_body( p_demux, p_node );
+ } while (i_type != XML_READER_ENDELEM || strcasecmp( psz_name, "smil" ) );
+
+ input_item_node_PostAndDelete( p_node );
+ input_item_Release( p_input );
+ return 0;
+}
+
+void Close_WPL( vlc_object_t* p_this )
+{
+ demux_t *p_demux = (demux_t*)p_this;
+ demux_sys_t* p_sys = p_demux->p_sys;
+
+ free( p_sys->psz_prefix );
+ if ( p_sys->p_reader )
+ xml_ReaderDelete( p_sys->p_reader );
+ if ( p_sys->p_xml )
+ xml_Delete( p_sys->p_xml );
+ free( p_sys );
+}
+
+int Import_WPL( vlc_object_t* p_this )
+{
+ demux_t* p_demux = (demux_t*)p_this;
+ if( !demux_IsPathExtension( p_demux, ".wpl" ) &&
+ !demux_IsPathExtension( p_demux, ".zpl" ) )
+ return VLC_EGENERIC;
+
+ DEMUX_INIT_COMMON();
+
+ demux_sys_t* p_sys = p_demux->p_sys;
+
+ p_sys->p_xml = xml_Create( p_demux );
+ if ( !p_sys->p_xml )
+ {
+ msg_Err( p_demux, "Failed to create an XML parser" );
+ Close_WPL( p_this );
+ return VLC_EGENERIC;
+ }
+
+ p_sys->p_reader = xml_ReaderCreate( p_sys->p_xml, p_demux->s );
+ if ( !p_sys->p_reader )
+ {
+ msg_Err( p_demux, "Failed to create an XML reader" );
+ Close_WPL( p_this );
+ return VLC_EGENERIC;
+ }
+
+ const char* psz_name;
+ int type = xml_ReaderNextNode( p_sys->p_reader, &psz_name );
+ if ( type != XML_READER_STARTELEM || strcasecmp( psz_name, "smil" ) )
+ {
+ msg_Err( p_demux, "Invalid WPL playlist. Root element should have been <smil>" );
+ Close_WPL( p_this );
+ return VLC_EGENERIC;
+ }
+
+ msg_Dbg( p_demux, "Found valid WPL playlist" );
+
+ return VLC_SUCCESS;
+}
+
More information about the vlc-commits
mailing list