⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 audioscrobbler.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 3 页
字号:
                    "&t%%5B%d%%5D=%s"                    "&i%%5B%d%%5D=%u"                    "&o%%5B%d%%5D=P"                    "&r%%5B%d%%5D="                    "&l%%5B%d%%5D=%d"                    "&b%%5B%d%%5D=%s"                    "&n%%5B%d%%5D=%s"                    "&m%%5B%d%%5D=%s",                    i_song, p_song->psz_a,                    i_song, p_song->psz_t,                    i_song, (unsigned)p_song->date, /* HACK: %ju (uintmax_t) unsupported on Windows */                    i_song,                    i_song,                    i_song, p_song->i_l,                    i_song, p_song->psz_b,                    i_song, p_song->psz_n,                    i_song, p_song->psz_m            ) )            {   /* Out of memory */                vlc_mutex_unlock( &p_sys->lock );                return;            }            psz_submit_tmp = psz_submit;            if( !asprintf( &psz_submit, "%s%s",                    psz_submit_tmp, psz_submit_song ) )            {   /* Out of memory */                free( psz_submit_tmp );                free( psz_submit_song );                vlc_mutex_unlock( &p_sys->lock );                return;            }            free( psz_submit_song );            free( psz_submit_tmp );        }        vlc_mutex_unlock( &p_sys->lock );        i_post_socket = net_ConnectTCP( p_intf,            p_sys->psz_submit_host, p_sys->i_submit_port );        if ( i_post_socket == -1 )        {            /* If connection fails, we assume we must handshake again */            HandleInterval( &p_sys->next_exchange, &p_sys->i_interval );            p_sys->b_handshaked = false;            free( psz_submit );            continue;        }        /* we transmit the data */        i_net_ret = net_Printf(            VLC_OBJECT( p_intf ), i_post_socket, NULL,            POST_REQUEST, p_sys->psz_submit_file,            (unsigned)strlen( psz_submit ), p_sys->psz_submit_file,            VERSION, psz_submit        );        free( psz_submit );        if ( i_net_ret == -1 )        {            /* If connection fails, we assume we must handshake again */            HandleInterval( &p_sys->next_exchange, &p_sys->i_interval );            p_sys->b_handshaked = false;            continue;        }        i_net_ret = net_Read( p_intf, i_post_socket, NULL,                    p_buffer, 1023, false );        if ( i_net_ret <= 0 )        {            /* if we get no answer, something went wrong : try again */            continue;        }        net_Close( i_post_socket );        p_buffer[i_net_ret] = '\0';        p_buffer_pos = strstr( ( char * ) p_buffer, "FAILED" );        if ( p_buffer_pos )        {            msg_Warn( p_intf, "%s", p_buffer_pos );            HandleInterval( &p_sys->next_exchange, &p_sys->i_interval );            continue;        }        p_buffer_pos = strstr( ( char * ) p_buffer, "BADSESSION" );        if ( p_buffer_pos )        {            msg_Err( p_intf, "Authentication failed (BADSESSION), are you connected to last.fm with another program ?" );            p_sys->b_handshaked = false;            HandleInterval( &p_sys->next_exchange, &p_sys->i_interval );            continue;        }        p_buffer_pos = strstr( ( char * ) p_buffer, "OK" );        if ( p_buffer_pos )        {            int i;            for( i = 0; i < p_sys->i_songs; i++ )                DeleteSong( &p_sys->p_queue[i] );            p_sys->i_songs = 0;            p_sys->i_interval = 0;            p_sys->next_exchange = mdate();            msg_Dbg( p_intf, "Submission successful!" );        }        else        {            msg_Err( p_intf, "Authentication failed, handshaking again (%s)",                              p_buffer );            p_sys->b_handshaked = false;            HandleInterval( &p_sys->next_exchange, &p_sys->i_interval );            continue;        }    }}/***************************************************************************** * PlayingChange: Playing status change callback *****************************************************************************/static int PlayingChange( vlc_object_t *p_this, const char *psz_var,                       vlc_value_t oldval, vlc_value_t newval, void *p_data ){    intf_thread_t   *p_intf = ( intf_thread_t* ) p_data;    intf_sys_t      *p_sys  = p_intf->p_sys;    VLC_UNUSED( p_this ); VLC_UNUSED( psz_var );    if( p_intf->b_dead )        return VLC_SUCCESS;    if( p_sys->b_meta_read == false && newval.i_int >= PLAYING_S )    {        ReadMetaData( p_intf );        return VLC_SUCCESS;    }    if( newval.i_int >= END_S )        AddToQueue( p_intf );    else if( oldval.i_int == PLAYING_S && newval.i_int == PAUSE_S )        p_sys->time_pause = mdate();    else if( oldval.i_int == PAUSE_S && newval.i_int == PLAYING_S )        p_sys->time_total_pauses += ( mdate() - p_sys->time_pause );    return VLC_SUCCESS;}/***************************************************************************** * ItemChange: Playlist item change callback *****************************************************************************/static int ItemChange( vlc_object_t *p_this, const char *psz_var,                       vlc_value_t oldval, vlc_value_t newval, void *p_data ){    playlist_t          *p_playlist;    input_thread_t      *p_input;    intf_thread_t       *p_intf     = ( intf_thread_t* ) p_data;    intf_sys_t          *p_sys      = p_intf->p_sys;    input_item_t        *p_item;    vlc_value_t         video_val;    VLC_UNUSED( p_this ); VLC_UNUSED( psz_var );    VLC_UNUSED( oldval ); VLC_UNUSED( newval );    if( p_intf->b_dead )        return VLC_SUCCESS;    p_sys->b_state_cb       = false;    p_sys->b_meta_read      = false;    p_sys->b_submit         = false;    p_playlist = pl_Yield( p_intf );    PL_LOCK;    p_input = p_playlist->p_input;    if( !p_input || p_input->b_dead )    {        PL_UNLOCK;        pl_Release( p_intf );        return VLC_SUCCESS;    }    vlc_object_yield( p_input );    PL_UNLOCK;    pl_Release( p_intf );    p_item = input_GetItem( p_input );    if( !p_item )    {        vlc_object_release( p_input );        return VLC_SUCCESS;    }    var_Change( p_input, "video-es", VLC_VAR_CHOICESCOUNT, &video_val, NULL );    if( ( video_val.i_int > 0 ) || p_item->i_type == ITEM_TYPE_NET )    {        msg_Dbg( p_this, "Not an audio local file, not submitting");        vlc_object_release( p_input );        return VLC_SUCCESS;    }    p_sys->time_total_pauses = 0;    time( &p_sys->p_current_song.date );        /* to be sent to last.fm */    p_sys->p_current_song.i_start = mdate();    /* only used locally */    var_AddCallback( p_input, "state", PlayingChange, p_intf );    p_sys->b_state_cb = true;    if( input_item_IsPreparsed( p_item ) )        ReadMetaData( p_intf );    /* if the input item was not preparsed, we'll do it in PlayingChange()     * callback, when "state" == PLAYING_S */    vlc_object_release( p_input );    return VLC_SUCCESS;}/***************************************************************************** * AddToQueue: Add the played song to the queue to be submitted *****************************************************************************/static void AddToQueue ( intf_thread_t *p_this ){    mtime_t                     played_time;    intf_sys_t                  *p_sys = p_this->p_sys;    vlc_mutex_lock( &p_sys->lock );    if( !p_sys->b_submit )        goto end;    /* wait for the user to listen enough before submitting */    played_time = mdate() - p_sys->p_current_song.i_start -                            p_sys->time_total_pauses;    played_time /= 1000000; /* µs → s */    /*HACK: it seam that the preparsing sometime fail,            so use the playing time as the song length */    if( p_sys->p_current_song.i_l == 0 )        p_sys->p_current_song.i_l = played_time;    /* Don't send song shorter than 30s */    if( p_sys->p_current_song.i_l < 30 )    {        msg_Dbg( p_this, "Song too short (< 30s), not submitting" );        goto end;    }    /* Send if the user had listen more than 240s OR half the track length */    if( ( played_time < 240 ) &&        ( played_time < ( p_sys->p_current_song.i_l / 2 ) ) )    {        msg_Dbg( p_this, "Song not listened long enough, not submitting" );        goto end;    }    /* Check that all meta are present */    if( !p_sys->p_current_song.psz_a || !*p_sys->p_current_song.psz_a ||        !p_sys->p_current_song.psz_t || !*p_sys->p_current_song.psz_t )    {        msg_Dbg( p_this, "Missing artist or title, not submitting" );        goto end;    }    if( p_sys->i_songs >= QUEUE_MAX )    {        msg_Warn( p_this, "Submission queue is full, not submitting" );        goto end;    }    msg_Dbg( p_this, "Song will be submitted." );#define QUEUE_COPY( a ) \    p_sys->p_queue[p_sys->i_songs].a = p_sys->p_current_song.a#define QUEUE_COPY_NULL( a ) \    QUEUE_COPY( a ); \    p_sys->p_current_song.a = NULL    QUEUE_COPY( i_l );    QUEUE_COPY_NULL( psz_n );    QUEUE_COPY_NULL( psz_a );    QUEUE_COPY_NULL( psz_t );    QUEUE_COPY_NULL( psz_b );    QUEUE_COPY_NULL( psz_m );    QUEUE_COPY( date );#undef QUEUE_COPY_NULL#undef QUEUE_COPY    p_sys->i_songs++;    /* signal the main loop we have something to submit */    vlc_object_signal( VLC_OBJECT( p_this ) );end:    DeleteSong( &p_sys->p_current_song );    p_sys->b_submit = false;    vlc_mutex_unlock( &p_sys->lock );}/***************************************************************************** * ParseURL : Split an http:// URL into host, file, and port * * Example: "62.216.251.205:80/protocol_1.2" *      will be split into "62.216.251.205", 80, "protocol_1.2" * * psz_url will be freed before returning * *psz_file & *psz_host will be freed before use * * Return value: *  VLC_ENOMEM      Out Of Memory *  VLC_EGENERIC    Invalid url provided *  VLC_SUCCESS     Success *****************************************************************************/static int ParseURL( char *psz_url, char **psz_host, char **psz_file,                        int *i_port ){    int i_pos;    int i_len = strlen( psz_url );    FREENULL( *psz_host );    FREENULL( *psz_file );    i_pos = strcspn( psz_url, ":" );    if( i_pos == i_len )        return VLC_EGENERIC;    *psz_host = strndup( psz_url, i_pos );    if( !*psz_host )        return VLC_ENOMEM;    i_pos++; /* skip the ':' */    *i_port = atoi( psz_url + i_pos );    if( *i_port <= 0 )    {        FREENULL( *psz_host );        return VLC_EGENERIC;    }    i_pos = strcspn( psz_url, "/" );    if( i_pos == i_len )        return VLC_EGENERIC;    i_pos++; /* skip the '/' */    *psz_file = strdup( psz_url + i_pos );    if( !*psz_file )    {        FREENULL( *psz_host );        return VLC_ENOMEM;    }

⌨️ 快捷键说明

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