📄 rss.c
字号:
} } /* Misc init */ p_filter->pf_sub_filter = Filter; p_sys->last_date = (mtime_t)0; vlc_mutex_unlock( &p_sys->lock ); return VLC_SUCCESS;}/***************************************************************************** * DestroyFilter: destroy RSS video filter *****************************************************************************/static void DestroyFilter( vlc_object_t *p_this ){ filter_t *p_filter = (filter_t *)p_this; filter_sys_t *p_sys = p_filter->p_sys; vlc_mutex_lock( &p_sys->lock ); free( p_sys->p_style ); free( p_sys->psz_marquee ); free( p_sys->psz_urls ); FreeRSS( p_filter ); vlc_mutex_unlock( &p_sys->lock ); vlc_mutex_destroy( &p_sys->lock ); free( p_sys ); /* Delete the RSS variables */ var_Destroy( p_filter, CFG_PREFIX "urls" ); var_Destroy( p_filter, CFG_PREFIX "speed" ); var_Destroy( p_filter, CFG_PREFIX "length" ); var_Destroy( p_filter, CFG_PREFIX "ttl" ); var_Destroy( p_filter, CFG_PREFIX "images" ); var_Destroy( p_filter, CFG_PREFIX "x" ); var_Destroy( p_filter, CFG_PREFIX "y" ); var_Destroy( p_filter, CFG_PREFIX "position" ); var_Destroy( p_filter, CFG_PREFIX "color"); var_Destroy( p_filter, CFG_PREFIX "opacity"); var_Destroy( p_filter, CFG_PREFIX "size"); var_Destroy( p_filter, CFG_PREFIX "title" );}/**************************************************************************** * Filter: the whole thing **************************************************************************** * This function outputs subpictures at regular time intervals. ****************************************************************************/static subpicture_t *Filter( filter_t *p_filter, mtime_t date ){ filter_sys_t *p_sys = p_filter->p_sys; subpicture_t *p_spu; video_format_t fmt; subpicture_region_t *p_region; int i_feed, i_item; struct rss_feed_t *p_feed; memset( &fmt, 0, sizeof(video_format_t) ); vlc_mutex_lock( &p_sys->lock ); if( p_sys->last_date + ( p_sys->i_cur_char == 0 && p_sys->i_cur_item == ( p_sys->i_title == scroll_title ? -1 : 0 ) ? 5 : 1 ) /* ( ... ? 5 : 1 ) means "wait 5 times more for the 1st char" */ * p_sys->i_speed > date ) { vlc_mutex_unlock( &p_sys->lock ); return NULL; } /* Do we need to update the feeds ? */ if( p_sys->i_ttl && time( NULL ) > p_sys->t_last_update + (time_t)p_sys->i_ttl ) { msg_Dbg( p_filter, "Forcing update of all the RSS feeds" ); if( FetchRSS( p_filter ) ) { msg_Err( p_filter, "Failed while fetching RSS ... too bad" ); vlc_mutex_unlock( &p_sys->lock ); return NULL; /* FIXME : we most likely messed up all the data, * so we might need to do something about it */ } p_sys->t_last_update = time( NULL ); } p_sys->last_date = date; p_sys->i_cur_char++; if( p_sys->i_cur_item == -1 ? p_sys->p_feeds[p_sys->i_cur_feed].psz_title[p_sys->i_cur_char] == 0 : p_sys->p_feeds[p_sys->i_cur_feed].p_items[p_sys->i_cur_item].psz_title[p_sys->i_cur_char] == 0 ) { p_sys->i_cur_char = 0; p_sys->i_cur_item++; if( p_sys->i_cur_item >= p_sys->p_feeds[p_sys->i_cur_feed].i_items ) { if( p_sys->i_title == scroll_title ) p_sys->i_cur_item = -1; else p_sys->i_cur_item = 0; p_sys->i_cur_feed = (p_sys->i_cur_feed + 1)%p_sys->i_feeds; } } p_spu = filter_NewSubpicture( p_filter ); if( !p_spu ) { vlc_mutex_unlock( &p_sys->lock ); return NULL; } fmt.i_chroma = VLC_FOURCC('T','E','X','T'); p_spu->p_region = p_spu->pf_create_region( VLC_OBJECT(p_filter), &fmt ); if( !p_spu->p_region ) { p_filter->pf_sub_buffer_del( p_filter, p_spu ); vlc_mutex_unlock( &p_sys->lock ); return NULL; } /* Generate the string that will be displayed. This string is supposed to be p_sys->i_length characters long. */ i_item = p_sys->i_cur_item; i_feed = p_sys->i_cur_feed; p_feed = &p_sys->p_feeds[i_feed]; if( ( p_feed->p_pic && p_sys->i_title == default_title ) || p_sys->i_title == hide_title ) { /* Don't display the feed's title if we have an image */ snprintf( p_sys->psz_marquee, p_sys->i_length, "%s", p_sys->p_feeds[i_feed].p_items[i_item].psz_title +p_sys->i_cur_char ); } else if( ( !p_feed->p_pic && p_sys->i_title == default_title ) || p_sys->i_title == prepend_title ) { snprintf( p_sys->psz_marquee, p_sys->i_length, "%s : %s", p_sys->p_feeds[i_feed].psz_title, p_sys->p_feeds[i_feed].p_items[i_item].psz_title +p_sys->i_cur_char ); } else /* scrolling title */ { if( i_item == -1 ) snprintf( p_sys->psz_marquee, p_sys->i_length, "%s : %s", p_sys->p_feeds[i_feed].psz_title + p_sys->i_cur_char, p_sys->p_feeds[i_feed].p_items[i_item+1].psz_title ); else snprintf( p_sys->psz_marquee, p_sys->i_length, "%s", p_sys->p_feeds[i_feed].p_items[i_item].psz_title +p_sys->i_cur_char ); } while( strlen( p_sys->psz_marquee ) < (unsigned int)p_sys->i_length ) { i_item++; if( i_item == p_sys->p_feeds[i_feed].i_items ) break; snprintf( strchr( p_sys->psz_marquee, 0 ), p_sys->i_length - strlen( p_sys->psz_marquee ), " - %s", p_sys->p_feeds[i_feed].p_items[i_item].psz_title ); } /* Calls to snprintf might split multibyte UTF8 chars ... * which freetype doesn't like. */ { char *a = strdup( p_sys->psz_marquee ); char *a2 = a; char *b = p_sys->psz_marquee; EnsureUTF8( p_sys->psz_marquee ); /* we want to use ' ' instead of '?' for erroneous chars */ while( *b != '\0' ) { if( *b != *a ) *b = ' '; b++;a++; } free( a2 ); } p_spu->p_region->psz_text = strdup(p_sys->psz_marquee); if( p_sys->p_style->i_font_size > 0 ) p_spu->p_region->fmt.i_visible_height = p_sys->p_style->i_font_size; p_spu->i_start = date; p_spu->i_stop = 0; p_spu->b_ephemer = true; /* where to locate the string: */ if( p_sys->i_pos < 0 ) { /* set to an absolute xy */ p_spu->p_region->i_align = OSD_ALIGN_LEFT | OSD_ALIGN_TOP; p_spu->b_absolute = true; } else { /* set to one of the 9 relative locations */ p_spu->p_region->i_align = p_sys->i_pos; p_spu->b_absolute = false; } p_spu->i_x = p_sys->i_xoff; p_spu->i_y = p_sys->i_yoff; p_spu->i_height = 1; p_spu->p_region->p_style = p_sys->p_style; if( p_feed->p_pic ) { /* Display the feed's image */ picture_t *p_pic = p_feed->p_pic; video_format_t fmt_out; memset( &fmt_out, 0, sizeof(video_format_t) ); fmt_out.i_chroma = VLC_FOURCC('Y','U','V','A'); fmt_out.i_aspect = VOUT_ASPECT_FACTOR; fmt_out.i_sar_num = fmt_out.i_sar_den = 1; fmt_out.i_width = fmt_out.i_visible_width = p_pic->p[Y_PLANE].i_visible_pitch; fmt_out.i_height = fmt_out.i_visible_height = p_pic->p[Y_PLANE].i_visible_lines; p_region = p_spu->pf_create_region( VLC_OBJECT( p_filter ), &fmt_out ); if( !p_region ) { msg_Err( p_filter, "cannot allocate SPU region" ); } else { vout_CopyPicture( p_filter, &p_region->picture, p_pic ); p_spu->p_region->p_next = p_region; } /* Offset text to display right next to the image */ p_spu->p_region->i_x = p_pic->p[Y_PLANE].i_visible_pitch; } vlc_mutex_unlock( &p_sys->lock ); return p_spu;}/**************************************************************************** * RSS related functions **************************************************************************** * You should always lock the p_filter mutex before using any of these * functions ***************************************************************************/#undef LoadImage /* do not conflict with Win32 API *//**************************************************************************** * download and resize image located at psz_url ***************************************************************************/static picture_t *LoadImage( filter_t *p_filter, const char *psz_url ){ filter_sys_t *p_sys = p_filter->p_sys; video_format_t fmt_in; video_format_t fmt_out; picture_t *p_orig; picture_t *p_pic = NULL; image_handler_t *p_handler = image_HandlerCreate( p_filter ); memset( &fmt_in, 0, sizeof(video_format_t) ); memset( &fmt_out, 0, sizeof(video_format_t) ); fmt_out.i_chroma = VLC_FOURCC('Y','U','V','A'); p_orig = image_ReadUrl( p_handler, psz_url, &fmt_in, &fmt_out ); if( !p_orig ) { msg_Warn( p_filter, "Unable to read image %s", psz_url ); } else if( p_sys->p_style->i_font_size > 0 ) { fmt_in.i_chroma = VLC_FOURCC('Y','U','V','A'); fmt_in.i_height = p_orig->p[Y_PLANE].i_visible_lines; fmt_in.i_width = p_orig->p[Y_PLANE].i_visible_pitch; fmt_out.i_width = p_orig->p[Y_PLANE].i_visible_pitch *p_sys->p_style->i_font_size/p_orig->p[Y_PLANE].i_visible_lines; fmt_out.i_height = p_sys->p_style->i_font_size; p_pic = image_Convert( p_handler, p_orig, &fmt_in, &fmt_out ); picture_Release( p_orig ); if( !p_pic ) { msg_Warn( p_filter, "Error while converting %s", psz_url ); } } else { p_pic = p_orig; } image_HandlerDelete( p_handler ); return p_pic;}/**************************************************************************** * remove all ' ' '\t' '\n' '\r' characters from the begining and end of the * string. ***************************************************************************/static char *removeWhiteChars( char *psz_src ){ char *psz_src2 = strdup( psz_src ); char *psz_clean = strdup( psz_src2 ); char *psz_clean2; int i; while( ( *psz_clean == ' ' || *psz_clean == '\t' || *psz_clean == '\n' || *psz_clean == '\r' ) && *psz_clean != '\0' ) { psz_clean++; } i = strlen( psz_clean ); while( --i > 0 && ( psz_clean[i] == ' ' || psz_clean[i] == '\t' || psz_clean[i] == '\n' || psz_clean[i] == '\r' ) ); psz_clean[i+1] = '\0'; psz_clean2 = strdup( psz_clean ); free( psz_src2 ); return psz_clean2;}/**************************************************************************** * FetchRSS (or Atom) feeds ***************************************************************************/static int FetchRSS( filter_t *p_filter){ filter_sys_t *p_sys = p_filter->p_sys; stream_t *p_stream = NULL; xml_t *p_xml = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -