src/input/input.c \
src/input/stream.c \
src/input/demux.c \
- src/input/input_ext-plugins.c \
+ src/input/subtitles.c \
+ src/input/input_ext-plugins.c \
src/input/input_ext-dec.c \
src/input/input_ext-intf.c \
src/input/input_dec.c \
SUPERCLASS = NSObject;
},
{
- ACTIONS = {deleteItems = id; playItem = id; selectAll = id; };
+ ACTIONS = {deleteItems = id; playItem = id; savePlaylist = id; selectAll = id; };
CLASS = VLCPlaylist;
LANGUAGE = ObjC;
OUTLETS = {
"o_ctx_menu" = id;
"o_mi_delete" = id;
"o_mi_play" = id;
+ "o_mi_save_playlist" = id;
"o_mi_selectall" = id;
"o_table_view" = id;
};
<key>IBEditorPositions</key>
<dict>
<key>29</key>
- <string>261 897 419 44 0 0 1280 1002 </string>
+ <string>431 891 419 44 0 0 1280 1002 </string>
<key>303</key>
<string>60 509 104 114 0 0 1280 1002 </string>
<key>909</key>
<array>
<integer>977</integer>
</array>
- <key>IBOpenObjects</key>
- <array>
- <integer>29</integer>
- </array>
<key>IBSystem Version</key>
<string>6L60</string>
</dict>
* ninput.h
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: ninput.h,v 1.11 2003/09/13 17:42:15 fenrir Exp $
+ * $Id: ninput.h,v 1.12 2003/09/22 03:40:06 hartman Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
/**
* @}
*/
+
+
+/**
+ * \defgroup subtitles Subtitles
+ * @{
+ */
+
+/* Subtitles */
+VLC_EXPORT( char **, subtitles_Detect, ( input_thread_t *, char* path, char *fname ) );
+
+/**
+ * @}
+ */
+
#endif
* sub.c
*****************************************************************************
* Copyright (C) 1999-2003 VideoLAN
- * $Id: sub.c,v 1.25 2003/08/26 19:43:51 hartman Exp $
+ * $Id: sub.c,v 1.26 2003/09/22 03:40:06 hartman Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
#define SUB_TYPE_LONGTEXT \
"One from \"microdvd\", \"subrip\", \"ssa1\", \"ssa2-4\", \"vplayer\" " \
"\"sami\" (nothing for autodetection, it should always work)."
-#define SUB_AUTO_LONGTEXT \
- "Automatically detect a subtitle file, if no subtitle filename is" \
- "is specified"
vlc_module_begin();
set_description( _("Text subtitles demux") );
set_capability( "subtitle demux", 12 );
add_category_hint( "Subtitles", NULL, VLC_TRUE );
- add_file( "sub-file", NULL, NULL,
- "Subtitles file name", "Subtitles file name", VLC_TRUE );
- add_bool( "sub-autodetect-file", VLC_TRUE, NULL, "Autodetect subtitle filename",
- SUB_AUTO_LONGTEXT, VLC_FALSE );
add_float( "sub-fps", 0.0, NULL,
"Frames per second",
SUB_FPS_LONGTEXT, VLC_TRUE );
p_sub->pf_close = sub_close;
/* Initialize the variables */
- var_Create( p_this, "sub-file", VLC_VAR_FILE | VLC_VAR_DOINHERIT );
- var_Create( p_this, "sub-autodetect-file", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
var_Create( p_this, "sub-fps", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT );
var_Create( p_this, "sub-delay", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
var_Create( p_this, "sub-type", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
{ NULL, SUB_TYPE_UNKNOWN, "Unknow", NULL }
};
-/*****************************************************************************
- * sub_detect: Use the original filename to find a subtitle file
- *****************************************************************************/
-char* sub_detect( subtitle_demux_t *p_sub, char *psz_filename)
-{
- DIR *p_dir_handle;
- struct dirent *p_dir_afile;
- char * ppsz_sub_exts[] = { "sub", "srt", "smi", "ssa", NULL};
- char *psz_result, *psz_basename, *psz_dir = NULL;
- char *psz_file_noext, *psz_extension;
- int i;
- size_t i_dirlen, i_baselen = 0;
-
- if( psz_filename && *psz_filename )
- {
-#ifdef WIN32
- psz_basename = strrchr( psz_filename , '\\' );
-#else
- psz_basename = strrchr( psz_filename , '/' );
-#endif
- if( psz_basename )
- {
- i_dirlen = ( 1 + psz_basename ) - psz_filename;
- psz_dir = (char*)malloc( i_dirlen + 1 );
-
- if( !psz_dir )
- {
- return "";
- }
- strncpy( psz_dir, psz_filename, i_dirlen );
- psz_dir[i_dirlen] = '\0';
- ++psz_basename;
- }
- else
- {
- psz_basename = psz_filename;
- }
-
- psz_extension = strrchr( psz_basename , '.' );
-
- if( psz_extension )
- {
- i_baselen = ( 1 + psz_extension ) - psz_basename;
-
- psz_file_noext = (char*)malloc( i_baselen + 1 );
- if( !psz_file_noext )
- {
- return "";
- }
- strncpy( psz_file_noext, psz_basename, i_baselen );
- psz_file_noext[i_baselen] = '\0';
- ++psz_extension;
- }
- else return "";
-
- p_dir_handle = opendir( psz_dir ? psz_dir : "" );
- if( p_dir_handle ) {
- while(( p_dir_afile = readdir( p_dir_handle ))) {
- char* psz_afile_ext = strrchr( p_dir_afile->d_name, '.' );
-
- if( psz_afile_ext )
- {
- int i_found = 0;
-
- ++psz_afile_ext;
- for (i = 0; ppsz_sub_exts[i]; i++) {
- if( strcmp( ppsz_sub_exts[i], psz_afile_ext ) == 0 ) {
- i_found = 1;
- break;
- }
- }
- if( i_found ) /* found a file with a subtitle extension */
- {
- if( strncmp( p_dir_afile->d_name, psz_file_noext, (strlen( p_dir_afile->d_name ) - strlen( psz_afile_ext) ) ) == 0 )
- {
- /* perfect match */
- msg_Dbg( p_sub, "autodetected subtitlefile: %s", strdup( p_dir_afile->d_name ) );
- if( psz_dir )
- {
- char *psz_append;
- psz_result = (char*)malloc( i_dirlen + strlen( p_dir_afile->d_name ) +1 );
- strncpy( psz_result, psz_dir, i_dirlen );
- psz_append = psz_result + i_dirlen;
- strncpy( psz_append, p_dir_afile->d_name, strlen( p_dir_afile->d_name ) );
- psz_result[i_dirlen + strlen( p_dir_afile->d_name )] = '\0';
- return psz_result;
- }
- else return strdup( p_dir_afile->d_name );
- }
- }
- }
- }
- closedir( p_dir_handle );
- }
- }
- return "";
-}
-
/*****************************************************************************
* sub_open: Open a subtitle file and add subtitle ES
*****************************************************************************/
p_sub->subtitle = NULL;
p_sub->p_input = p_input;
- if( !psz_name || !*psz_name)
+ if( !psz_name )
{
- var_Get( p_sub, "sub-file", &val );
- if( !val.psz_string || !*val.psz_string )
- {
- var_Get( p_sub, "sub-autodetect-file", &val );
- if( val.b_bool )
- {
- psz_name = strdup( sub_detect( p_sub, p_input->psz_source));
- if( !psz_name || !*psz_name ) return VLC_EGENERIC;
- }
- else
- {
- if( val.psz_string ) free( val.psz_string );
- return VLC_EGENERIC;
- }
- }
- else
- {
- psz_name = strdup( val.psz_string );
- if( val.psz_string ) free( val.psz_string );
- }
+ msg_Err( p_sub, "no subtitle file specified", psz_name );
+ free( psz_name );
+ return VLC_EGENERIC;
}
/* *** load the file *** */
* output.m: MacOS X Output Dialog
*****************************************************************************
* Copyright (C) 2002-2003 VideoLAN
- * $Id: output.m,v 1.14 2003/09/19 23:03:27 hartman Exp $
+ * $Id: output.m,v 1.15 2003/09/22 03:40:05 hartman Exp $
*
* Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
* Christophe Massiot <massiot@via.ecp.fr>
- (void)initStrings
{
- NSArray *o_muxers = [NSArray arrayWithObjects: @"MPEG TS", @"MPEG PS", @"MPEG1",
- @"AVI", @"Ogg", @"MPEG4", @"Quicktime", nil];
+ NSArray *o_muxers = [NSArray arrayWithObjects: @"MPEG TS", @"MPEG PS", @"MPEG 1",
+ @"Ogg", @"AVI", @"ASF", @"MPEG 4", @"Quicktime", nil];
NSArray *o_a_channels = [NSArray arrayWithObjects: @"1", @"2", @"4", @"6", nil];
NSArray *o_a_bitrates = [NSArray arrayWithObjects: @"96", @"128", @"192", @"256", @"512", nil];
NSArray *o_v_bitrates = [NSArray arrayWithObjects:
[o_stream_port_lbl setStringValue: _NS("Port")];
[o_stream_ttl_lbl setStringValue: _NS("TTL")];
[[o_stream_type itemAtIndex: 0] setTitle: _NS("HTTP")];
- [[o_stream_type itemAtIndex: 1] setTitle: _NS("UDP")];
- [[o_stream_type itemAtIndex: 2] setTitle: _NS("RTP")];
+ [[o_stream_type itemAtIndex: 1] setTitle: _NS("MMSH")];
+ [[o_stream_type itemAtIndex: 2] setTitle: _NS("UDP")];
+ [[o_stream_type itemAtIndex: 3] setTitle: _NS("RTP")];
[o_stream_type_lbl setStringValue: _NS("Type")];
[o_mux_lbl setStringValue: _NS("Encapsulation Method")];
[o_sap_chkbox setEnabled: NO];
[o_sap_name setEnabled: NO];
+ [[o_mux_selector itemAtIndex: 0] setEnabled: YES];
if( [o_mode isEqualToString: _NS("File")] )
{
[o_stream_ttl_stp setEnabled: NO];
[o_stream_type setEnabled: NO];
[o_mux_selector setEnabled: YES];
- [[o_mux_selector itemAtIndex: 1] setEnabled: YES];
- [[o_mux_selector itemAtIndex: 2] setEnabled: YES];
- [[o_mux_selector itemAtIndex: 3] setEnabled: YES];
- [[o_mux_selector itemAtIndex: 4] setEnabled: YES];
- [[o_mux_selector itemAtIndex: 5] setEnabled: YES];
- [[o_mux_selector itemAtIndex: 6] setEnabled: YES];
+ [[o_mux_selector itemAtIndex: 1] setEnabled: YES]; // MPEG PS
+ [[o_mux_selector itemAtIndex: 2] setEnabled: YES]; // MPEG 1
+ [[o_mux_selector itemAtIndex: 3] setEnabled: YES]; // Ogg
+ [[o_mux_selector itemAtIndex: 4] setEnabled: YES]; // AVI
+ [[o_mux_selector itemAtIndex: 5] setEnabled: YES]; // ASF
+ [[o_mux_selector itemAtIndex: 6] setEnabled: YES]; // MPEG 4
+ [[o_mux_selector itemAtIndex: 7] setEnabled: YES]; // QuickTime
}
else if( [o_mode isEqualToString: _NS("Stream")] )
{
[o_stream_ttl_stp setEnabled: NO];
[[o_mux_selector itemAtIndex: 1] setEnabled: YES];
[[o_mux_selector itemAtIndex: 2] setEnabled: YES];
- [[o_mux_selector itemAtIndex: 3] setEnabled: NO];
- [[o_mux_selector itemAtIndex: 4] setEnabled: YES];
+ [[o_mux_selector itemAtIndex: 3] setEnabled: YES];
+ [[o_mux_selector itemAtIndex: 4] setEnabled: NO];
[[o_mux_selector itemAtIndex: 5] setEnabled: NO];
[[o_mux_selector itemAtIndex: 6] setEnabled: NO];
+ [[o_mux_selector itemAtIndex: 7] setEnabled: NO];
+ }
+ else if( [o_mode isEqualToString: _NS("MMSH")] )
+ {
+ [o_stream_address setEnabled: YES];
+ [o_stream_ttl setEnabled: NO];
+ [o_stream_ttl_stp setEnabled: NO];
+ [[o_mux_selector itemAtIndex: 0] setEnabled: NO];
+ [[o_mux_selector itemAtIndex: 1] setEnabled: NO];
+ [[o_mux_selector itemAtIndex: 2] setEnabled: NO];
+ [[o_mux_selector itemAtIndex: 3] setEnabled: NO];
+ [[o_mux_selector itemAtIndex: 4] setEnabled: NO];
+ [[o_mux_selector itemAtIndex: 5] setEnabled: YES];
+ [[o_mux_selector itemAtIndex: 6] setEnabled: NO];
+ [[o_mux_selector itemAtIndex: 7] setEnabled: NO];
}
else if( [o_mode isEqualToString: _NS("UDP")] )
{
[[o_mux_selector itemAtIndex: 4] setEnabled: NO];
[[o_mux_selector itemAtIndex: 5] setEnabled: NO];
[[o_mux_selector itemAtIndex: 6] setEnabled: NO];
+ [[o_mux_selector itemAtIndex: 7] setEnabled: NO];
[o_sap_chkbox setEnabled: YES];
[o_sap_name setEnabled: YES];
}
[[o_mux_selector itemAtIndex: 4] setEnabled: NO];
[[o_mux_selector itemAtIndex: 5] setEnabled: NO];
[[o_mux_selector itemAtIndex: 6] setEnabled: NO];
+ [[o_mux_selector itemAtIndex: 7] setEnabled: NO];
}
}
if( ![[o_mux_selector selectedItem] isEnabled] )
if ( [o_mux isEqualToString: _NS("AVI")] ) o_mux_string = @"avi";
else if ( [o_mux isEqualToString: _NS("Ogg")] ) o_mux_string = @"ogg";
else if ( [o_mux isEqualToString: _NS("MPEG PS")] ) o_mux_string = @"ps";
- else if ( [o_mux isEqualToString: _NS("MPEG4")] ) o_mux_string = @"mp4";
- else if ( [o_mux isEqualToString: _NS("MPEG1")] ) o_mux_string = @"mpeg1";
+ else if ( [o_mux isEqualToString: _NS("MPEG 4")] ) o_mux_string = @"mp4";
+ else if ( [o_mux isEqualToString: _NS("MPEG 1")] ) o_mux_string = @"mpeg1";
else if ( [o_mux isEqualToString: _NS("Quicktime")] ) o_mux_string = @"mov";
+ else if ( [o_mux isEqualToString: _NS("ASF")] ) o_mux_string = @"asf";
else o_mux_string = @"ts";
if( [o_mode isEqualToString: _NS("File")] )
if ( [o_mode isEqualToString: _NS("HTTP")] )
o_mode = @"http";
+ else if ( [o_mode isEqualToString: _NS("MMSH")] )
+ {
+ if ( [o_mux isEqualToString: _NS("ASF")] ) o_mux_string = @"asfh";
+ o_mode = @"mmsh";
+ }
else if ( [o_mode isEqualToString: _NS("UDP")] )
{
o_mode = @"udp";
NSString *o_mux_string;
if ( [[o_mux_selector titleOfSelectedItem] isEqualToString: _NS("MPEG PS")] )
o_mux_string = @"vob";
- else if ( [[o_mux_selector titleOfSelectedItem] isEqualToString: _NS("MPEG1")] )
+ else if ( [[o_mux_selector titleOfSelectedItem] isEqualToString: _NS("MPEG 1")] )
o_mux_string = @"mpg";
else if ( [[o_mux_selector titleOfSelectedItem] isEqualToString: _NS("AVI")] )
o_mux_string = @"avi";
+ else if ( [[o_mux_selector titleOfSelectedItem] isEqualToString: _NS("ASF")] )
+ o_mux_string = @"asf";
else if ( [[o_mux_selector titleOfSelectedItem] isEqualToString: _NS("Ogg")] )
o_mux_string = @"ogm";
- else if ( [[o_mux_selector titleOfSelectedItem] isEqualToString: _NS("MPEG4")] )
+ else if ( [[o_mux_selector titleOfSelectedItem] isEqualToString: _NS("MPEG 4")] )
o_mux_string = @"mp4";
else if ( [[o_mux_selector titleOfSelectedItem] isEqualToString: _NS("Quicktime")] )
o_mux_string = @"mov";
* playlist.h: MacOS X interface plugin
*****************************************************************************
* Copyright (C) 2002-2003 VideoLAN
- * $Id: playlist.h,v 1.10 2003/07/27 23:05:41 hartman Exp $
+ * $Id: playlist.h,v 1.11 2003/09/22 03:40:05 hartman Exp $
*
* Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
* Derk-Jan Hartman <thedj@users.sourceforge.net>
IBOutlet id o_ctx_menu;
+ IBOutlet id o_mi_save_playlist;
IBOutlet id o_mi_play;
IBOutlet id o_mi_delete;
IBOutlet id o_mi_selectall;
- (NSMenu *)menuForEvent:(NSEvent *)o_event;
+- (IBAction)savePlaylist:(id)sender;
- (IBAction)playItem:(id)sender;
- (IBAction)deleteItems:(id)sender;
- (IBAction)selectAll:(id)sender;
* playlist.m: MacOS X interface plugin
*****************************************************************************
* Copyright (C) 2002-2003 VideoLAN
- * $Id: playlist.m,v 1.32 2003/09/20 13:46:00 hartman Exp $
+ * $Id: playlist.m,v 1.33 2003/09/22 03:40:05 hartman Exp $
*
* Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
* Derk-Jan Hartman <thedj@users.sourceforge.net>
[o_table_view registerForDraggedTypes:
[NSArray arrayWithObjects: NSFilenamesPboardType, nil]];
+ [o_mi_save_playlist setTitle: _NS("Save Playlist...")];
[o_mi_play setTitle: _NS("Play")];
[o_mi_delete setTitle: _NS("Delete")];
[o_mi_selectall setTitle: _NS("Select All")];
return( o_ctx_menu );
}
+- (IBAction)savePlaylist:(id)sender
+{
+ intf_thread_t * p_intf = [NSApp getIntf];
+ playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
+ FIND_ANYWHERE );
+
+ NSSavePanel *o_save_panel = [NSSavePanel savePanel];
+ NSString * o_name = [NSString stringWithFormat: @"%@.m3u", _NS("Untitled")];
+ [o_save_panel setTitle: _NS("Save Playlist")];
+ [o_save_panel setPrompt: _NS("Save")];
+
+ if( [o_save_panel runModalForDirectory: nil
+ file: o_name] == NSOKButton )
+ {
+ playlist_SaveFile( p_playlist, [[o_save_panel filename] fileSystemRepresentation] );
+ }
+
+}
+
- (IBAction)playItem:(id)sender
{
intf_thread_t * p_intf = [NSApp getIntf];
/*****************************************************************************
* input.c: input thread
- * Read an MPEG2 stream, demultiplex and parse it before sending it to
+ * Read a stream, demultiplex and parse it before sending it to
* decoders.
*****************************************************************************
* Copyright (C) 1998-2002 VideoLAN
- * $Id: input.c,v 1.242 2003/09/20 13:50:14 fenrir Exp $
+ * $Id: input.c,v 1.243 2003/09/22 03:40:06 hartman Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
var_Create( p_input, "audio", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
var_Create( p_input, "audio-channel", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT );
var_Create( p_input, "spu-channel", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT );
+ var_Create( p_input, "sub-file", VLC_VAR_FILE | VLC_VAR_DOINHERIT );
+ var_Create( p_input, "sub-autodetect-file", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
var_Create( p_input, "sout", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
var_Create( p_input, "sout-audio", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
i_microsecondperframe = (int64_t)( (double)1000000.0 / (double)f_fps );
}
- /* Now add subtitles (for now only one) */
- if( ( p_sub = subtitle_New( p_input, NULL, i_microsecondperframe ) ) )
+ /* Look for and add subtitle files */
+ var_Get( p_input, "sub-autodetect-file", &val );
+ if( val.b_bool )
{
- TAB_APPEND( p_input->p_sys->i_sub, p_input->p_sys->sub, p_sub );
-
- /* see if it should be selected */
- var_Get( p_sub, "sub-file", &val );
- if( val.psz_string && *val.psz_string )
+ char **tmp = subtitles_Detect( p_input, "", p_input->psz_source );
+ char **tmp2 = tmp;
+ while (*tmp2)
{
- subtitle_Select( p_sub );
+ if( ( p_sub = subtitle_New( p_input, strdup(*tmp2++), i_microsecondperframe ) ) )
+ {
+ TAB_APPEND( p_input->p_sys->i_sub, p_input->p_sys->sub, p_sub );
+ }
+ }
+ free(tmp);
+ }
+ else
+ {
+ var_Get( p_input, "sub-file", &val );
+ if( val.psz_string )
+ {
+ if( ( p_sub = subtitle_New( p_input, strdup(val.psz_string), i_microsecondperframe ) ) )
+ {
+ TAB_APPEND( p_input->p_sys->i_sub, p_input->p_sys->sub, p_sub );
+ }
+ free( val.psz_string );
}
}
}
return VLC_SUCCESS;
}
-
--- /dev/null
+/*****************************************************************************
+ * subtitles.c
+ *****************************************************************************
+ * Copyright (C) 2003 VideoLAN
+ * $Id: subtitles.c,v 1.1 2003/09/22 03:40:06 hartman Exp $
+ *
+ * Authors: Derk-Jan Hartman <hartman at videolan.org>
+ * This is adapted code from the GPL'ed MPlayer (http://mplayerhq.hu)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+ *****************************************************************************/
+
+#include <stdlib.h>
+#include <vlc/vlc.h>
+#include <vlc/input.h>
+
+#include "ninput.h"
+#include <dirent.h>
+#include <ctype.h>
+
+#if defined( WIN32 )
+ #define DIRECTORY_SEPARATOR '\\'
+#else
+ #define DIRECTORY_SEPARATOR '/'
+#endif
+
+#define MAX_SUBTITLE_FILES 128
+
+
+static void strcpy_trim( char *d, char *s )
+{
+ /* skip leading whitespace */
+ while( *s && !isalnum(*s) )
+ {
+ s++;
+ }
+ for(;;)
+ {
+ /* copy word */
+ while( *s && isalnum(*s) )
+ {
+ *d = tolower(*s);
+ s++; d++;
+ }
+ if (*s == 0) break;
+ /* trim excess whitespace */
+ while( *s && !isalnum(*s) )
+ {
+ s++;
+ }
+ if( *s == 0 ) break;
+ *d++ = ' ';
+ }
+ *d = 0;
+}
+
+static void strcpy_strip_ext( char *d, char *s )
+{
+ char *tmp = strrchr(s, '.');
+ if( !tmp ) {
+ strcpy(d, s);
+ return;
+ }
+ else
+ {
+ strncpy(d, s, tmp - s);
+ d[tmp - s] = 0;
+ }
+ while( *d )
+ {
+ *d = tolower(*d);
+ d++;
+ }
+}
+
+static void strcpy_get_ext( char *d, char *s )
+{
+ char *tmp = strrchr(s, '.');
+ if( !tmp )
+ {
+ strcpy(d, "");
+ return;
+ } else strcpy( d, tmp + 1 );
+}
+
+static int whiteonly( char *s )
+{
+ while ( *s )
+ {
+ if( isalnum( *s ) ) return 0;
+ s++;
+ }
+ return 1;
+}
+
+typedef struct _subfn
+{
+ int priority;
+ char *psz_fname;
+} subfn;
+
+static int compare_sub_priority( const void *a, const void *b )
+{
+ if (((subfn*)a)->priority > ((subfn*)b)->priority) {
+ return -1;
+ } else if (((subfn*)a)->priority < ((subfn*)b)->priority) {
+ return 1;
+ } else {
+ return strcoll(((subfn*)a)->psz_fname, ((subfn*)b)->psz_fname);
+ }
+}
+
+/*****************************************************************************
+ * subtitles_Detect: Use the original filename to find a subtitle files.
+ *****************************************************************************/
+char** subtitles_Detect( input_thread_t *p_input, char *psz_path, char *psz_fname )
+{
+ /* variables to be used for derivatives of psz_fname */
+ char *f_dir, *f_fname, *f_fname_noext, *f_fname_trim, *tmp;
+ /* variables to be used for derivatives FILE *f */
+ char *tmp_fname_noext, *tmp_fname_trim, *tmp_fname_ext, *tmpresult;
+
+ int len, i, j, i_sub_count, i_sub_match_fuzziness;
+ subfn *result; /* unsorted results */
+ char **result2; /* sorted results */
+
+ FILE *f;
+ DIR *d;
+ struct dirent *de;
+
+ char * sub_exts[] = { "utf", "utf8", "utf-8", "sub", "srt", "smi", "txt", "ssa", NULL};
+ /* extensions from unsupported types */
+ /* rt, aqt, jss, js, ass */
+
+ i_sub_count = 0;
+ len = ( strlen( psz_fname ) > 256 ? strlen( psz_fname ) : 256 ) +
+ ( strlen( psz_path ) > 256 ? strlen( psz_path ) : 256 ) + 2;
+
+ f_dir = (char*)malloc(len);
+ f_fname = (char*)malloc(len);
+ f_fname_noext = (char*)malloc(len);
+ f_fname_trim = (char*)malloc(len);
+
+ tmp_fname_noext = (char*)malloc(len);
+ tmp_fname_trim = (char*)malloc(len);
+ tmp_fname_ext = (char*)malloc(len);
+
+ tmpresult = (char*)malloc(len);
+
+ result = (subfn*)malloc( sizeof(subfn) * MAX_SUBTITLE_FILES );
+ memset( result, 0, sizeof(subfn) * MAX_SUBTITLE_FILES );
+
+ /* extract filename & dirname from psz_fname */
+ tmp = strrchr( psz_fname, DIRECTORY_SEPARATOR );
+ if( tmp )
+ {
+ int pos;
+ strcpy( f_fname, tmp + 1 );
+ pos = tmp - psz_fname;
+ strncpy( f_dir, psz_fname, pos + 1 );
+ f_dir[pos + 1] = 0;
+ }
+ else
+ {
+ strcpy( f_fname, psz_fname );
+ strcpy( f_dir, "" );
+ }
+
+ strcpy_strip_ext( f_fname_noext, f_fname );
+ strcpy_trim( f_fname_trim, f_fname_noext );
+
+ i_sub_match_fuzziness = 3;
+ /* 0 = nothing
+ * 1 = any subtitle file
+ * 2 = any sub file containing movie name
+ * 3 = sub file matching movie name exactly
+ * 4 = sub file matching movie name with additional chars
+ */
+ for( j = 0; j <= 1; j++)
+ {
+ d = opendir( j == 0 ? f_dir : psz_path );
+ if( d )
+ {
+ int b_found;
+ while( de = readdir( d ) )
+ {
+ /* retrieve various parts of the filename */
+ strcpy_strip_ext( tmp_fname_noext, de->d_name );
+ strcpy_get_ext( tmp_fname_ext, de->d_name );
+ strcpy_trim( tmp_fname_trim, tmp_fname_noext );
+
+ /* does it end with a subtitle extension? */
+ b_found = 0;
+ for( i = 0; sub_exts[i]; i++ )
+ {
+ if( strcmp(sub_exts[i], tmp_fname_ext ) == 0 )
+ {
+ b_found = 1;
+ msg_Dbg( p_input, "found subtitle: %s", de->d_name );
+ break;
+ }
+ }
+
+ /* we have a (likely) subtitle file */
+ if( b_found )
+ {
+ int i_prio = 0;
+ if( !i_prio && strcmp( tmp_fname_trim, f_fname_trim ) == 0 )
+ {
+ /* matches the movie name exactly */
+ i_prio = 4;
+ }
+ if( !i_prio && ( tmp = strstr( tmp_fname_trim, f_fname_trim ) ) )
+ {
+ /* contains the movie name */
+ tmp += strlen( f_fname_trim );
+ if( whiteonly( tmp ) )
+ {
+ /* chars in front of the movie name */
+ i_prio = 2;
+ }
+ else
+ {
+ /* chars after (and possibly in front of) the movie name */
+ i_prio = 3;
+ }
+ }
+ if( !i_prio )
+ {
+ /* doesn't contain the movie name */
+ if( j == 0 ) i_prio = 1;
+ }
+
+ if( i_prio >= i_sub_match_fuzziness )
+ {
+ sprintf( tmpresult, "%s%s", j == 0 ? f_dir : psz_path, de->d_name );
+ msg_Dbg( p_input, "autodetected subtitle: %s with priority %d", de->d_name, i_prio );
+ if( f = fopen( tmpresult, "rt" ) )
+ {
+ fclose( f );
+ result[i_sub_count].priority = i_prio;
+ result[i_sub_count].psz_fname = strdup( tmpresult );
+ i_sub_count++;
+ }
+ }
+
+ }
+ if( i_sub_count >= MAX_SUBTITLE_FILES ) break;
+ }
+ closedir( d );
+ }
+ }
+
+ free( f_dir );
+ free( f_fname );
+ free( f_fname_noext );
+ free( f_fname_trim );
+
+ free( tmp_fname_noext );
+ free( tmp_fname_trim );
+ free( tmp_fname_ext );
+
+ free( tmpresult );
+
+ qsort( result, i_sub_count, sizeof( subfn ), compare_sub_priority );
+
+ result2 = (char**)malloc( sizeof(char*) * ( i_sub_count + 1 ) );
+ memset( result2, 0, sizeof(char*) * ( i_sub_count + 1 ) );
+
+ for( i = 0; i < i_sub_count; i++ )
+ {
+ result2[i] = result[i].psz_fname;
+ }
+ result2[i_sub_count] = NULL;
+ free( result );
+ return result2;
+}
+
* libvlc.h: main libvlc header
*****************************************************************************
* Copyright (C) 1998-2002 VideoLAN
- * $Id: libvlc.h,v 1.86 2003/09/20 19:37:54 hartman Exp $
+ * $Id: libvlc.h,v 1.87 2003/09/22 03:40:06 hartman Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
"Give the stream number of the audio channel you want to use in a DVD " \
"(from 1 to n).")
-#define INPUT_SUBT_TEXT N_("Choose subtitles")
+#define INPUT_SUBT_TEXT N_("Choose subtitles track")
#define INPUT_SUBT_LONGTEXT N_( \
- "Give the stream number of the subtitle channel you want to use in a " \
- "DVD (from 1 to n).")
+ "Give the stream number of the subtitle channel you want to use " \
+ "(from 1 to n).")
+
+#define SUB_AUTO_TEXT N_("Autodetect subtitle files")
+#define SUB_AUTO_LONGTEXT \
+ "Automatically detect a subtitle file, if no subtitle filename is" \
+ "is specified."
+
+#define SUB_FILE_TEXT N_("Use subtitle file")
+#define SUB_FILE_LONGTEXT \
+ "Load this subtitle file. To be used when autodetect cannot detect " \
+ "your subtitlefile."
#define DVD_DEV_TEXT N_("DVD device")
#ifdef WIN32
INPUT_CHAN_TEXT, INPUT_CHAN_LONGTEXT, VLC_TRUE );
add_integer( "spu-channel", -1, NULL,
INPUT_SUBT_TEXT, INPUT_SUBT_LONGTEXT, VLC_TRUE );
+ add_bool( "sub-autodetect-file", VLC_TRUE, NULL,
+ SUB_AUTO_TEXT, SUB_AUTO_LONGTEXT, VLC_FALSE );
+ add_file( "sub-file", NULL, NULL,
+ SUB_FILE_TEXT, SUB_FILE_LONGTEXT, VLC_TRUE );
+
add_file( "dvd", DVD_DEVICE, NULL, DVD_DEV_TEXT, DVD_DEV_LONGTEXT, VLC_FALSE );
add_file( "vcd", VCD_DEVICE, NULL, VCD_DEV_TEXT, VCD_DEV_LONGTEXT, VLC_FALSE );