[vlc-devel] [PATCH] input: subtitles: Added support for detecting external subtitle files on network shares
Benjamin Adolphi
b.adolphi at gmail.com
Wed Mar 9 21:32:08 CET 2016
---
src/input/input.c | 95 +++++++++++++++++++++++++++------------------------
src/input/subtitles.c | 52 ++++++++++++++--------------
2 files changed, 78 insertions(+), 69 deletions(-)
diff --git a/src/input/input.c b/src/input/input.c
index 4a0caf4..a0ce7b9 100644
--- a/src/input/input.c
+++ b/src/input/input.c
@@ -102,8 +102,7 @@ enum {
SUB_CANFAIL = 0x02,
};
-static void input_SubtitleAdd( input_thread_t *, const char *, unsigned );
-static void input_SubtitleFileAdd( input_thread_t *, const char *, unsigned, bool );
+static void input_SubtitleAdd( input_thread_t *, const char *, unsigned, bool );
static void input_ChangeState( input_thread_t *p_input, int i_state ); /* TODO fix name */
#undef input_Create
@@ -953,7 +952,7 @@ static void LoadSubtitles( input_thread_t *p_input )
if( psz_subtitle != NULL )
{
msg_Dbg( p_input, "forced subtitle: %s", psz_subtitle );
- input_SubtitleFileAdd( p_input, psz_subtitle, i_flags, true );
+ input_SubtitleAdd( p_input, psz_subtitle, i_flags, true );
i_flags = SUB_NOFLAG;
}
@@ -969,7 +968,7 @@ static void LoadSubtitles( input_thread_t *p_input )
if( !psz_subtitle || strcmp( psz_subtitle, ppsz_subs[i] ) )
{
i_flags |= SUB_CANFAIL;
- input_SubtitleFileAdd( p_input, ppsz_subs[i], i_flags, false );
+ input_SubtitleAdd( p_input, ppsz_subs[i], i_flags, false );
i_flags = SUB_NOFLAG;
}
@@ -1007,7 +1006,7 @@ static void LoadSubtitles( input_thread_t *p_input )
{
var_SetString( p_input, "sub-description", a->psz_description ? a->psz_description : "");
- input_SubtitleAdd( p_input, psz_mrl, i_flags );
+ input_SubtitleAdd( p_input, psz_mrl, i_flags, false );
i_flags = SUB_NOFLAG;
free( psz_mrl );
@@ -1868,7 +1867,7 @@ static bool Control( input_thread_t *p_input,
case INPUT_CONTROL_ADD_SUBTITLE:
if( val.psz_string )
- input_SubtitleFileAdd( p_input, val.psz_string, SUB_FORCED, true );
+ input_SubtitleAdd( p_input, val.psz_string, SUB_FORCED, true );
break;
case INPUT_CONTROL_ADD_SLAVE:
@@ -2772,18 +2771,62 @@ static void MRLSections( const char *p,
*pi_chapter_end = chapter_end;
}
+static bool input_DoesFileExist( input_thread_t *p_input, const char *psz_url )
+{
+ stream_t *stream = stream_UrlNew( p_input, psz_url );
+
+ if( stream == NULL )
+ return false;
+
+ stream_Delete( stream );
+ return true;
+}
+
/*****************************************************************************
* input_AddSubtitles: add a subtitle file and enable it
*****************************************************************************/
static void input_SubtitleAdd( input_thread_t *p_input,
- const char *url, unsigned i_flags )
+ const char *psz_path, unsigned i_flags,
+ bool b_check_idx)
{
+ /* create a url in case we were given a local path */
+ char * psz_subtitle;
+ if( strstr( psz_path, "://" ) == NULL )
+ psz_subtitle = vlc_path2uri( psz_path, NULL );
+ else
+ psz_subtitle = strdup( psz_path );
+
+ /* if we are provided a subtitle.sub file,
+ * see if we don't have a subtitle.idx and use it instead */
+ char *psz_extension = b_check_idx ? strrchr( psz_subtitle, '.') : NULL;
+ if( psz_extension && strcmp( psz_extension, ".sub" ) == 0 )
+ {
+ char *psz_idxpath = strdup( psz_subtitle );
+ if( psz_idxpath )
+ {
+ psz_extension = psz_extension - psz_subtitle + psz_idxpath;
+ strcpy( psz_extension, ".idx" );
+
+ if( input_DoesFileExist( p_input, psz_idxpath ) )
+ {
+ msg_Dbg( p_input, "using %s as subtitle file instead of %s",
+ psz_idxpath, psz_subtitle );
+ free( psz_subtitle );
+ psz_subtitle = psz_idxpath;
+ }
+ else
+ free( psz_idxpath );
+ }
+ }
+
vlc_value_t count;
var_Change( p_input, "spu-es", VLC_VAR_CHOICESCOUNT, &count, NULL );
- input_source_t *sub = InputSourceNew( p_input, url, "subtitle",
+ input_source_t *sub = InputSourceNew( p_input, psz_subtitle, "subtitle",
(i_flags & SUB_CANFAIL) );
+
+ free( psz_subtitle );
if( sub == NULL )
return;
@@ -2811,42 +2854,6 @@ static void input_SubtitleAdd( input_thread_t *p_input,
var_FreeList( &list, NULL );
}
-static void input_SubtitleFileAdd( input_thread_t *p_input,
- const char *psz_subtitle, unsigned i_flags,
- bool b_check_idx )
-{
- /* if we are provided a subtitle.sub file,
- * see if we don't have a subtitle.idx and use it instead */
- char *psz_idxpath = NULL;
- char *psz_extension = b_check_idx ? strrchr( psz_subtitle, '.') : NULL;
- if( psz_extension && strcmp( psz_extension, ".sub" ) == 0 )
- {
- psz_idxpath = strdup( psz_subtitle );
- if( psz_idxpath )
- {
- struct stat st;
-
- psz_extension = psz_extension - psz_subtitle + psz_idxpath;
- strcpy( psz_extension, ".idx" );
-
- if( !vlc_stat( psz_idxpath, &st ) && S_ISREG( st.st_mode ) )
- {
- msg_Dbg( p_input, "using %s as subtitle file instead of %s",
- psz_idxpath, psz_subtitle );
- psz_subtitle = psz_idxpath;
- }
- }
- }
-
- char *url = vlc_path2uri( psz_subtitle, NULL );
- free( psz_idxpath );
- if( url == NULL )
- return;
-
- input_SubtitleAdd( p_input, url, i_flags );
- free( url );
-}
-
/*****************************************************************************
* Statistics
*****************************************************************************/
diff --git a/src/input/subtitles.c b/src/input/subtitles.c
index 23bf4f9..c8d0a00 100644
--- a/src/input/subtitles.c
+++ b/src/input/subtitles.c
@@ -238,12 +238,12 @@ static char **paths_to_list( const char *psz_dir, char *psz_path )
* \ingroup Demux
* \param p_this the calling \ref input_thread_t
* \param psz_path a list of subdirectories (separated by a ',') to look in.
- * \param psz_name the complete filename to base the search on.
+ * \param psz_url the complete url to base the search on.
* \return a NULL terminated array of filenames with detected possible subtitles.
* The array contains max MAX_SUBTITLE_FILES items and you need to free it after use.
*/
char **subtitles_Detect( input_thread_t *p_this, char *psz_path,
- const char *psz_name_org )
+ const char *psz_url )
{
int i_fuzzy = var_GetInteger( p_this, "sub-autodetect-fuzzy" );
if ( i_fuzzy == 0 )
@@ -256,30 +256,22 @@ char **subtitles_Detect( input_thread_t *p_this, char *psz_path,
vlc_subfn_t *result = NULL; /* unsorted results */
char **result2; /* sorted results */
- if( !psz_name_org )
- return NULL;
-
- char *psz_fname = vlc_uri2path( psz_name_org );
- if( !psz_fname )
+ if( !psz_url )
return NULL;
/* extract filename & dirname from psz_fname */
- char *f_dir = strdup( psz_fname );
+ char *f_dir = strdup( psz_url );
if( f_dir == NULL )
- {
- free( psz_fname );
return NULL;
- }
- const char *f_fname = strrchr( psz_fname, DIR_SEP_CHAR );
+ const char *f_fname = strrchr( psz_url, '/' );
if( !f_fname )
{
free( f_dir );
- free( psz_fname );
return NULL;
}
f_fname++; /* Skip the '/' */
- f_dir[f_fname - psz_fname] = 0; /* keep dir separator in f_dir */
+ f_dir[f_fname - psz_url] = 0; /* keep dir separator in f_dir */
i_fname_len = strlen( f_fname );
@@ -290,7 +282,6 @@ char **subtitles_Detect( input_thread_t *p_this, char *psz_path,
free( f_dir );
free( f_fname_noext );
free( f_fname_trim );
- free( psz_fname );
return NULL;
}
@@ -306,17 +297,28 @@ char **subtitles_Detect( input_thread_t *p_this, char *psz_path,
continue;
/* parse psz_src dir */
- DIR *dir = vlc_opendir( psz_dir );
- if( dir == NULL )
+ stream_t *stream = stream_UrlNew( p_this, psz_dir );
+ if(stream == NULL)
continue;
msg_Dbg( p_this, "looking for a subtitle file in %s", psz_dir );
- const char *psz_name;
- while( (psz_name = vlc_readdir( dir )) && i_sub_count < MAX_SUBTITLE_FILES )
+ input_item_t *item;
+ while( i_sub_count < MAX_SUBTITLE_FILES && (item = stream_ReadDir( stream )) != NULL )
{
+ const char *psz_name = strrchr( item->psz_uri, '/' );
+ if( !psz_name )
+ {
+ input_item_Release(item);
+ continue;
+ }
+ psz_name++; /* Skip the '/' */
+
if( psz_name[0] == '.' || !subtitles_Filter( psz_name ) )
+ {
+ input_item_Release( item );
continue;
+ }
char tmp_fname_noext[strlen( psz_name ) + 1];
char tmp_fname_trim[strlen( psz_name ) + 1];
@@ -357,15 +359,15 @@ char **subtitles_Detect( input_thread_t *p_this, char *psz_path,
}
if( i_prio >= i_fuzzy )
{
- struct stat st;
char *path;
if( asprintf( &path, "%s"DIR_SEP"%s", psz_dir, psz_name ) < 0 )
+ {
+ input_item_Release( item );
continue;
+ }
- if( strcmp( path, psz_fname )
- && vlc_stat( path, &st ) == 0
- && S_ISREG( st.st_mode ) && result )
+ if( strcmp( path, psz_url ) && item->i_type == ITEM_TYPE_FILE && result )
{
msg_Dbg( p_this,
"autodetected subtitle: %s with priority %d",
@@ -378,8 +380,9 @@ char **subtitles_Detect( input_thread_t *p_this, char *psz_path,
}
free( path );
}
+ input_item_Release( item );
}
- closedir( dir );
+ stream_Delete( stream );
}
if( subdirs )
{
@@ -390,7 +393,6 @@ char **subtitles_Detect( input_thread_t *p_this, char *psz_path,
free( f_dir );
free( f_fname_trim );
free( f_fname_noext );
- free( psz_fname );
if( !result )
return NULL;
--
2.7.2
More information about the vlc-devel
mailing list