xspf.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:9k
源码类别:

midi

开发平台:

Unix_Linux

  1. /******************************************************************************
  2.  * xspf.c : XSPF playlist export functions
  3.  ******************************************************************************
  4.  * Copyright (C) 2006-2009 the VideoLAN team
  5.  * $Id: 923d57b5ac42bdc778839f7b627e4b94fb0e2ac1 $
  6.  *
  7.  * Authors: Daniel Stränger <vlc at schmaller dot de>
  8.  *          Yoann Peronneau <yoann@videolan.org>
  9.  *
  10.  * This program is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU General Public License as published by
  12.  * the Free Software Foundation; either version 2 of the License, or
  13.  * (at your option) any later version.
  14.  *
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  * GNU General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this program; if not, write to the Free Software
  22.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  23.  *******************************************************************************/
  24. /**
  25.  * file modules/misc/playlist/xspf.c
  26.  * brief XSPF playlist export functions
  27.  */
  28. #ifdef HAVE_CONFIG_H
  29. # include "config.h"
  30. #endif
  31. #include <vlc_common.h>
  32. #include <vlc_playlist.h>
  33. #include <vlc_input.h>
  34. #include <vlc_strings.h>
  35. #include <vlc_url.h>
  36. #include "xspf.h"
  37. #include <assert.h>
  38. static void xspf_export_item( playlist_item_t *, FILE *, int * );
  39. static void xspf_extension_item( playlist_item_t *, FILE *, int * );
  40. /**
  41.  * brief Prints the XSPF header to file, writes each item by xspf_export_item()
  42.  * and closes the open xml elements
  43.  * param p_this the VLC playlist object
  44.  * return VLC_SUCCESS if some memory is available, otherwise VLC_ENONMEM
  45.  */
  46. int xspf_export_playlist( vlc_object_t *p_this )
  47. {
  48.     const playlist_t *p_playlist = (playlist_t *)p_this;
  49.     const playlist_export_t *p_export =
  50.         (playlist_export_t *)p_playlist->p_private;
  51.     int               i, i_count;
  52.     char             *psz_temp;
  53.     playlist_item_t  *p_node = p_export->p_root;
  54.     /* write XSPF XML header */
  55.     fprintf( p_export->p_file, "<?xml version="1.0" encoding="UTF-8"?>n" );
  56.     fprintf( p_export->p_file,
  57.              "<playlist version="1" xmlns="http://xspf.org/ns/0/" " 
  58.              "xmlns:vlc="http://www.videolan.org/vlc/playlist/ns/0/">n" );
  59.     if( !p_node ) return VLC_SUCCESS;
  60.     /* save name of the playlist node */
  61.     psz_temp = convert_xml_special_chars( p_node->p_input->psz_name );
  62.     if( *psz_temp )
  63.     {
  64.         fprintf(  p_export->p_file, "t<title>%s</title>n", psz_temp );
  65.     }
  66.     free( psz_temp );
  67.     /* export all items in a flat format */
  68.     fprintf( p_export->p_file, "t<trackList>n" );
  69.     i_count = 0;
  70.     for( i = 0; i < p_node->i_children; i++ )
  71.     {
  72.         xspf_export_item( p_node->pp_children[i], p_export->p_file,
  73.                           &i_count );
  74.     }
  75.     fprintf( p_export->p_file, "t</trackList>n" );
  76.     /* export the tree structure in <extension> */
  77.     fprintf( p_export->p_file, "t<extension application="" 
  78.              "http://www.videolan.org/vlc/playlist/0">n" );
  79.     i_count = 0;
  80.     for( i = 0; i < p_node->i_children; i++ )
  81.     {
  82.         xspf_extension_item( p_node->pp_children[i], p_export->p_file,
  83.                              &i_count );
  84.     }
  85.     fprintf( p_export->p_file, "t</extension>n" );
  86.     /* close the header elements */
  87.     fprintf( p_export->p_file, "</playlist>n" );
  88.     return VLC_SUCCESS;
  89. }
  90. /**
  91.  * brief exports one item to file or traverse if item is a node
  92.  * param p_item playlist item to export
  93.  * param p_file file to write xml-converted item to
  94.  * param p_i_count counter for track identifiers
  95.  */
  96. static void xspf_export_item( playlist_item_t *p_item, FILE *p_file,
  97.                               int *p_i_count )
  98. {
  99.     char *psz;
  100.     char *psz_temp;
  101.     int i;
  102.     mtime_t i_duration;
  103.     if( !p_item ) return;
  104.     /* if we get a node here, we must traverse it */
  105.     if( p_item->i_children > 0 )
  106.     {
  107.         int i;
  108.         for( i = 0; i < p_item->i_children; i++ )
  109.         {
  110.             xspf_export_item( p_item->pp_children[i], p_file, p_i_count );
  111.         }
  112.         return;
  113.     }
  114.     /* don't write empty nodes */
  115.     if( p_item->i_children == 0 )
  116.     {
  117.         return;
  118.     }
  119.     /* leaves can be written directly */
  120.     fprintf( p_file, "tt<track>n" );
  121.     /* -> the location */
  122.     char *psz_uri = input_item_GetURI( p_item->p_input );
  123.     if( psz_uri && *psz_uri )
  124.     {
  125.         psz = make_URI( psz_uri );
  126.         fprintf( p_file, "ttt<location>%s</location>n", psz );
  127.         free( psz );
  128.     }
  129.     /* -> the name/title (only if different from uri)*/
  130.     char *psz_name = input_item_GetTitle( p_item->p_input );
  131.     if( psz_name && psz_uri && strcmp( psz_uri, psz_name ) )
  132.     {
  133.         psz_temp = convert_xml_special_chars( psz_name );
  134.         if( *psz_temp )
  135.             fprintf( p_file, "ttt<title>%s</title>n", psz_temp );
  136.         free( psz_temp );
  137.     }
  138.     free( psz_name );
  139.     free( psz_uri );
  140.     if( p_item->p_input->p_meta == NULL )
  141.     {
  142.         goto xspfexportitem_end;
  143.     }
  144.     /* -> the artist/creator */
  145.     psz = input_item_GetArtist( p_item->p_input );
  146.     if( psz == NULL ) psz = strdup( "" );
  147.     psz_temp = convert_xml_special_chars( psz );
  148.     free( psz );
  149.     if( *psz_temp )
  150.     {
  151.         fprintf( p_file, "ttt<creator>%s</creator>n", psz_temp );
  152.     }
  153.     free( psz_temp );
  154.     /* -> the album */
  155.     psz = input_item_GetAlbum( p_item->p_input );
  156.     if( psz == NULL ) psz = strdup( "" );
  157.     psz_temp = convert_xml_special_chars( psz );
  158.     free( psz );
  159.     if( *psz_temp )
  160.     {
  161.         fprintf( p_file, "ttt<album>%s</album>n", psz_temp );
  162.     }
  163.     free( psz_temp );
  164.     /* -> the track number */
  165.     psz = input_item_GetTrackNum( p_item->p_input );
  166.     if( psz == NULL ) psz = strdup( "" );
  167.     if( psz && *psz )
  168.     {
  169.         int i_tracknum = atoi( psz );
  170.         if( i_tracknum > 0 )
  171.             fprintf( p_file, "ttt<trackNum>%i</trackNum>n", i_tracknum );
  172.     }
  173.     free( psz );
  174.     /* -> the description */
  175.     psz = input_item_GetDescription( p_item->p_input );
  176.     if( psz == NULL ) psz = strdup( "" );
  177.     psz_temp = convert_xml_special_chars( psz );
  178.     free( psz );
  179.     if( *psz_temp )
  180.     {
  181.         fprintf( p_file, "ttt<annotation>%s</annotation>n", psz_temp );
  182.     }
  183.     free( psz_temp );
  184.     psz = input_item_GetArtURL( p_item->p_input );
  185.     if( psz == NULL ) psz = strdup( "" );
  186.     if( !EMPTY_STR( psz ) )
  187.     {
  188.         fprintf( p_file, "ttt<image>%s</image>n", psz );
  189.     }
  190.     free( psz );
  191. xspfexportitem_end:
  192.     /* -> the duration */
  193.     i_duration = input_item_GetDuration( p_item->p_input );
  194.     if( i_duration > 0 )
  195.     {
  196.         fprintf( p_file, "ttt<duration>%ld</duration>n",
  197.                  (long)(i_duration / 1000) );
  198.     }
  199.     /* export the intenal id and the input's options (bookmarks, ...)
  200.      * in <extension> */
  201.     fprintf( p_file, "ttt<extension application="" 
  202.              "http://www.videolan.org/vlc/playlist/0">n" );
  203.     /* print the id and increase the counter */
  204.     fprintf( p_file, "tttt<vlc:id>%i</vlc:id>n", *p_i_count );
  205.     ( *p_i_count )++;
  206.     for( i = 0; i < p_item->p_input->i_options; i++ )
  207.     {
  208.         fprintf( p_file, "tttt<vlc:option>%s</vlc:option>n",
  209.                  p_item->p_input->ppsz_options[i][0] == ':' ?
  210.                  p_item->p_input->ppsz_options[i] + 1 :
  211.                  p_item->p_input->ppsz_options[i] );
  212.     }
  213.     fprintf( p_file, "ttt</extension>n" );
  214.     fprintf( p_file, "tt</track>n" );
  215.     return;
  216. }
  217. /**
  218.  * brief exports one item in extension to file and traverse if item is a node
  219.  * param p_item playlist item to export
  220.  * param p_file file to write xml-converted item to
  221.  * param p_i_count counter for track identifiers
  222.  */
  223. static void xspf_extension_item( playlist_item_t *p_item, FILE *p_file,
  224.                                  int *p_i_count )
  225. {
  226.     if( !p_item ) return;
  227.     /* if we get a node here, we must traverse it */
  228.     if( p_item->i_children >= 0 )
  229.     {
  230.         int i;
  231.         char *psz_temp = NULL;
  232.         if( p_item->p_input->psz_name )
  233.             psz_temp = convert_xml_special_chars( p_item->p_input->psz_name );
  234.         fprintf( p_file, "tt<vlc:node title="%s">n",
  235.                  psz_temp ? psz_temp : "" );
  236.         free( psz_temp );
  237.         for( i = 0; i < p_item->i_children; i++ )
  238.         {
  239.             xspf_extension_item( p_item->pp_children[i], p_file, p_i_count );
  240.         }
  241.         fprintf( p_file, "tt</vlc:node>n" );
  242.         return;
  243.     }
  244.     /* print leaf and increase the counter */
  245.     fprintf( p_file, "ttt<vlc:item tid="%i" />n", *p_i_count );
  246.     ( *p_i_count )++;
  247.     return;
  248. }