📄 intf.c
字号:
char *psz_uri_to_load; mtime_t i_seconds; vlc_value_t time; p_playlist = (playlist_t *) vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE ); if ( !p_playlist ) { msg_Warn( p_intf, "can't find playlist" ); return; } /* Get new URL */ p_current_item = p_playlist->pp_items[p_playlist->i_index];#ifdef CMML_INTF_DEBUG msg_Dbg( p_intf, "Current playlist item URL is \"%s\"", p_current_item->input.psz_uri );#endif psz_uri_to_load = XURL_Concat( p_current_item->input.psz_uri, psz_url );#ifdef CMML_INTF_DEBUG msg_Dbg( p_intf, "URL to load is \"%s\"", psz_uri_to_load );#endif if( var_Get( p_intf->p_sys->p_input, "time", &time ) ) { msg_Dbg( p_intf, "couldn't get time from current clip" ); time.i_time = 0; } i_seconds = time.i_time / 1000000;#ifdef CMML_INTF_DEBUG msg_Dbg( p_intf, "Current time is \"%lld\"", i_seconds );#endif /* TODO: we need a (much) more robust way of detecting whether * the file's a media file ... */ if( strstr( psz_uri_to_load, ".anx" ) != NULL ) { history_t *p_history = NULL; history_item_t *p_history_item = NULL; char *psz_timed_url; p_history = GetHistory( p_playlist ); /* create history item */ psz_timed_url = GetTimedURLFromPlaylistItem( p_intf, p_current_item ); p_history_item = historyItem_New( psz_timed_url, psz_timed_url ); free( psz_timed_url ); if( !p_history_item ) { msg_Warn( p_intf, "could not initialise history item" ); } else {#ifdef CMML_INTF_DEBUG msg_Dbg( p_intf, "history pre-index %d", p_history->i_index );#endif history_PruneAndInsert( p_history, p_history_item );#ifdef CMML_INTF_DEBUG msg_Dbg( p_intf, "new history item at %p, uri is \"%s\"", p_history_item, p_history_item->psz_uri ); msg_Dbg( p_intf, "history index now %d", p_history->i_index );#endif } /* free current-anchor-url */ free( psz_url ); val.p_address = NULL; if( var_Set( p_cmml_decoder, "psz-current-anchor-url", val ) != VLC_SUCCESS ) { msg_Dbg( p_intf, "couldn't reset psz-current-anchor-url" ); } ReplacePlaylistItem( p_playlist, psz_uri_to_load ); } else {#ifdef CMML_INTF_DEBUG msg_Dbg( p_intf, "calling browser_Open with \"%s\"", psz_url );#endif (void) browser_Open( psz_url ); playlist_Control( p_playlist, PLAYLIST_PAUSE, 0 ); } free( psz_uri_to_load ); vlc_object_release( p_playlist ); }}staticchar *GetTimedURLFromPlaylistItem( intf_thread_t *p_intf, playlist_item_t *p_current_item ){#ifdef CMML_INTF_USE_TIMED_URIS char *psz_url = NULL; char *psz_return_value = NULL; char *psz_seconds = NULL; int i_seconds; psz_url = XURL_GetWithoutFragment( p_current_item->input->psz_uri ); /* Get current time as a string */ if( XURL_IsFileURL( psz_url ) == VLC_TRUE ) psz_url = xstrcat( psz_url, "#" ); else psz_url = xstrcat( psz_url, "?" ); /* jump back to 2 seconds before where we are now */ i_seconds = GetCurrentTimeInSeconds( p_intf->p_sys->p_input ) - 2; psz_seconds = GetTimedURIFragmentForTime( i_seconds < 0 ? 0 : i_seconds ); if( psz_seconds ) { psz_url = xstrcat( psz_url, psz_seconds ); free( psz_seconds ); psz_return_value = psz_url; } return psz_return_value;#else void *p; /* Suppress warning messages about unused functions */ p = GetTimedURIFragmentForTime; /* unused */ p = GetCurrentTimeInSeconds; /* unused */ return strdup( p_current_item->input.psz_uri );#endif}/* * Get the current time, rounded down to the nearest second * * http://www.ietf.org/internet-drafts/draft-pfeiffer-temporal-fragments-02.txt */staticint GetCurrentTimeInSeconds( input_thread_t *p_input ){ vlc_value_t time; mtime_t i_seconds; var_Get( p_input, "time", &time ); i_seconds = time.i_time / 1000000; return i_seconds;}staticchar *GetTimedURIFragmentForTime( int seconds ){ char *psz_time; asprintf( &psz_time, "%d", seconds ); return psz_time;}staticint GoBackCallback( vlc_object_t *p_this, char const *psz_var, vlc_value_t oldval, vlc_value_t newval, void *p_data ){ intf_thread_t *p_intf = (intf_thread_t *) p_data; GoBack( p_intf ); return VLC_SUCCESS;}staticint GoForwardCallback( vlc_object_t *p_this, char const *psz_var, vlc_value_t oldval, vlc_value_t newval, void *p_data ){ intf_thread_t *p_intf = (intf_thread_t *) p_data; GoForward( p_intf ); return VLC_SUCCESS;}staticint FollowAnchorCallback( vlc_object_t *p_this, char const *psz_var, vlc_value_t oldval, vlc_value_t newval, void *p_data ){ intf_thread_t *p_intf = (intf_thread_t *) p_data; FollowAnchor( p_intf ); return VLC_SUCCESS;}staticvoid GoBack( intf_thread_t *p_intf ){ vlc_value_t history; history_t *p_history = NULL; history_item_t *p_history_item = NULL; history_item_t *p_new_history_item = NULL; playlist_t *p_playlist = NULL; char *psz_timed_url = NULL; playlist_item_t *p_current_item;#ifdef CMML_INTF_DEBUG msg_Dbg( p_intf, "Going back in navigation history" );#endif /* Find the playlist */ p_playlist = (playlist_t *) vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE ); if ( !p_playlist ) { msg_Warn( p_intf, "can't find playlist" ); return; } /* Retrieve navigation history from playlist */ if( var_Get( p_playlist, "navigation-history", &history ) != VLC_SUCCESS || !history.p_address ) { /* History doesn't exist yet: ignore user's request */ msg_Warn( p_intf, "can't go back: no history exists yet" ); vlc_object_release( p_playlist ); return; } p_history = history.p_address;#ifdef CMML_INTF_DEBUG msg_Dbg( p_intf, "back: nav history retrieved from %p", p_history ); msg_Dbg( p_intf, "nav history index:%d, p_xarray:%p", p_history->i_index, p_history->p_xarray );#endif /* Check whether we can go back in the history */ if( history_CanGoBack( p_history ) == VLC_FALSE ) { msg_Warn( p_intf, "can't go back: already at beginning of history" ); vlc_object_release( p_playlist ); return; } p_current_item = p_playlist->pp_items[p_playlist->i_index]; /* Save the currently-playing media in a new history item */ psz_timed_url = GetTimedURLFromPlaylistItem( p_intf, p_current_item ); p_new_history_item = historyItem_New( psz_timed_url, psz_timed_url ); free( psz_timed_url ); if( !p_new_history_item ) {#ifdef CMML_INTF_DEBUG msg_Dbg( p_intf, "back: could not initialise new history item" );#endif vlc_object_release( p_playlist ); return; } /* Go back in the history, saving the currently-playing item */ (void) history_GoBackSavingCurrentItem( p_history, p_new_history_item ); p_history_item = history_Item( p_history );#ifdef CMML_INTF_DEBUG msg_Dbg( p_intf, "retrieving item from h index %d", p_history->i_index ); msg_Dbg( p_intf, "got previous history item: %p", p_history_item ); msg_Dbg( p_intf, "prev history item URL: \"%s\"", p_history_item->psz_uri );#endif ReplacePlaylistItem( p_playlist, p_history_item->psz_uri ); vlc_object_release( p_playlist );}staticvoid GoForward( intf_thread_t *p_intf ){ vlc_value_t history; history_t *p_history = NULL; history_item_t *p_history_item = NULL; history_item_t *p_new_history_item = NULL; playlist_t *p_playlist = NULL; playlist_item_t *p_current_item;#ifdef CMML_INTF_DEBUG msg_Dbg( p_intf, "Going forward in navigation history" );#endif /* Find the playlist */ p_playlist = (playlist_t *) vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE ); if ( !p_playlist ) { msg_Warn( p_intf, "can't find playlist" ); return; } /* Retrieve navigation history from playlist */ if( var_Get( p_playlist, "navigation-history", &history ) != VLC_SUCCESS || !history.p_address ) { /* History doesn't exist yet: ignore user's request */ msg_Warn( p_intf, "can't go back: no history exists yet" ); vlc_object_release( p_playlist ); return; } p_history = history.p_address;#ifdef CMML_INTF_DEBUG msg_Dbg( p_intf, "forward: nav history retrieved from %p", p_history ); msg_Dbg( p_intf, "nav history index:%d, p_xarray:%p", p_history->i_index, p_history->p_xarray );#endif /* Check whether we can go forward in the history */ if( history_CanGoForward( p_history ) == VLC_FALSE ) { msg_Warn( p_intf, "can't go forward: already at end of history" ); vlc_object_release( p_playlist ); return; } /* Save the currently-playing media in a new history item */ p_new_history_item = malloc( sizeof(history_item_t) ); if( !p_new_history_item ) {#ifdef CMML_INTF_DEBUG msg_Dbg( p_intf, "forward: could not initialise new history item" );#endif vlc_object_release( p_playlist ); return; } p_current_item = p_playlist->pp_items[p_playlist->i_index]; p_new_history_item->psz_uri = GetTimedURLFromPlaylistItem( p_intf, p_current_item ); p_new_history_item->psz_name = p_new_history_item->psz_uri; /* Go forward in the history, saving the currently-playing item */ (void) history_GoForwardSavingCurrentItem( p_history, p_new_history_item ); p_history_item = history_Item( p_history );#ifdef CMML_INTF_DEBUG msg_Dbg( p_intf, "retrieving item from h index %d", p_history->i_index ); msg_Dbg( p_intf, "got next history item: %p", p_history_item ); msg_Dbg( p_intf, "next history item URL: \"%s\"", p_history_item->psz_uri );#endif ReplacePlaylistItem( p_playlist, p_history_item->psz_uri ); vlc_object_release( p_playlist );}static void ReplacePlaylistItem( playlist_t *p_playlist, char *psz_uri ){ playlist_Stop( p_playlist ); (void) playlist_Add( p_playlist, psz_uri, psz_uri, PLAYLIST_REPLACE, p_playlist->i_index ); playlist_Goto( p_playlist, p_playlist->i_index );}/**************************************************************************** * DisplayAnchor: displays an anchor on the given video output ****************************************************************************/static int DisplayAnchor( intf_thread_t *p_intf, vout_thread_t *p_vout, char *psz_anchor_description, char *psz_anchor_url ){ int i_margin_h, i_margin_v; mtime_t i_now; i_margin_h = 0; i_margin_v = 10; i_now = mdate(); if( p_vout ) { text_style_t *p_style = NULL; text_style_t blue_with_underline = default_text_style; blue_with_underline.b_underline = VLC_TRUE; blue_with_underline.i_color = 0x22ff22; if( psz_anchor_url ) { /* Should display subtitle underlined and in blue, but it looks * like VLC doesn't implement any text styles yet. D'oh! */ p_style = &blue_with_underline; } /* TODO: p_subpicture doesn't have the proper i_x and i_y * coordinates. Need to look at the subpicture display system to * work out why. */ if ( vout_ShowTextAbsolute( p_vout, DEFAULT_CHAN, psz_anchor_description, p_style, OSD_ALIGN_BOTTOM, i_margin_h, i_margin_v, i_now, 0 ) == VLC_SUCCESS ) { /* Displayed successfully */ } else { return VLC_EGENERIC; } } else { msg_Dbg( p_intf, "DisplayAnchor couldn't find a video output" ); return VLC_EGENERIC; } return VLC_SUCCESS;}static history_t * GetHistory( playlist_t *p_playlist ){ vlc_value_t val; history_t *p_history = NULL; if( var_Get( p_playlist, "navigation-history", &val ) != VLC_SUCCESS ) { /* history doesn't exist yet: need to create it */ history_t *new_history = history_New(); val.p_address = new_history; var_Create( p_playlist, "navigation-history", VLC_VAR_ADDRESS|VLC_VAR_DOINHERIT ); if( var_Set( p_playlist, "navigation-history", val ) != VLC_SUCCESS ) { msg_Warn( p_playlist, "could not initialise history" ); } else { p_history = new_history;#ifdef CMML_INTF_HISTORY_DEBUG msg_Dbg( p_playlist, "nav history created at %p", new_history ); msg_Dbg( p_playlist, "nav history index:%d, p_xarray:%p", p_history->i_index, p_history->p_xarray );#endif } } else { p_history = val.p_address;#ifdef CMML_INTF_HISTORY_DEBUG msg_Dbg( p_playlist, "nav history retrieved from %p", p_history );#endif } return p_history;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -