wizard.m 87.1 KB
Newer Older
1
/*****************************************************************************
2
 * wizard.m: MacOS X Streaming Wizard
3
 *****************************************************************************
4
 * Copyright (C) 2005-2008 the VideoLAN team
5 6
 * $Id$
 *
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
7
 * Authors: Felix Kühne <fkuehne@users.sf.net>
8 9 10 11 12
 *
 * 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.
13
 *
14 15 16 17 18 19 20
 * 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
Antoine Cellerier's avatar
Antoine Cellerier committed
21
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 23
 *****************************************************************************/

24

25
/*****************************************************************************
Felix Paul Kühne's avatar
Felix Paul Kühne committed
26
 * Note: this code is partially based upon ../wxwidgets/wizard.cpp and
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
27
 *         ../wxwidgets/streamdata.h; both written by Clément Stenac.
28
 *****************************************************************************/
29

30

31 32
/*****************************************************************************
 * Preamble
33
 *****************************************************************************/
34 35
#import "wizard.h"
#import "intf.h"
36
#import "playlist.h"
37
#import <vlc_interface.h>
38 39 40 41 42 43 44 45 46 47 48 49 50 51

/*****************************************************************************
 * VLCWizard implementation
 *****************************************************************************/

@implementation VLCWizard

static VLCWizard *_o_sharedInstance = nil;

+ (VLCWizard *)sharedInstance
{
    return _o_sharedInstance ? _o_sharedInstance : [[self alloc] init];
}

52
- (id)init
53 54 55 56 57 58
{
    if (_o_sharedInstance) {
        [self dealloc];
    } else {
        _o_sharedInstance = [super init];
    }
59

60 61 62
    return _o_sharedInstance;
}

63 64
- (void)dealloc
{
65 66 67 68 69
    [o_userSelections release];
    [o_videoCodecs release];
    [o_audioCodecs release];
    [o_encapFormats release];
    [super dealloc];
70 71
}

72 73 74 75
- (void)awakeFromNib
{
    /* some minor cleanup */
    [o_t2_tbl_plst setEnabled:NO];
76 77
    o_userSelections = [[NSMutableDictionary alloc] init];
    [o_btn_backward setEnabled:NO];
78

79
    /* add audio-bitrates for transcoding */
80
    NSArray * audioBitratesArray;
81
    audioBitratesArray = [NSArray arrayWithObjects: @"512", @"256", @"192", 
82
        @"128", @"64", @"32", @"16", nil ];
83 84 85
    [o_t4_pop_audioBitrate removeAllItems];
    [o_t4_pop_audioBitrate addItemsWithTitles: audioBitratesArray];
    [o_t4_pop_audioBitrate selectItemWithTitle: @"192"];
86

87
    /* add video-bitrates for transcoding */
88
    NSArray * videoBitratesArray;
89
    videoBitratesArray = [NSArray arrayWithObjects: @"3072", @"2048", @"1024", 
90
        @"768", @"512", @"256", @"192", @"128", @"64", @"32", @"16", nil ];
91 92 93
    [o_t4_pop_videoBitrate removeAllItems];
    [o_t4_pop_videoBitrate addItemsWithTitles: videoBitratesArray];
    [o_t4_pop_videoBitrate selectItemWithTitle: @"1024"];
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111

    /* fill 2 global arrays with arrays containing all codec-related information
     * - one array per codec named by its short name to define the encap-compability,
     *     cmd-names, real names, more info in the order: realName, shortName,
     *     moreInfo, encaps */
    NSArray * o_mp1v;
    NSArray * o_mp2v;
    NSArray * o_mp4v;
    NSArray * o_div1;
    NSArray * o_div2;
    NSArray * o_div3;
    NSArray * o_h263;
    NSArray * o_h264;
    NSArray * o_wmv1;
    NSArray * o_wmv2;
    NSArray * o_mjpg;
    NSArray * o_theo;
    NSArray * o_dummyVid;
112 113 114
    o_mp1v = [NSArray arrayWithObjects: @"MPEG-1 Video", @"mp1v", 
        _NS("MPEG-1 Video codec (usable with MPEG PS, MPEG TS, MPEG1, OGG " 
        "and RAW)"), @"MUX_PS", @"MUX_TS", @"MUX_MPEG", @"MUX_OGG", @"MUX_RAW",
115
        @"NO", @"NO", @"NO", @"NO", nil];
116 117 118
    o_mp2v = [NSArray arrayWithObjects: @"MPEG-2 Video", @"mp2v",
        _NS("MPEG-2 Video codec (usable with MPEG PS, MPEG TS, MPEG1, OGG "
        "and RAW)"), @"MUX_PS", @"MUX_TS", @"MUX_MPEG", @"MUX_OGG", @"MUX_RAW",
119
        @"NO", @"NO", @"NO", @"NO", nil];
120 121 122
    o_mp4v = [NSArray arrayWithObjects: @"MPEG-4 Video", @"mp4v",
        _NS("MPEG-4 Video codec (useable with MPEG PS, MPEG TS, MPEG1, ASF, "
        "MP4, OGG and RAW)"), @"MUX_PS", @"MUX_TS", @"MUX_MPEG", @"MUX_ASF",
123
        @"MUX_MP4", @"MUX_OGG", @"MUX_RAW", @"NO", @"NO", nil];
124 125 126
    o_div1 = [NSArray arrayWithObjects: @"DIVX 1", @"DIV1",
        _NS("DivX first version (useable with MPEG TS, MPEG1, ASF and OGG)"),
        @"MUX_TS", @"MUX_MPEG", @"MUX_ASF", @"MUX_OGG", @"NO", @"NO", @"NO",
127
        @"NO", @"NO", nil];
128 129 130
    o_div2 = [NSArray arrayWithObjects: @"DIVX 2", @"DIV2",
        _NS("DivX second version (useable with MPEG TS, MPEG1, ASF and OGG)"),
        @"MUX_TS", @"MUX_MPEG", @"MUX_ASF", @"MUX_OGG", @"NO", @"NO", @"NO",
131
        @"NO", @"NO", nil];
132 133 134
    o_div3 = [NSArray arrayWithObjects: @"DIVX 3", @"DIV3",
        _NS("DivX third version (useable with MPEG TS, MPEG1, ASF and OGG)"),
        @"MUX_TS", @"MUX_MPEG", @"MUX_ASF", @"MUX_OGG", @"NO", @"NO", @"NO",
135
        @"NO", @"NO", nil];
136 137 138
    o_h263 = [NSArray arrayWithObjects: @"H.263", @"h263",
        _NS("H263 is a video codec optimized for videoconference "
        "(low rates, useable with MPEG TS)"), @"MUX_TS", @"NO", @"NO", @"NO",
139
        @"NO", @"NO", @"NO", @"NO", @"NO", nil];
140 141 142
    o_h264 = [NSArray arrayWithObjects: @"H.264", @"h264",
        _NS("H264 is a new video codec (useable with MPEG TS and MP4)"),
        @"MUX_TS", @"MUX_MP4", @"NO", @"NO", @"NO", @"NO", @"NO", @"NO",
143
        @"NO", nil];
144 145 146
    o_wmv1 = [NSArray arrayWithObjects: @"WMV 1", @"WMV1",
        _NS("WMV (Windows Media Video) 1 (useable with MPEG TS, MPEG1, ASF and "
        "OGG)"), @"MUX_TS", @"MUX_MPEG", @"MUX_ASF", @"MUX_OGG", @"NO", @"NO",
147
        @"NO", @"NO", @"NO", nil];
148 149 150
    o_wmv2 = [NSArray arrayWithObjects: @"WMV 2", @"WMV2",
        _NS("WMV (Windows Media Video) 2 (useable with MPEG TS, MPEG1, ASF and "
        "OGG)"), @"MUX_TS", @"MUX_MPEG", @"MUX_ASF", @"MUX_OGG", @"NO", @"NO",
151
        @"NO", @"NO", @"NO", nil];
152 153 154
    o_mjpg = [NSArray arrayWithObjects: @"MJPEG", @"MJPG",
        _NS("MJPEG consists of a series of JPEG pictures (useable with MPEG TS,"
        " MPEG1, ASF and OGG)"), @"MUX_TS", @"MUX_MPEG", @"MUX_ASF", @"MUX_OGG",
155
        @"NO", @"NO", @"NO", @"NO", @"NO", nil];
156 157 158
    o_theo = [NSArray arrayWithObjects: @"Theora", @"theo",
        _NS("Theora is a free general-purpose codec (useable with MPEG TS "
        "and OGG)"), @"MUX_TS", @"MUX_OGG", @"NO", @"NO", @"NO", @"NO", @"NO",
159
        @"NO", @"NO", nil];
160 161 162
    o_dummyVid = [NSArray arrayWithObjects: @"Dummy", @"dummy",
        _NS("Dummy codec (do not transcode, useable with all encapsulation "
        "formats)"), @"MUX_PS", @"MUX_TS", @"MUX_MPEG", @"MUX_ASF", @"MUX_MP4",
163
        @"MUX_OGG", @"MUX_WAV", @"MUX_RAW", @"MUX_MOV", nil];
164 165
    o_videoCodecs = [[NSArray alloc] initWithObjects: o_mp1v, o_mp2v, o_mp4v,
        o_div1, o_div2, o_div3, o_h263, o_h264, o_wmv1, o_wmv2, o_mjpg, o_theo,
166
        o_dummyVid, nil];
167
 
168

169 170 171 172 173 174 175 176 177 178
    NSArray * o_mpga;
    NSArray * o_mp3;
    NSArray * o_mp4a;
    NSArray * o_a52;
    NSArray * o_vorb;
    NSArray * o_flac;
    NSArray * o_spx;
    NSArray * o_s16l;
    NSArray * o_fl32;
    NSArray * o_dummyAud;
179 180 181
    o_mpga = [NSArray arrayWithObjects: @"MPEG Audio", @"mpga",
        _NS("The standard MPEG audio (1/2) format (useable with MPEG PS, MPEG TS, "
        "MPEG1, ASF, OGG and RAW)"), @"MUX_PS", @"MUX_TS", @"MUX_MPEG",
182
        @"MUX_ASF", @"MUX_OGG", @"MUX_RAW", @"-1", @"-1", @"-1", nil];
183 184 185
    o_mp3 = [NSArray arrayWithObjects: @"MP3", @"mp3",
        _NS("MPEG Audio Layer 3 (useable with MPEG PS, MPEG TS, MPEG1, ASF, OGG "
        "and RAW)"), @"MUX_PS", @"MUX_TS", @"MUX_MPEG", @"MUX_ASF", @"MUX_OGG",
186
        @"MUX_RAW", @"-1", @"-1", @"-1", nil];
187 188
    o_mp4a = [NSArray arrayWithObjects: @"MPEG 4 Audio", @"mp4a",
        _NS("Audio format for MPEG4 (useable with MPEG TS and MPEG4)"), @"MUX_TS",
189
        @"MUX_MP4", @"-1", @"-1", @"-1", @"-1", @"-1", @"-1", @"-1", nil];
190
    o_a52 = [NSArray arrayWithObjects: @"A/52", @"a52",
191 192
        _NS("DVD audio format (useable with MPEG PS, MPEG TS, MPEG1, ASF, OGG "
        "and RAW)"), @"MUX_PS", @"MUX_TS", @"MUX_MPEG", @"MUX_ASF", @"MUX_OGG",
193
        @"MUX_RAW", @"-1", @"-1", @"-1", nil];
194 195
    o_vorb = [NSArray arrayWithObjects: @"Vorbis", @"vorb",
        _NS("Vorbis is a free audio codec (useable with OGG)"), @"MUX_OGG",
196
        @"-1",  @"-1", @"-1", @"-1", @"-1", @"-1", @"-1", @"-1", nil];
197 198 199
    o_flac = [NSArray arrayWithObjects: @"FLAC", @"flac",
        _NS("FLAC is a lossless audio codec (useable with OGG and RAW)"),
        @"MUX_OGG", @"MUX_RAW", @"-1", @"-1", @"-1", @"-1", @"-1", @"-1",
200
        @"-1", nil];
201 202 203
    o_spx = [NSArray arrayWithObjects: @"Speex", @"spx",
        _NS("A free audio codec dedicated to compression of voice (useable "
        "with OGG)"), @"MUX_OGG", @"-1", @"-1", @"-1", @"-1", @"-1", @"-1",
204
        @"-1", @"-1", nil];
205 206
    o_s16l = [NSArray arrayWithObjects: @"Uncompressed, integer", @"s16l",
        _NS("Uncompressed audio samples (useable with WAV)"), @"MUX_WAV",
207
        @"-1", @"-1", @"-1", @"-1", @"-1", @"-1", @"-1", @"-1", nil];
208 209
    o_fl32 = [NSArray arrayWithObjects: @"Uncompressed, floating point", @"fl32",
        _NS("Uncompressed audio samples (useable with WAV)"), @"MUX_WAV",
210
        @"-1", @"-1", @"-1", @"-1", @"-1", @"-1", @"-1", @"-1", nil];
211 212 213
    o_dummyAud = [NSArray arrayWithObjects: @"Dummy", @"dummy",
        _NS("Dummy codec (do not transcode, useable with all encapsulation "
        "formats)"), @"MUX_PS", @"MUX_TS", @"MUX_MPEG", @"MUX_ASF", @"MUX_MP4",
214
        @"MUX_OGG", @"MUX_RAW", @"MUX_MOV", @"MUX_WAV", nil];
215
    o_audioCodecs = [[NSArray alloc] initWithObjects: o_mpga, o_mp3, o_mp4a,
216
        o_a52, o_vorb, o_flac, o_spx, o_s16l, o_fl32, o_dummyAud, nil];
217 218


219 220 221 222 223 224 225 226 227 228 229 230 231
    /* fill another global array with all information about the encap-formats
     * note that the order of the formats inside the g. array is the same as on
     * the encap-tab */
    NSArray * o_ps;
    NSArray * o_ts;
    NSArray * o_mpeg;
    NSArray * o_ogg;
    NSArray * o_raw;
    NSArray * o_asf;
    NSArray * o_avi;
    NSArray * o_mp4;
    NSArray * o_mov;
    NSArray * o_wav;
232
    NSArray * o_asfh;
233
    o_ps = [NSArray arrayWithObjects: @"ps", @"MPEG PS",
234
        _NS("MPEG Program Stream"), @"mpg", nil];
235
    o_ts = [NSArray arrayWithObjects: @"ts", @"MPEG TS",
236
        _NS("MPEG Transport Stream"), nil];
237
    o_mpeg = [NSArray arrayWithObjects: @"ps", @"MPEG 1",
238
        _NS("MPEG 1 Format"), @"mpg", nil];
239 240 241 242 243 244 245
    o_ogg = [NSArray arrayWithObjects: @"ogg", @"OGG", @"OGG", nil];
    o_raw = [NSArray arrayWithObjects: @"raw", @"RAW", @"RAW", nil];
    o_asf = [NSArray arrayWithObjects: @"asf", @"ASF", @"ASF", nil];
    o_avi = [NSArray arrayWithObjects: @"avi", @"AVI", @"AVI", nil];
    o_mp4 = [NSArray arrayWithObjects: @"mp4", @"MP4", @"MPEG4", nil];
    o_mov = [NSArray arrayWithObjects: @"mov", @"MOV", @"MOV", nil];
    o_wav = [NSArray arrayWithObjects: @"wav", @"WAV", @"WAV", nil];
246
    o_asfh = [NSArray arrayWithObjects: @"asfh", @"ASFH", @"ASFH", nil];
247
    o_encapFormats = [[NSArray alloc] initWithObjects: o_ps, o_ts, o_mpeg,
248
        o_ogg, o_raw, o_asf, o_avi, o_mp4, o_mov, o_wav, o_asfh, nil];
249

250 251
    /* yet another array on streaming methods including help texts */
    NSArray * o_http;
252
    NSArray * o_mms;
253 254
    NSArray * o_udp_uni;
    NSArray * o_udp_multi;
255 256
    NSArray * o_rtp_uni;
    NSArray * o_rtp_multi;
257 258 259 260 261
    o_http = [NSArray arrayWithObjects: @"http", @"HTTP", _NS("Enter the local "
        "addresses you want to listen requests on. Do not enter anything if "
        "you want to listen on all the network interfaces. This is generally "
        "the best thing to do. Other computers can then access the stream at "
        "http://yourip:8080 by default.") , _NS("Use this to stream to several "
262 263
        "computers. This method is not the most efficient, as the server needs "\
        "to send the stream several times, but generally the most compatible"), nil];
264 265 266 267 268 269 270 271
    o_mms = [NSArray arrayWithObjects: @"mmsh", @"MMS", _NS("Enter the local "
        "addresses you want to listen requests on. Do not enter anything if "
        "you want to listen on all the network interfaces. This is generally "
        "the best thing to do. Other computers can then access the stream at "
        "mms://yourip:8080 by default."), _NS("Use this to stream to several "
        "computers using the Microsoft MMS protocol. This protocol is used as "
        "transport method by many Microsoft's softwares. Note that only a "
        "small part of the MMS protocol is supported (MMS encapsulated in "
272
        "HTTP)." ), nil];
273 274
    o_udp_uni = [NSArray arrayWithObjects: @"udp", @"UDP-Unicast", _NS("Enter "
        "the address of the computer to stream to."), _NS("Use this to stream "
275
        "to a single computer."), nil];
276 277 278 279 280 281
    o_udp_multi = [NSArray arrayWithObjects: @"udp", @"UDP-Multicast", _NS("Enter "
        "the multicast address to stream to in this field. This must be an IP "
        "address between 224.0.0.0 and 239.255.255.255. For a private use, "
        "enter an address beginning with 239.255."), _NS("Use this to stream "
        "to a dynamic group of computers on a multicast-enabled network. This "
        "is the most efficient method to stream to several computers, but it "
282
        "won't work over the Internet."), nil];
283 284
    o_rtp_uni = [NSArray arrayWithObjects: @"rtp", @"RTP-Unicast", _NS("Enter the "
        "address of the computer to stream to.") , _NS("Use this to stream "
285
        "to a single computer. RTP headers will be added to the stream"), nil];
286 287 288 289 290 291
    o_rtp_multi = [NSArray arrayWithObjects: @"rtp", @"RTP-Multicast", _NS("Enter "
        "the multicast address to stream to in this field. This must be an IP "
        "address between 224.0.0.0 and 239.255.255.255. For a private use, "
        "enter an address beginning with 239.255."), _NS("Use this to stream "
        "to a dynamic group of computers on a multicast-enabled network. This "
        "is the most efficient method to stream to several computers, but it "
292
        "won't work over Internet. RTP headers will be added to the stream"), nil];
293
    o_strmgMthds = [[NSArray alloc] initWithObjects: o_http, o_mms,
294
        o_udp_uni, o_udp_multi, o_rtp_uni, o_rtp_multi, nil];
295 296 297 298 299 300 301 302 303 304
}

- (void)showWizard
{
    /* just present the window to the user */
    [o_wizard_window center];
    [o_wizard_window displayIfNeeded];
    [o_wizard_window makeKeyAndOrderFront:nil];
}

305 306
- (void)resetWizard
{
307
    /* go to the front page and clean up a bit */
308
    [o_userSelections removeAllObjects];
309 310
    [o_btn_forward setTitle: _NS("Next")];
    [o_tab_pageHolder selectFirstTabViewItem:self];
311 312
}

313 314 315
- (void)initStrings
{
    /* localise all strings to the users lang */
Felix Paul Kühne's avatar
Felix Paul Kühne committed
316
    /* method is called from intf.m (in method showWizard) */
317

318
    /* general items */
319
    [o_btn_backward setTitle: _NS("Back")];
320
    [o_btn_cancel setTitle: _NS("Cancel")];
321
    [o_btn_forward setTitle: _NS("Next")];
322
    [o_wizard_window setTitle: _NS("Streaming/Transcoding Wizard")];
323

324 325
    /* page one ("Hello") */
    [o_t1_txt_title setStringValue: _NS("Streaming/Transcoding Wizard")];
326
    [o_t1_txt_text setStringValue: _NS("This wizard allows to configure "
327
        "simple streaming or transcoding setups.")];
328 329
    [o_t1_btn_mrInfo_strmg setTitle: _NS("More Info")];
    [o_t1_btn_mrInfo_trnscd setTitle: _NS("More Info")];
330 331 332
    [o_t1_txt_notice setStringValue: _NS("This wizard only gives access to "
        "a small subset of VLC's streaming and transcoding capabilities. "
        "The Open and 'Saving/Streaming' dialogs will give access to more "
333
        "features.")];
334 335 336 337
    [[o_t1_matrix_strmgOrTrnscd cellAtRow:0 column:0] setTitle: 
        _NS("Stream to network")];
    [[o_t1_matrix_strmgOrTrnscd cellAtRow:1 column:0] setTitle: 
        _NS("Transcode/Save to file")];
338

339 340
    /* page two ("Input") */
    [o_t2_title setStringValue: _NS("Choose input")];
Felix Paul Kühne's avatar
OSX:  
Felix Paul Kühne committed
341
    [o_t2_text setStringValue: _NS("Choose here your input stream.")];
342
    [[o_t2_matrix_inputSourceType cellAtRow:0 column:0] setTitle:
343
        _NS("Select a stream")];
344
    [[o_t2_matrix_inputSourceType cellAtRow:1 column:0] setTitle:
345
        _NS("Existing playlist item")];
346
    [o_t2_btn_chooseFile setTitle: _NS("Choose...")];
347
    [[[o_t2_tbl_plst tableColumnWithIdentifier:@"name"] headerCell]
348
        setStringValue: _NS("Title")];
349
    [[[o_t2_tbl_plst tableColumnWithIdentifier:@"artist"] headerCell]
350
        setStringValue: _NS("Author")];
351 352
    [[[o_t2_tbl_plst tableColumnWithIdentifier:@"duration"] headerCell]
     setStringValue: _NS("Duration")];
353 354
    [o_t2_box_prtExtrct setTitle: _NS("Partial Extract")];
    [o_t2_ckb_enblPartExtrct setTitle: _NS("Enable")];
355 356 357
    [o_t2_ckb_enblPartExtrct setToolTip: _NS("This can be used to read only a "
        "part of the stream. It must be possible to control the incoming "
        "stream (for example, a file or a disc, but not an UDP network stream.) "
358
        "The starting and ending times can be given in seconds.")];
359 360
    [o_t2_txt_prtExtrctFrom setStringValue: _NS("From")];
    [o_t2_txt_prtExtrctTo setStringValue: _NS("To")];
361

362 363
    /* page three ("Streaming 1") */
    [o_t3_txt_title setStringValue: _NS("Streaming")];
364
    [o_t3_txt_text setStringValue: _NS("This page allows to select how "
365
        "the input stream will be sent.")];
366 367
    [o_t3_box_dest setTitle: _NS("Destination")];
    [o_t3_box_strmgMthd setTitle: _NS("Streaming method")];
368
    [o_t3_txt_destInfo setStringValue: _NS("Address of the computer "
369
        "to stream to.")];
370 371
    [[o_t3_matrix_stmgMhd cellAtRow:0 column:0] setTitle: _NS("UDP Unicast")];
    [[o_t3_matrix_stmgMhd cellAtRow:0 column:1] setTitle: _NS("UDP Multicast")];
372
    [o_t3_txt_strgMthdInfo setStringValue: _NS("Use this to stream to a single "
373
        "computer.")];
374

375 376
    /* page four ("Transcode 1") */
    [o_t4_title setStringValue: _NS("Transcode")];
377 378
    [o_t4_text setStringValue: _NS("This page allows to change the compression "
        "format of the audio or video tracks. To change only "
379
        "the container format, proceed to next page.")];
380 381 382 383 384 385
    [o_t4_box_audio setTitle: _NS("Audio")];
    [o_t4_box_video setTitle: _NS("Video")];
    [o_t4_ckb_audio setTitle: _NS("Transcode audio")];
    [o_t4_ckb_video setTitle: _NS("Transcode video")];
    [o_t4_txt_videoBitrate setStringValue: _NS("Bitrate (kb/s)")];
    [o_t4_txt_videoCodec setStringValue: _NS("Codec")];
386 387 388 389
    [o_t4_txt_hintAudio setStringValue: _NS("Enabling this allows to transcode "\
    "the audio track if one is present in the stream.")];
    [o_t4_txt_hintVideo setStringValue: _NS("Enabling this allows to transcode "\
    "the video track if one is present in the stream.")];
390

391 392
    /* page five ("Encap") */
    [o_t5_title setStringValue: _NS("Encapsulation format")];
393
    [o_t5_text setStringValue: _NS("This page allows to select how the "
394 395
        "stream will be encapsulated. Depending on previously chosen settings "
        "all formats won't be available.")];
396

397 398
    /* page six ("Streaming 2") */
    [o_t6_title setStringValue: _NS("Additional streaming options")];
399
    [o_t6_text setStringValue: _NS("In this page, a few "
400
                              "additional streaming parameters can be set.")];
401 402 403 404
    [o_t6_txt_ttl setStringValue: _NS("Time-To-Live (TTL)")];
    [o_t6_btn_mrInfo_ttl setTitle: _NS("More Info")];
    [o_t6_ckb_sap setTitle: _NS("SAP Announce")];
    [o_t6_btn_mrInfo_sap setTitle: _NS("More Info")];
Felix Paul Kühne's avatar
Felix Paul Kühne committed
405 406
    [o_t6_ckb_local setTitle: _NS("Local playback")];
    [o_t6_btn_mrInfo_local setTitle: _NS("More Info")];
407
    [o_t6_ckb_soverlay setTitle: _NS("Add Subtitles to transcoded video")];
408

409 410
    /* page seven ("Transcode 2") */
    [o_t7_title setStringValue: _NS("Additional transcode options")];
411
    [o_t7_text setStringValue: _NS("In this page, a few "
412
                              "additional transcoding parameters can be set.")];
413 414
    [o_t7_txt_saveFileTo setStringValue: _NS("Select the file to save to")];
    [o_t7_btn_chooseFile setTitle: _NS("Choose...")];
Felix Paul Kühne's avatar
Felix Paul Kühne committed
415
    [o_t7_ckb_local setTitle: _NS("Local playback")];
416
    [o_t7_ckb_soverlay setTitle: _NS("Add Subtitles to transcoded video")];
417 418 419
    [o_t7_ckb_soverlay setToolTip: _NS("Adds available subtitles directly to "
                                       "the video. These cannot be disabled "
                                       "by the receiving user as they become "
420
                                       "part of the image.")];
Felix Paul Kühne's avatar
Felix Paul Kühne committed
421
    [o_t7_btn_mrInfo_local setTitle: _NS("More Info")];
422

423
    /* page eight ("Summary") */
424
    [o_t8_txt_text setStringValue: _NS("This page lists all the settings. "
425
        "Click \"Finish\" to start streaming or transcoding.")];
Felix Paul Kühne's avatar
OSX:  
Felix Paul Kühne committed
426
    [o_t8_txt_title setStringValue: _NS("Summary")];
427
    [o_t8_txt_destination setStringValue: [_NS("Destination")
428
        stringByAppendingString: @":"]];
429
    [o_t8_txt_encapFormat setStringValue: [_NS("Encap. format")
430
        stringByAppendingString: @":"]];
431
    [o_t8_txt_inputStream setStringValue: [_NS("Input stream")
432
        stringByAppendingString: @":"]];
433
    [o_t8_txt_partExtract setStringValue: [_NS("Partial Extract")
434
        stringByAppendingString: @":"]];
435
    [o_t8_txt_sap setStringValue: [_NS("SAP Announce")
436
        stringByAppendingString: @":"]];
437
    [o_t8_txt_saveFileTo setStringValue: [_NS("Save file to")
438
        stringByAppendingString: @":"]];
439
    [o_t8_txt_strmgMthd setStringValue: [_NS("Streaming method")
440
        stringByAppendingString: @":"]];
441
    [o_t8_txt_trnscdAudio setStringValue: [_NS("Transcode audio")
442
        stringByAppendingString: @":"]];
443
    [o_t8_txt_trnscdVideo setStringValue: [_NS("Transcode video")
444
        stringByAppendingString: @":"]];
445
    [o_t8_txt_soverlay setStringValue: [_NS("Include subtitles")
446
        stringByAppendingString: @":"]];
447
    [o_t8_txt_local setStringValue: [_NS("Local playback")
448
        stringByAppendingString: @":"]];
449 450
}

451 452 453
- (void)initWithExtractValuesFrom: (NSString *)from 
                               to: (NSString *)to
                           ofItem: (NSString *)item
454 455
{
    [self resetWizard];
456
    msg_Dbg(VLCIntf, "wizard was reseted");
457 458 459 460 461 462 463 464 465
    [o_userSelections setObject:@"trnscd" forKey:@"trnscdOrStrmg"];
    [o_btn_backward setEnabled:YES];
    [o_tab_pageHolder selectTabViewItemAtIndex:1];
    [o_t2_fld_prtExtrctFrom setStringValue: from];
    [o_t2_fld_prtExtrctTo setStringValue: to];
    [o_t2_fld_pathToNewStrm setStringValue: item];
    [o_t1_matrix_strmgOrTrnscd selectCellAtRow:1 column:0];
    [[o_t1_matrix_strmgOrTrnscd cellAtRow:0 column:0] setState: NSOffState];
    [o_t2_ckb_enblPartExtrct setState: NSOnState];
466
    [self t2_enableExtract: nil];
467
    msg_Dbg(VLCIntf, "wizard interface is set");
468
 
469 470 471 472 473 474
    [o_wizard_window center];
    [o_wizard_window display];
    [o_wizard_window makeKeyAndOrderFront:nil];
    msg_Dbg(VLCIntf, "wizard window displayed");
}

475 476 477 478 479
- (IBAction)cancelRun:(id)sender
{
    [o_wizard_window close];
}

480 481 482 483 484
- (id)getPlaylistWizard
{
    return o_playlist_wizard;
}

485 486
- (IBAction)nextTab:(id)sender
{
487 488 489 490 491 492 493 494
    if ([[[o_tab_pageHolder selectedTabViewItem] label] isEqualToString: @"Hello"])
    {
        /* check whether the user wants to stream or just to transcode;
         * store information for later usage */
        NSString *o_mode;
        o_mode = [[o_t1_matrix_strmgOrTrnscd selectedCell] title];
        if( [o_mode isEqualToString: _NS("Stream to network")] )
        {
495
            /* we will be streaming */
496
            [o_userSelections setObject:@"strmg" forKey:@"trnscdOrStrmg"];
497 498 499
        }
        else
        {
500
            /* we will just do some transcoding */
501 502 503 504
            [o_userSelections setObject:@"trnscd" forKey:@"trnscdOrStrmg"];
        }
        [o_btn_backward setEnabled:YES];
        [o_tab_pageHolder selectTabViewItemAtIndex:1];
505 506 507 508

        /* Fill the playlist with current playlist items */
        [o_playlist_wizard reloadOutlineView];

509 510 511 512 513 514 515
    }
    else if ([[[o_tab_pageHolder selectedTabViewItem] label] isEqualToString: @"Input"])
    {
        /* check whether partialExtract is enabled and store the values, if needed */
        if ([o_t2_ckb_enblPartExtrct state] == NSOnState)
        {
            [o_userSelections setObject:@"YES" forKey:@"partExtract"];
516
            [o_userSelections setObject:[o_t2_fld_prtExtrctFrom stringValue]
517
                forKey:@"partExtractFrom"];
518
            [o_userSelections setObject:[o_t2_fld_prtExtrctTo stringValue]
519
                forKey:@"partExtractTo"];
520 521 522
        }else{
            [o_userSelections setObject:@"NO" forKey:@"partExtract"];
        }
523

524 525 526 527 528 529 530 531 532 533 534 535
        /* check whether we use an existing pl-item or add an new one;
         * store the path or the index and set a flag.
         * complain to the user if s/he didn't provide a path */
        NSString *o_mode;
        BOOL stop;
        stop = NO;
        o_mode = [[o_t2_matrix_inputSourceType selectedCell] title];
        if( [o_mode isEqualToString: _NS("Select a stream")] )
        {
            [o_userSelections setObject:@"YES" forKey:@"newStrm"];
            if ([[o_t2_fld_pathToNewStrm stringValue] isEqualToString: @""])
            {
536
                /* set a flag that no file is selected */
537
                stop = YES;
538 539 540
            }
            else
            {
541 542
                [o_userSelections setObject:[NSArray arrayWithObject:
                    [o_t2_fld_pathToNewStrm stringValue]] forKey:@"pathToStrm"];
543
            }
544 545 546
        }
        else
        {
547
            if ([o_t2_tbl_plst numberOfSelectedRows] > 0)
548
            {
549 550 551 552
                int x = 0;
                int y = [[o_t2_tbl_plst selectedRowIndexes] count];
                NSMutableArray * tempArray = [[NSMutableArray alloc] init];
                while( x != y )
553
                {
554
                    playlist_item_t *p_item =
555 556
                        [[o_t2_tbl_plst itemAtRow:
                            [[o_t2_tbl_plst selectedRowIndexes]
557 558 559 560
                            indexGreaterThanOrEqualToIndex: x]] pointerValue];

                    if( p_item->i_children <= 0 )
                    {
561
                        char *psz_uri = input_item_GetURI( p_item->p_input );
562
                        [tempArray addObject: [NSString stringWithUTF8String: psz_uri]];
563
                        free( psz_uri );
564 565 566 567 568
                        stop = NO;
                    }
                    else
                        stop = YES;
                    x += 1;
569
                }
570 571 572 573 574 575
                [o_userSelections setObject:[NSArray arrayWithArray: tempArray]
                    forKey:@"pathToStrm"];
                [tempArray release];
            }
            else
            {
576 577
                /* set a flag that no item is selected */
                stop = YES;
578 579
            }
        }
580

581 582 583
        /* show either "Streaming 1" or "Transcode 1" to the user */
        if (stop == NO)
        {
584
            if ([[o_userSelections objectForKey:@"trnscdOrStrmg"]
585
                isEqualToString:@"strmg"])
586 587 588 589 590
            {
                /* we are streaming */
                [o_tab_pageHolder selectTabViewItemAtIndex:2];
            }else{
                /* we are just transcoding */
591 592 593 594

                /* rebuild the menues for the codec-selections */
                [self rebuildCodecMenus];

595 596 597 598
                [o_tab_pageHolder selectTabViewItemAtIndex:3];
            }
        } else {
            /* show a sheet that the user didn't select a file */
599 600 601
            NSBeginInformationalAlertSheet(_NS("No input selected"),
                _NS("OK"), @"", @"", o_wizard_window, nil, nil, nil, nil,
                _NS("No new stream or valid playlist item has been selected.\n\n"
602
                "Choose one before going to the next page."));
603 604
        }
    }
605
    else if ([[[o_tab_pageHolder selectedTabViewItem] label] isEqualToString:
606
        @"Streaming 1"])
607
    {
608 609
        /* rebuild the menues for the codec-selections */
        [self rebuildCodecMenus];
610
 
611
        /* check which streaming method is selected and store it */
612 613 614
        int mode;
        mode = [[o_t3_matrix_stmgMhd selectedCell] tag];
        if( mode == 0 )
615
        {
616
            /* HTTP Streaming */
617
            [o_userSelections setObject:@"0" forKey:@"stmgMhd"];
618 619 620 621

            /* disable all codecs which don't support MPEG PS, MPEG TS, MPEG 1,
             * OGG, RAW or ASF */
            [o_t4_pop_audioCodec removeItemWithTitle:@"Uncompressed, integer"];
622
            [o_t4_pop_audioCodec removeItemWithTitle:@"Uncompressed, floating point"];
623
 
624
        } else if ( mode == 1 )
625
        {
626
            /* MMS Streaming */
627
            [o_userSelections setObject:@"1" forKey:@"stmgMhd"];
628
 
629 630 631 632 633 634
            /* disable all codecs which don't support ASF / ASFH */
            [o_t4_pop_audioCodec removeItemWithTitle:@"MPEG 4 Audio"];
            [o_t4_pop_audioCodec removeItemWithTitle:@"Vorbis"];
            [o_t4_pop_audioCodec removeItemWithTitle:@"FLAC"];
            [o_t4_pop_audioCodec removeItemWithTitle:@"Speex"];
            [o_t4_pop_audioCodec removeItemWithTitle:@"Uncompressed, integer"];
635
            [o_t4_pop_audioCodec removeItemWithTitle:@"Uncompressed, floating point"];
636
 
637 638 639 640 641 642
            [o_t4_pop_videoCodec removeItemWithTitle:@"MPEG-1 Video"];
            [o_t4_pop_videoCodec removeItemWithTitle:@"MPEG-2 Video"];
            [o_t4_pop_videoCodec removeItemWithTitle:@"H.263"];
            [o_t4_pop_videoCodec removeItemWithTitle:@"H.264"];
            [o_t4_pop_videoCodec removeItemWithTitle:@"MJPEG"];
            [o_t4_pop_videoCodec removeItemWithTitle:@"Theora"];
643
        } else {
644
            /* RTP/UDP Unicast/Multicast Streaming */
645
            [o_userSelections setObject: [[NSNumber numberWithInt: mode]
646
                stringValue] forKey:@"stmgMhd"];
647
 
648 649 650 651 652
            /* disable all codecs which don't support MPEG-TS */
            [o_t4_pop_audioCodec removeItemWithTitle:@"Vorbis"];
            [o_t4_pop_audioCodec removeItemWithTitle:@"FLAC"];
            [o_t4_pop_audioCodec removeItemWithTitle:@"Speex"];
            [o_t4_pop_audioCodec removeItemWithTitle:@"Uncompressed, integer"];
653
            [o_t4_pop_audioCodec removeItemWithTitle:@"Uncompressed, floating point"];
654
        }
655

656
        /* store the destination and check whether is it empty */
657
        if([[o_userSelections objectForKey:@"stmgMhd"] intValue] >=2 )
658
        {
659
           /* empty field is valid for HTTP and MMS */
660
            if( [[o_t3_fld_address stringValue] isEqualToString: @""] )
661
            {
662
                /* complain to the user that "" is no valid dest. */
663 664 665 666 667 668
                NSBeginInformationalAlertSheet(_NS("No valid destination"),
                    _NS("OK"), @"", @"", o_wizard_window, nil, nil, nil, nil,
                    _NS("A valid destination has to be selected "
                    "Enter either a Unicast-IP or a Multicast-IP."
                    "\n\nIf you don't know what this means, have a look at "
                    "the VLC Streaming HOWTO and the help texts in this "
669
                    "window."));
670
            } else {
Felix Paul Kühne's avatar
OSX:  
Felix Paul Kühne committed
671
                /* FIXME: check whether the entered IP is really valid */
672
                [o_userSelections setObject:[o_t3_fld_address stringValue]
673
                    forKey:@"stmgDest"];
674 675
                /* let's go to the transcode-1-tab */
                [o_tab_pageHolder selectTabViewItemAtIndex:3];
676 677
            }
        } else {
678
            [o_userSelections setObject:[o_t3_fld_address stringValue]
679
                forKey:@"stmgDest"];
680 681
            /* let's go to the transcode-1-tab */
            [o_tab_pageHolder selectTabViewItemAtIndex:3];
682 683
        }
    }
684
    else if ([[[o_tab_pageHolder selectedTabViewItem] label] isEqualToString:
685
        @"Transcode 1"])
686
    {
687
        /* check whether the user wants to transcode the video-track and store
688
         * the related options */
689 690 691 692 693
        if ([o_t4_ckb_video state] == NSOnState)
        {
            NSNumber * theNum;
            theNum = [NSNumber numberWithInt:[o_t4_pop_videoCodec indexOfSelectedItem]];
            [o_userSelections setObject:@"YES" forKey:@"trnscdVideo"];
694
            [o_userSelections setObject:[o_t4_pop_videoBitrate titleOfSelectedItem]
695
                forKey:@"trnscdVideoBitrate"];
696 697 698 699
            [o_userSelections setObject:theNum forKey:@"trnscdVideoCodec"];
        } else {
            [o_userSelections setObject:@"NO" forKey:@"trnscdVideo"];
        }
700

701
        /* check whether the user wants to transcode the audio-track and store
702
         * the related options */
703 704 705 706 707
        if ([o_t4_ckb_audio state] == NSOnState)
        {
            NSNumber * theNum;
            theNum = [NSNumber numberWithInt:[o_t4_pop_audioCodec indexOfSelectedItem]];
            [o_userSelections setObject:@"YES" forKey:@"trnscdAudio"];
708
            [o_userSelections setObject:[o_t4_pop_audioBitrate titleOfSelectedItem]
709
                forKey:@"trnscdAudioBitrate"];
710 711 712 713
            [o_userSelections setObject:theNum forKey:@"trnscdAudioCodec"];
        } else {
            [o_userSelections setObject:@"NO" forKey:@"trnscdAudio"];
        }
714

715 716 717
        /* store the currently selected item for further reference */
        int i_temp = [[o_t5_matrix_encap selectedCell] tag];

718 719 720 721 722 723 724 725 726 727 728
        /* disable all encap-formats */
        [[o_t5_matrix_encap cellAtRow:0 column:0] setEnabled:NO];
        [[o_t5_matrix_encap cellAtRow:1 column:0] setEnabled:NO];
        [[o_t5_matrix_encap cellAtRow:2 column:0] setEnabled:NO];
        [[o_t5_matrix_encap cellAtRow:3 column:0] setEnabled:NO];
        [[o_t5_matrix_encap cellAtRow:4 column:0] setEnabled:NO];
        [[o_t5_matrix_encap cellAtRow:5 column:0] setEnabled:NO];
        [[o_t5_matrix_encap cellAtRow:6 column:0] setEnabled:NO];
        [[o_t5_matrix_encap cellAtRow:7 column:0] setEnabled:NO];
        [[o_t5_matrix_encap cellAtRow:8 column:0] setEnabled:NO];
        [[o_t5_matrix_encap cellAtRow:9 column:0] setEnabled:NO];
729
        [[o_t5_matrix_encap cellAtRow:10 column:0] setEnabled:NO];
730

731 732 733
        /* re-enable the encap-formats supported by the chosen codecs */
        /* FIXME: the following is a really bad coding-style. feel free to mail
            me ideas how to make this nicer, if you want to -- FK, 7/11/05 */
734

735 736 737 738 739
        if ([[o_userSelections objectForKey:@"trnscdAudio"] isEqualTo: @"YES"])
        {
            if ([[o_userSelections objectForKey:@"trnscdVideo"] isEqualTo: @"YES"])
            {
                /* we are transcoding both audio and video, so we need to check both deps */
740
                if ([[o_videoCodecs objectAtIndex:[[o_userSelections objectForKey:
741
                    @"trnscdVideoCodec"] intValue]] containsObject: @"MUX_PS"])
742
                {
743 744
                    if ([[o_audioCodecs objectAtIndex:[[o_userSelections
                        objectForKey:@"trnscdAudioCodec"] intValue]]
745
                        containsObject: @"MUX_PS"])
746 747 748 749 750
                    {
                        [[o_t5_matrix_encap cellAtRow:0 column:0] setEnabled:YES];
                        [o_t5_matrix_encap selectCellAtRow:0 column:0];
                    }
                }
751
                if ([[o_videoCodecs objectAtIndex:[[o_userSelections
752
                    objectForKey:@"trnscdVideoCodec"] intValue]] containsObject: @"MUX_TS"])
753
                {
754
                    if ([[o_audioCodecs objectAtIndex:[[o_userSelections objectForKey:
755
                        @"trnscdAudioCodec"] intValue]] containsObject: @"MUX_TS"])
756 757 758 759 760
                    {
                        [[o_t5_matrix_encap cellAtRow:1 column:0] setEnabled:YES];
                        [o_t5_matrix_encap selectCellAtRow:1 column:0];
                    }
                }
761
                if ([[o_videoCodecs objectAtIndex:[[o_userSelections objectForKey:
762
                    @"trnscdVideoCodec"] intValue]] containsObject: @"MUX_MPEG"])
763
                {
764
                    if ([[o_audioCodecs objectAtIndex:[[o_userSelections objectForKey:
765
                        @"trnscdAudioCodec"] intValue]] containsObject: @"MUX_MPEG"])
766 767 768 769 770
                    {
                        [[o_t5_matrix_encap cellAtRow:2 column:0] setEnabled:YES];
                        [o_t5_matrix_encap selectCellAtRow:2 column:0];
                    }
                }
771
                if ([[o_videoCodecs objectAtIndex:[[o_userSelections objectForKey:
772
                    @"trnscdVideoCodec"] intValue]] containsObject: @"MUX_OGG"])
773
                {
774
                    if ([[o_audioCodecs objectAtIndex:[[o_userSelections
775
                        objectForKey:@"trnscdAudioCodec"] intValue]] containsObject: @"MUX_OGG"])
776 777 778 779 780
                    {
                        [[o_t5_matrix_encap cellAtRow:3 column:0] setEnabled:YES];
                        [o_t5_matrix_encap selectCellAtRow:3 column:0];
                    }
                }
781
                if ([[o_videoCodecs objectAtIndex:[[o_userSelections objectForKey:
782
                    @"trnscdVideoCodec"] intValue]] containsObject: @"MUX_RAW"])
783
                {
784
                    if ([[o_audioCodecs objectAtIndex:[[o_userSelections objectForKey:
785
                        @"trnscdAudioCodec"] intValue]] containsObject: @"MUX_RAW"])
786 787 788 789 790
                    {
                        [[o_t5_matrix_encap cellAtRow:4 column:0] setEnabled:YES];
                        [o_t5_matrix_encap selectCellAtRow:4 column:0];
                    }
                }
791
                if ([[o_videoCodecs objectAtIndex:[[o_userSelections objectForKey:
792
                    @"trnscdVideoCodec"] intValue]] containsObject: @"MUX_ASF"])
793
                {
794
                    if ([[o_audioCodecs objectAtIndex:[[o_userSelections objectForKey:
795
                        @"trnscdAudioCodec"] intValue]] containsObject: @"MUX_ASF"])
796 797 798 799 800
                    {
                        [[o_t5_matrix_encap cellAtRow:5 column:0] setEnabled:YES];
                        [o_t5_matrix_encap selectCellAtRow:5 column:0];
                    }
                }
801
                if ([[o_videoCodecs objectAtIndex:[[o_userSelections objectForKey:
802
                    @"trnscdVideoCodec"] intValue]] containsObject: @"MUX_AVI"])
803
                {
804
                    if ([[o_audioCodecs objectAtIndex:[[o_userSelections objectForKey:
805
                        @"trnscdAudioCodec"] intValue]] containsObject: @"MUX_AVI"])
806 807 808 809 810
                    {
                        [[o_t5_matrix_encap cellAtRow:6 column:0] setEnabled:YES];
                        [o_t5_matrix_encap selectCellAtRow:6 column:0];
                    }
                }
811
                if ([[o_videoCodecs objectAtIndex:[[o_userSelections objectForKey:
812
                    @"trnscdVideoCodec"] intValue]] containsObject: @"MUX_MP4"])
813
                {
814
                    if ([[o_audioCodecs objectAtIndex:[[o_userSelections objectForKey:
815
                        @"trnscdAudioCodec"] intValue]] containsObject: @"MUX_MP4"])
816 817 818 819 820
                    {
                        [[o_t5_matrix_encap cellAtRow:7 column:0] setEnabled:YES];
                        [o_t5_matrix_encap selectCellAtRow:7 column:0];
                    }
                }
821
                if ([[o_videoCodecs objectAtIndex:[[o_userSelections objectForKey:
822
                    @"trnscdVideoCodec"] intValue]] containsObject: @"MUX_MOV"