[vlc-devel] [vlc-commits] playlist: Rewrite WPL module

Tristan Matthews tmatth at videolan.org
Fri Mar 13 15:25:34 CET 2015


On Fri, Mar 13, 2015 at 9:21 AM, Hugo Beauzée-Luyssen <git at videolan.org> wrote:
> 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 );

msg_Dbg?

> +            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;
> +}
> +
>
> _______________________________________________
> vlc-commits mailing list
> vlc-commits at videolan.org
> https://mailman.videolan.org/listinfo/vlc-commits



More information about the vlc-devel mailing list