[vlc-commits] playlist: m3u: parse tvg meta in EXTINF
Francois Cartegnie
git at videolan.org
Thu Mar 12 13:27:15 CET 2020
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Wed Mar 11 19:46:00 2020 +0100| [9eb3af029ae69ad4bf4f4efa41bed61af056fb40] | committer: Francois Cartegnie
playlist: m3u: parse tvg meta in EXTINF
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=9eb3af029ae69ad4bf4f4efa41bed61af056fb40
---
modules/demux/playlist/m3u.c | 114 ++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 113 insertions(+), 1 deletion(-)
diff --git a/modules/demux/playlist/m3u.c b/modules/demux/playlist/m3u.c
index 00ad624526..5780f94d97 100644
--- a/modules/demux/playlist/m3u.c
+++ b/modules/demux/playlist/m3u.c
@@ -217,6 +217,9 @@ struct entry_meta_s
char *psz_artist;
char *psz_album_art;
char *psz_mrl;
+ char *psz_language;
+ char *psz_tvgid;
+ char *psz_grouptitle;
vlc_tick_t i_duration;
const char**ppsz_options;
int i_options;
@@ -234,6 +237,9 @@ static void entry_meta_Clean( struct entry_meta_s *e )
free( e->psz_artist );
free( e->psz_album_art );
free( e->psz_mrl );
+ free( e->psz_language );
+ free( e->psz_tvgid );
+ free( e->psz_grouptitle );
while( e->i_options-- ) free( (char*)e->ppsz_options[e->i_options] );
}
@@ -258,6 +264,12 @@ static int CreateEntry( input_item_node_t *p_node, const struct entry_meta_s *me
input_item_SetTitle( p_input, meta->psz_name );
if( meta->psz_album_art )
input_item_SetArtURL( p_input, meta->psz_album_art );
+ if( meta->psz_language )
+ input_item_SetLanguage( p_input, meta->psz_language );
+ if( meta->psz_tvgid )
+ input_item_AddInfo( p_input, "XMLTV", "tvg-id", "%s", meta->psz_tvgid );
+ if( meta->psz_grouptitle )
+ input_item_SetAlbum( p_input, meta->psz_grouptitle );
input_item_node_AppendItem( p_node, p_input );
input_item_Release( p_input );
@@ -404,6 +416,100 @@ static void parseEXTINFTitle( char *psz_string,
}
}
+static void parseEXTINFIptvDiots( char *psz_string,
+ char *(*pf_dup)(const char *),
+ struct entry_meta_s *meta )
+{
+ char **ppsz_meta = NULL;
+ if( strncmp( psz_string, "tvg-", 4 ) &&
+ strncmp( psz_string, "group-", 6 ) )
+ return;
+ char *psz_sep = strchr( psz_string + 4, '=' );
+ if( unlikely(!psz_sep) )
+ return;
+ size_t i_keylen = psz_sep - psz_string;
+
+ if( !strncmp( psz_string + 4, "logo", i_keylen - 4 ) )
+ ppsz_meta = &meta->psz_album_art;
+ else if( !strncmp( psz_string + 4, "name", i_keylen - 4 ) )
+ ppsz_meta = &meta->psz_name;
+ else if( !strncmp( psz_string + 4, "language", i_keylen - 4 ) )
+ ppsz_meta = &meta->psz_language;
+ else if( !strncmp( psz_string + 4, "id", i_keylen - 4 ) )
+ ppsz_meta = &meta->psz_tvgid;
+ else if( !strncmp( psz_string + 6, "title", i_keylen - 4 ) )
+ ppsz_meta = &meta->psz_grouptitle;
+
+ if( !ppsz_meta || *ppsz_meta /* no overwrite */ )
+ return;
+
+ char *psz_value = psz_sep + 1;
+ size_t i_valuelen = strlen( psz_value );
+ if( unlikely(i_valuelen == 0) )
+ return;
+
+ bool b_escaped = (*psz_value == '"');
+ if( i_valuelen > 2 && b_escaped )
+ {
+ psz_value[ i_valuelen - 1 ] = 0;
+ *ppsz_meta = pf_dup( psz_value + 1 );
+ }
+ else
+ *ppsz_meta = pf_dup( psz_value );
+}
+
+static void parseEXTINFIptvDiotsInDuration( char *psz_string,
+ char *(*pf_dup)(const char *),
+ struct entry_meta_s *meta )
+{
+ for( ;; )
+ {
+ while( isspace( *psz_string ) )
+ psz_string++;
+
+ char *psz_start = psz_string;
+ bool b_escaped = false;
+ bool b_key = false;
+ bool b_value = false;
+ bool b_next = false;
+
+ for( ;!b_next; ++psz_string )
+ {
+ switch( *psz_string )
+ {
+ case '"':
+ if(!b_escaped && b_value)
+ return;
+ if(!b_key)
+ return;
+ b_value = true;
+ b_escaped = !b_escaped;
+ break;
+ case '\0':
+ if(!b_escaped && b_value)
+ parseEXTINFIptvDiots( psz_start, pf_dup, meta );
+ return;
+ case ' ':
+ if(!b_escaped)
+ {
+ *psz_string = '\0';
+ if(b_value)
+ parseEXTINFIptvDiots( psz_start, pf_dup, meta );
+ b_next = true;
+ }
+ break;
+ case '=':
+ b_key = true;
+ break;
+ default:
+ if(b_key)
+ b_value = true;
+ break;
+ }
+ }
+ }
+}
+
static void parseEXTINF( char *psz_string,
char *(*pf_dup)(const char *),
struct entry_meta_s *meta )
@@ -427,8 +533,14 @@ static void parseEXTINF( char *psz_string,
}
/* Parse duration */
- long i_parsed_duration = strtol( psz_string, NULL, 10 );
+ char *psz_end = NULL;
+ long i_parsed_duration = strtol( psz_string, &psz_end, 10 );
if( i_parsed_duration > 0 )
meta->i_duration = vlc_tick_from_sec( i_parsed_duration );
+
+ if( psz_end && psz_end != psz_string && isspace(*psz_end) )
+ {
+ parseEXTINFIptvDiotsInDuration( psz_end, pf_dup, meta );
+ }
}
More information about the vlc-commits
mailing list