📄 audioscrobbler.c
字号:
free( psz_url ); return VLC_SUCCESS;}/***************************************************************************** * Handshake : Init audioscrobbler connection *****************************************************************************/static int Handshake( intf_thread_t *p_this ){ char *psz_username, *psz_password; time_t timestamp; char psz_timestamp[21]; struct md5_s p_struct_md5; stream_t *p_stream; char *psz_handshake_url; uint8_t p_buffer[1024]; char *p_buffer_pos; int i_ret; char *psz_url; intf_thread_t *p_intf = ( intf_thread_t* ) p_this; intf_sys_t *p_sys = p_this->p_sys; psz_username = config_GetPsz( p_this, "lastfm-username" ); if( !psz_username ) return VLC_ENOMEM; psz_password = config_GetPsz( p_this, "lastfm-password" ); if( !psz_password ) { free( psz_username ); return VLC_ENOMEM; } /* username or password have not been setup */ if ( !*psz_username || !*psz_password ) { free( psz_username ); free( psz_password ); return VLC_ENOVAR; } time( ×tamp ); /* generates a md5 hash of the password */ InitMD5( &p_struct_md5 ); AddMD5( &p_struct_md5, ( uint8_t* ) psz_password, strlen( psz_password ) ); EndMD5( &p_struct_md5 ); free( psz_password ); char *psz_password_md5 = psz_md5_hash( &p_struct_md5 ); if( !psz_password_md5 ) { free( psz_username ); return VLC_ENOMEM; } snprintf( psz_timestamp, sizeof( psz_timestamp ), "%"PRIu64, (uint64_t)timestamp ); /* generates a md5 hash of : * - md5 hash of the password, plus * - timestamp in clear text */ InitMD5( &p_struct_md5 ); AddMD5( &p_struct_md5, ( uint8_t* ) psz_password_md5, 32 ); AddMD5( &p_struct_md5, ( uint8_t* ) psz_timestamp, strlen( psz_timestamp )); EndMD5( &p_struct_md5 ); free( psz_password_md5 ); char *psz_auth_token = psz_md5_hash( &p_struct_md5 ); if( !psz_auth_token ) { free( psz_username ); return VLC_ENOMEM; } strncpy( p_sys->psz_auth_token, psz_auth_token, 33 ); free( psz_auth_token ); if( !asprintf( &psz_handshake_url, "http://post.audioscrobbler.com/?hs=true&p=1.2&c=%s&v=%s&u=%s&t=%s&a=%s", CLIENT_NAME, CLIENT_VERSION, psz_username, psz_timestamp, p_sys->psz_auth_token ) ) { free( psz_username ); return VLC_ENOMEM; } free( psz_username ); /* send the http handshake request */ p_stream = stream_UrlNew( p_intf, psz_handshake_url ); free( psz_handshake_url ); if( !p_stream ) return VLC_EGENERIC; /* read answer */ i_ret = stream_Read( p_stream, p_buffer, 1023 ); if( i_ret == 0 ) { stream_Delete( p_stream ); return VLC_EGENERIC; } p_buffer[i_ret] = '\0'; stream_Delete( p_stream ); p_buffer_pos = strstr( ( char* ) p_buffer, "FAILED " ); if ( p_buffer_pos ) { /* handshake request failed, sorry */ msg_Err( p_this, "last.fm handshake failed: %s", p_buffer_pos + 7 ); return VLC_EGENERIC; } p_buffer_pos = strstr( ( char* ) p_buffer, "BADAUTH" ); if ( p_buffer_pos ) { /* authentication failed, bad username/password combination */ intf_UserFatal( p_this, false, _("last.fm: Authentication failed"), _("last.fm username or password is incorrect. " "Please verify your settings and relaunch VLC." ) ); return VLC_AUDIOSCROBBLER_EFATAL; } p_buffer_pos = strstr( ( char* ) p_buffer, "BANNED" ); if ( p_buffer_pos ) { /* oops, our version of vlc has been banned by last.fm servers */ msg_Err( p_intf, "This version of VLC has been banned by last.fm. " "You should upgrade VLC, or disable the last.fm plugin." ); return VLC_AUDIOSCROBBLER_EFATAL; } p_buffer_pos = strstr( ( char* ) p_buffer, "BADTIME" ); if ( p_buffer_pos ) { /* The system clock isn't good */ msg_Err( p_intf, "last.fm handshake failed because your clock is too " "much shifted. Please correct it, and relaunch VLC." ); return VLC_AUDIOSCROBBLER_EFATAL; } p_buffer_pos = strstr( ( char* ) p_buffer, "OK" ); if ( !p_buffer_pos ) goto proto; p_buffer_pos = strstr( p_buffer_pos, "\n" ); if( !p_buffer_pos || strlen( p_buffer_pos ) < 34 ) goto proto; p_buffer_pos++; /* we skip the '\n' */ /* save the session ID */ snprintf( p_sys->psz_auth_token, 33, "%s", p_buffer_pos ); p_buffer_pos = strstr( p_buffer_pos, "http://" ); if( !p_buffer_pos || strlen( p_buffer_pos ) == 7 ) goto proto; /* We need to read the nowplaying url */ p_buffer_pos += 7; /* we skip "http://" */#if 0 //NOT USED psz_url = strndup( p_buffer_pos, strcspn( p_buffer_pos, "\n" ) ); if( !psz_url ) goto oom; switch( ParseURL( psz_url, &p_sys->psz_nowp_host, &p_sys->psz_nowp_file, &p_sys->i_nowp_port ) ) { case VLC_ENOMEM: goto oom; case VLC_EGENERIC: goto proto; case VLC_SUCCESS: default: break; }#endif p_buffer_pos = strstr( p_buffer_pos, "http://" ); if( !p_buffer_pos || strlen( p_buffer_pos ) == 7 ) goto proto; /* We need to read the submission url */ p_buffer_pos += 7; /* we skip "http://" */ psz_url = strndup( p_buffer_pos, strcspn( p_buffer_pos, "\n" ) ); if( !psz_url ) goto oom; switch( ParseURL( psz_url, &p_sys->psz_submit_host, &p_sys->psz_submit_file, &p_sys->i_submit_port ) ) { case VLC_ENOMEM: goto oom; case VLC_EGENERIC: goto proto; case VLC_SUCCESS: default: break; } return VLC_SUCCESS;oom: return VLC_ENOMEM;proto: msg_Err( p_intf, "Handshake: can't recognize server protocol" ); return VLC_EGENERIC;}/***************************************************************************** * DeleteSong : Delete the char pointers in a song *****************************************************************************/static void DeleteSong( audioscrobbler_song_t* p_song ){ FREENULL( p_song->psz_a ); FREENULL( p_song->psz_b ); FREENULL( p_song->psz_t ); FREENULL( p_song->psz_m ); FREENULL( p_song->psz_n );}/***************************************************************************** * ReadMetaData : Read meta data when parsed by vlc *****************************************************************************/static int ReadMetaData( intf_thread_t *p_this ){ playlist_t *p_playlist; input_thread_t *p_input; input_item_t *p_item; intf_sys_t *p_sys = p_this->p_sys; p_playlist = pl_Yield( p_this ); PL_LOCK; p_input = p_playlist->p_input; if( !p_input ) { PL_UNLOCK; pl_Release( p_this ); return( VLC_SUCCESS ); } vlc_object_yield( p_input ); PL_UNLOCK; pl_Release( p_this ); p_item = input_GetItem( p_input ); if( !p_item ) return VLC_SUCCESS; char *psz_meta;#define ALLOC_ITEM_META( a, b ) \ psz_meta = input_item_Get##b( p_item ); \ if( psz_meta && *psz_meta ) \ { \ a = encode_URI_component( psz_meta ); \ if( !a ) \ { \ vlc_mutex_unlock( &p_sys->lock ); \ vlc_object_release( p_input ); \ free( psz_meta ); \ return VLC_ENOMEM; \ } \ } vlc_mutex_lock( &p_sys->lock ); p_sys->b_meta_read = true; ALLOC_ITEM_META( p_sys->p_current_song.psz_a, Artist ) else { vlc_mutex_unlock( &p_sys->lock ); msg_Dbg( p_this, "No artist.." ); vlc_object_release( p_input ); free( psz_meta ); return VLC_EGENERIC; } free( psz_meta ); ALLOC_ITEM_META( p_sys->p_current_song.psz_t, Title ) else { vlc_mutex_unlock( &p_sys->lock ); msg_Dbg( p_this, "No track name.." ); vlc_object_release( p_input ); free( p_sys->p_current_song.psz_a ); free( psz_meta ); return VLC_EGENERIC; } free( psz_meta ); /* Now we have read the mandatory meta data, so we can submit that info */ p_sys->b_submit = true; ALLOC_ITEM_META( p_sys->p_current_song.psz_b, Album ) else p_sys->p_current_song.psz_b = calloc( 1, 1 ); free( psz_meta ); ALLOC_ITEM_META( p_sys->p_current_song.psz_m, TrackID ) else p_sys->p_current_song.psz_m = calloc( 1, 1 ); free( psz_meta ); p_sys->p_current_song.i_l = input_item_GetDuration( p_item ) / 1000000; ALLOC_ITEM_META( p_sys->p_current_song.psz_n, TrackNum ) else p_sys->p_current_song.psz_n = calloc( 1, 1 ); free( psz_meta );#undef ALLOC_ITEM_META msg_Dbg( p_this, "Meta data registered" ); vlc_mutex_unlock( &p_sys->lock ); vlc_object_release( p_input ); return VLC_SUCCESS;}static void HandleInterval( mtime_t *next, unsigned int *i_interval ){ if( *i_interval == 0 ) { /* first interval is 1 minute */ *i_interval = 1; } else { /* else we double the previous interval, up to 120 minutes */ *i_interval <<= 1; if( *i_interval > 120 ) *i_interval = 120; } *next = mdate() + ( *i_interval * 1000000 * 60 );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -