id3tag.c

来自「VLC媒体播放程序」· C语言 代码 · 共 293 行

C
293
字号
/***************************************************************************** * id3tag.c: id3 tag parser/skipper based on libid3tag ***************************************************************************** * Copyright (C) 2002-2004 VideoLAN * $Id: id3tag.c,v 1.21 2004/02/14 01:53:17 gbazin Exp $ * * Authors: Sigmund Augdal <sigmunau@idi.ntnu.no> * * 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., 59 Temple Place - Suite 330, Boston, MA  02111, USA. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#include <stdlib.h>                                      /* malloc(), free() */#include <string.h>#include <vlc/vlc.h>#include <vlc/intf.h>#include <vlc/input.h>#include "ninput.h"#include <sys/types.h>#include <id3tag.h>#include "id3genres.h"/***************************************************************************** * Local prototypes *****************************************************************************/static int  ParseID3Tags ( vlc_object_t * );/***************************************************************************** * Module descriptor *****************************************************************************/vlc_module_begin();set_description( _("ID3 tag parser using libid3tag" ) );set_capability( "id3", 70 );set_callbacks( ParseID3Tags, NULL );vlc_module_end();/***************************************************************************** * Definitions of structures  and functions used by this plugins *****************************************************************************//***************************************************************************** * ParseID3Tag : parse an id3tag into the info structures *****************************************************************************/static void ParseID3Tag( input_thread_t *p_input, uint8_t *p_data, int i_size ){    playlist_t            *p_playlist;    struct id3_tag        *p_id3_tag;    struct id3_frame      *p_frame;    input_info_category_t *p_category;    char                  *psz_temp;    vlc_value_t val;    int i;    var_Get( p_input, "demuxed-id3", &val );    if( val.b_bool )    {        msg_Dbg( p_input, "the ID3 tag was already parsed" );        return;    }    p_playlist = vlc_object_find( p_input, VLC_OBJECT_PLAYLIST, FIND_PARENT );    val.b_bool = VLC_FALSE;    p_id3_tag = id3_tag_parse( p_data, i_size );    p_category = input_InfoCategory( p_input, "ID3" );    i = 0;    while ( ( p_frame = id3_tag_findframe( p_id3_tag , "T", i ) ) )    {        int i_strings;        playlist_item_t *p_item = playlist_ItemGetByPos( p_playlist, -1 );        if( !p_item )        {            msg_Err( p_input, "Unable to get item" );            return;        }        vlc_mutex_lock( &p_item->lock );        i_strings = id3_field_getnstrings( &p_frame->fields[1] );        while ( i_strings > 0 )        {            psz_temp = id3_ucs4_utf8duplicate( id3_field_getstrings( &p_frame->fields[1], --i_strings ) );            if ( !strcmp(p_frame->id, ID3_FRAME_GENRE ) )            {                int i_genre;                char *psz_endptr;                i_genre = strtol( psz_temp, &psz_endptr, 10 );                if( psz_temp != psz_endptr && i_genre >= 0 && i_genre < NUM_GENRES )                {                    input_AddInfo( p_category, (char *)p_frame->description,                                   ppsz_genres[atoi(psz_temp)]);                    playlist_ItemAddInfo( p_item, "ID3",                                    (char *)p_frame->description,                                    ppsz_genres[atoi(psz_temp)]);                }                else                {                    input_AddInfo( p_category, (char *)p_frame->description,                                                psz_temp );                    playlist_ItemAddInfo( p_item, "ID3",                                    (char *)p_frame->description,                                    psz_temp);                }            }            else if ( !strcmp(p_frame->id, ID3_FRAME_TITLE ) )            {                if( p_item )                {                    if( p_item->psz_name )                    {                        free( p_item->psz_name );                    }                    p_item->psz_name = strdup( psz_temp );;                    val.b_bool = VLC_TRUE;                }                input_AddInfo( p_category, (char *)p_frame->description,                                            psz_temp );                playlist_ItemAddInfo( p_item, "ID3",                                        (char *)p_frame->description,                                    psz_temp);            }            else if ( !strcmp(p_frame->id, ID3_FRAME_ARTIST ) )            {                if( p_item )                {                    playlist_ItemAddInfo( p_item,                                          _("General"), _("Author"), psz_temp);                    val.b_bool = VLC_TRUE;                }                input_AddInfo( p_category, (char *)p_frame->description,                                            psz_temp );                playlist_ItemAddInfo( p_item, "ID3",                                           (char *)p_frame->description,                                           psz_temp);            }            else            {                input_AddInfo( p_category, (char *)p_frame->description,                                            psz_temp );                playlist_ItemAddInfo( p_item, "ID3",                                           (char *)p_frame->description,                                           psz_temp);            }            free( psz_temp );        }        i++;        vlc_mutex_unlock( &p_item->lock );    }    id3_tag_delete( p_id3_tag );    if(val.b_bool == VLC_TRUE )    {        if( p_playlist )        {            val.b_bool = p_playlist->i_index;            var_Set( p_playlist, "item-change", val );        }    }    val.b_bool = VLC_TRUE;    var_Change( p_input, "demuxed-id3", VLC_VAR_SETVALUE, &val, NULL );    if( p_playlist )    {        vlc_object_release( p_playlist );    }}/***************************************************************************** * ParseID3Tags: check if ID3 tags at common locations. Parse them and skip it * if it's at the start of the file ****************************************************************************/static int ParseID3Tags( vlc_object_t *p_this ){    input_thread_t *p_input;    uint8_t *p_peek;    int i_size;    int i_size2;    if ( p_this->i_object_type != VLC_OBJECT_INPUT )    {        return( VLC_EGENERIC );    }    p_input = (input_thread_t *)p_this;    msg_Dbg( p_input, "checking for ID3 tag" );    if ( p_input->stream.b_seekable &&         p_input->stream.i_method != INPUT_METHOD_NETWORK )    {        int64_t i_pos;        /*look for a ID3v1 tag at the end of the file*/        i_pos = stream_Size( p_input->s );        if ( i_pos >128 )        {            input_AccessReinit( p_input );            p_input->pf_seek( p_input, i_pos - 128 );            /* get 10 byte id3 header */            if( stream_Peek( p_input->s, &p_peek, 10 ) < 10 )            {                msg_Err( p_input, "cannot peek()" );                return( VLC_EGENERIC );            }            i_size2 = id3_tag_query( p_peek, 10 );            if ( i_size2 == 128 )            {                /* peek the entire tag */                if ( stream_Peek( p_input->s, &p_peek, i_size2 ) < i_size2 )                {                    msg_Err( p_input, "cannot peek()" );                    return( VLC_EGENERIC );                }                msg_Dbg( p_input, "found ID3v1 tag" );                ParseID3Tag( p_input, p_peek, i_size2 );            }            /* look for ID3v2.4 tag at end of file */            /* get 10 byte ID3 footer */            if( stream_Peek( p_input->s, &p_peek, 128 ) < 128 )            {                msg_Err( p_input, "cannot peek()" );                return( VLC_EGENERIC );            }            i_size2 = id3_tag_query( p_peek + 118, 10 );            if ( i_size2 < 0  && i_pos > -i_size2 )            {                                        /* id3v2.4 footer found */                input_AccessReinit( p_input );                p_input->pf_seek( p_input, i_pos + i_size2 );                /* peek the entire tag */                if ( stream_Peek( p_input->s, &p_peek, i_size2 ) < i_size2 )                {                    msg_Err( p_input, "cannot peek()" );                    return( VLC_EGENERIC );                }                msg_Dbg( p_input, "found ID3v2 tag at end of file" );                ParseID3Tag( p_input, p_peek, i_size2 );            }        }        input_AccessReinit( p_input );        p_input->pf_seek( p_input, 0 );    }    /* get 10 byte id3 header */    if( stream_Peek( p_input->s, &p_peek, 10 ) < 10 )    {        msg_Err( p_input, "cannot peek()" );        return( VLC_EGENERIC );    }    i_size = id3_tag_query( p_peek, 10 );    if ( i_size <= 0 )    {        return( VLC_SUCCESS );    }    /* Read the entire tag */    p_peek = malloc( i_size );    if( !p_peek || stream_Read( p_input->s, p_peek, i_size ) < i_size )    {        msg_Err( p_input, "cannot read ID3 tag" );        if( p_peek ) free( p_peek );        return( VLC_EGENERIC );    }    ParseID3Tag( p_input, p_peek, i_size );    msg_Dbg( p_input, "found ID3v2 tag" );    free( p_peek );    return( VLC_SUCCESS );}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?