macosx: split output from open panel
[vlc.git] / modules / gui / macosx / output.m
1 /*****************************************************************************
2  * output.m: MacOS X Output Dialog
3  *****************************************************************************
4  * Copyright (C) 2002-2015 VLC authors and VideoLAN
5  * $Id$
6  *
7  * Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
8  *          Christophe Massiot <massiot@via.ecp.fr>
9  *          Derk-Jan Hartman <thedj@users.sourceforge.net>
10  *          Benjamin Pracht <bigben AT videolan DOT org>
11  *          Felix Paul K├╝hne <fkuehne # videolan org>
12  *
13  * This program is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 2 of the License, or
16  * (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
26  *****************************************************************************/
27
28 #include "intf.h"
29 #include "output.h"
30
31 @interface VLCOutput()
32 {
33     NSString *_transcode;
34     NSArray *_soutMRL;
35 }
36 @end
37
38 @implementation VLCOutput
39
40 - (NSArray *)soutMRL
41 {
42     return _soutMRL;
43 }
44
45 - (void)awakeFromNib
46 {
47     NSArray *muxers = [NSArray arrayWithObjects:@"MPEG TS", @"MPEG PS", @"MPEG 1",
48                          @"Ogg", @"AVI", @"ASF", @"MPEG 4", @"Quicktime", @"Raw", nil];
49     NSArray *a_channels = [NSArray arrayWithObjects:@"1", @"2", @"4", @"6", nil];
50     NSArray *a_bitrates = [NSArray arrayWithObjects:@"16", @"32", @"64", @"96",
51                              @"128", @"192", @"256", @"512", nil];
52     NSArray *v_bitrates = [NSArray arrayWithObjects:@"16", @"32", @"64", @"96",
53                              @"128", @"192", @"256", @"384", @"512", @"768", @"1024", @"2048", @"3072", nil];
54     NSArray *v_scales = [NSArray arrayWithObjects:@"0.25", @"0.5", @"0.75", @"1", @"1.25", @"1.5", @"1.75", @"2", nil];
55     NSArray *a_codecs = [NSArray arrayWithObjects:@"mpga", @"mp3 ", @"mp4a", @"a52 ", @"vorb", @"flac", @"spx ", nil];
56     NSArray *v_codecs = [NSArray arrayWithObjects:@"mp1v", @"mp2v", @"mp4v", @"DIV1",
57                            @"DIV2", @"DIV3", @"h263", @"h264", @"WMV1", @"WMV2", @"MJPG", @"theo", nil];
58
59     [_okButton setTitle: _NS("OK")];
60     [_optionsBox setTitle: _NS("Streaming and Transcoding Options")];
61
62     [_displayOnLocalScreenCheckbox setTitle: _NS("Display the stream locally")];
63     [[_outputMethodMatrix cellAtRow:0 column:0] setTitle: _NS("File")];
64     [[_outputMethodMatrix cellAtRow:1 column:0] setTitle: _NS("Stream")];
65     [_dumpCheckbox setTitle: _NS("Dump raw input")];
66     [_browseButton setTitle: _NS("Browse...")];
67     [_streamAddressLabel setStringValue: _NS("Address")];
68     [_streamPortLabel setStringValue: _NS("Port")];
69     [_streamTTLLabel setStringValue: @"TTL"];
70     [[_streamTypePopup itemAtIndex: 0] setTitle: @"HTTP"];
71     [[_streamTypePopup itemAtIndex: 1] setTitle: @"MMSH"];
72     [[_streamTypePopup itemAtIndex: 2] setTitle: @"UDP"];
73     [[_streamTypePopup itemAtIndex: 3] setTitle: @"RTP"];
74     [_streamTypeLabel setStringValue: _NS("Type")];
75
76     [_muxLabel setStringValue: _NS("Encapsulation Method")];
77     [_muxSelectorPopup removeAllItems];
78     [_muxSelectorPopup addItemsWithTitles: muxers];
79
80     [_transcodeBox setTitle: _NS("Transcoding options")];
81     [_transcodeVideoCheckbox setTitle: _NS("Video")];
82     [_transcodeVideoSelectorPopup removeAllItems];
83     [_transcodeVideoSelectorPopup addItemsWithTitles: v_codecs];
84     [_transcodeVideoBitrateLabel setStringValue: _NS("Bitrate (kb/s)")];
85     [_transcodeVideoBitrateComboBox removeAllItems];
86     [_transcodeVideoBitrateComboBox addItemsWithObjectValues: v_bitrates];
87     [_transcodeVideoScaleLabel setStringValue: _NS("Scale")];
88     [_transcodeVideoScaleComboBox removeAllItems];
89     [_transcodeVideoScaleComboBox addItemsWithObjectValues: v_scales];
90     [_transcodeVideoScaleComboBox selectItemWithObjectValue: @"1"];
91     [_transcodeAudioCheckbox setTitle: _NS("Audio")];
92     [_transcodeAudioSelectorPopup removeAllItems];
93     [_transcodeAudioSelectorPopup addItemsWithTitles: a_codecs];
94     [_transcodeAudioBitrateLabel setStringValue: _NS("Bitrate (kb/s)")];
95     [_transcodeAudioBitrateComboBox removeAllItems];
96     [_transcodeAudioBitrateComboBox addItemsWithObjectValues: a_bitrates];
97     [_transcodeAudioChannelsLabel setStringValue: _NS("Channels")];
98     [_transcodeAudioChannelsComboBox removeAllItems];
99     [_transcodeAudioChannelsComboBox addItemsWithObjectValues: a_channels];
100
101     [_miscBox setTitle: _NS("Stream Announcing")];
102     [_sapCheckbox setTitle: _NS("SAP Announcement")];
103     [_rtspCheckbox setTitle: _NS("RTSP Announcement")];
104     [_httpCheckbox setTitle:_NS("HTTP Announcement")];
105     [_fileCheckbox setTitle:_NS("Export SDP as file")];
106
107     [_channelNameLabel setStringValue: _NS("Channel Name")];
108     [_sdpURLLabel setStringValue: _NS("SDP URL")];
109
110     [[NSNotificationCenter defaultCenter] addObserver: self
111         selector: @selector(outputInfoChanged:)
112         name: NSControlTextDidChangeNotification
113         object: _fileTextField];
114     [[NSNotificationCenter defaultCenter] addObserver: self
115         selector: @selector(outputInfoChanged:)
116         name: NSControlTextDidChangeNotification
117         object: _streamAddressTextField];
118     [[NSNotificationCenter defaultCenter] addObserver: self
119         selector: @selector(outputInfoChanged:)
120         name: NSControlTextDidChangeNotification
121         object: _streamPortTextField];
122     [[NSNotificationCenter defaultCenter] addObserver: self
123         selector: @selector(TTLChanged:)
124         name: NSControlTextDidChangeNotification
125         object: _streamTTLTextField];
126     [[NSNotificationCenter defaultCenter] addObserver: self
127         selector: @selector(transcodeInfoChanged:)
128         name: NSControlTextDidChangeNotification
129         object: _transcodeVideoBitrateComboBox];
130     [[NSNotificationCenter defaultCenter] addObserver: self
131         selector: @selector(transcodeInfoChanged:)
132         name: NSControlTextDidChangeNotification
133         object: _transcodeVideoScaleComboBox];
134     [[NSNotificationCenter defaultCenter] addObserver: self
135         selector: @selector(transcodeInfoChanged:)
136         name: NSControlTextDidChangeNotification
137         object: _transcodeAudioBitrateComboBox];
138     [[NSNotificationCenter defaultCenter] addObserver: self
139         selector: @selector(transcodeInfoChanged:)
140         name: NSControlTextDidChangeNotification
141         object: _transcodeAudioChannelsComboBox];
142     [[NSNotificationCenter defaultCenter] addObserver: self
143         selector: @selector(transcodeInfoChanged:)
144         name: NSControlTextDidChangeNotification
145         object: _channelNameTextField];
146     [[NSNotificationCenter defaultCenter] addObserver: self
147         selector: @selector(transcodeInfoChanged:)
148         name: NSControlTextDidChangeNotification
149         object: _sdpURLTextField];
150
151     [_muxSelectorPopup setAutoenablesItems: NO];
152     [self transcodeChanged:nil];
153 }
154
155 - (IBAction)outputCloseSheet:(id)sender
156 {
157     [self.outputSheet orderOut:sender];
158     [NSApp endSheet:self.outputSheet];
159 }
160
161 - (IBAction)outputMethodChanged:(id)sender
162 {
163     NSString *mode;
164     mode = [[self.outputMethodMatrix selectedCell] title];
165
166     [self.sapCheckbox setEnabled: NO];
167     [self.httpCheckbox setEnabled: NO];
168     [self.rtspCheckbox setEnabled: NO];
169     [self.fileCheckbox setEnabled: NO];
170     [self.channelNameTextField setEnabled: NO];
171     [self.sdpURLTextField setEnabled: NO];
172     [[self.muxSelectorPopup itemAtIndex: 0] setEnabled: YES];
173
174     if ([mode isEqualToString: _NS("File")]) {
175         [self.fileTextField setEnabled: YES];
176         [self.browseButton setEnabled: YES];
177         [self.dumpCheckbox setEnabled: YES];
178         [self.streamAddressTextField setEnabled: NO];
179         [self.streamPortTextField setEnabled: NO];
180         [self.streamTTLTextField setEnabled: NO];
181         [self.streamPortStepper setEnabled: NO];
182         [self.streamTTLStepper setEnabled: NO];
183         [self.streamTypePopup setEnabled: NO];
184         [self.muxSelectorPopup setEnabled: YES];
185         [[self.muxSelectorPopup itemAtIndex: 1] setEnabled: YES]; // MPEG PS
186         [[self.muxSelectorPopup itemAtIndex: 2] setEnabled: YES]; // MPEG 1
187         [[self.muxSelectorPopup itemAtIndex: 3] setEnabled: YES]; // Ogg
188         [[self.muxSelectorPopup itemAtIndex: 4] setEnabled: YES]; // AVI
189         [[self.muxSelectorPopup itemAtIndex: 5] setEnabled: YES]; // ASF
190         [[self.muxSelectorPopup itemAtIndex: 6] setEnabled: YES]; // MPEG 4
191         [[self.muxSelectorPopup itemAtIndex: 7] setEnabled: YES]; // QuickTime
192         [[self.muxSelectorPopup itemAtIndex: 8] setEnabled: YES]; // Raw
193     } else if ([mode isEqualToString: _NS("Stream")]) {
194         [self.fileTextField setEnabled: NO];
195         [self.dumpCheckbox setEnabled: NO];
196         [self.browseButton setEnabled: NO];
197         [self.streamPortTextField setEnabled: YES];
198         [self.streamPortStepper setEnabled: YES];
199         [self.streamTypePopup setEnabled: YES];
200         [self.muxSelectorPopup setEnabled: YES];
201
202         mode = [self.streamTypePopup titleOfSelectedItem];
203
204         if ([mode isEqualToString: @"HTTP"]) {
205             [self.streamAddressTextField setEnabled: YES];
206             [self.streamTTLTextField setEnabled: NO];
207             [self.streamTTLStepper setEnabled: NO];
208             [[self.muxSelectorPopup itemAtIndex: 1] setEnabled: YES];
209             [[self.muxSelectorPopup itemAtIndex: 2] setEnabled: YES];
210             [[self.muxSelectorPopup itemAtIndex: 3] setEnabled: YES];
211             [[self.muxSelectorPopup itemAtIndex: 4] setEnabled: NO];
212             [[self.muxSelectorPopup itemAtIndex: 5] setEnabled: YES];
213             [[self.muxSelectorPopup itemAtIndex: 6] setEnabled: NO];
214             [[self.muxSelectorPopup itemAtIndex: 7] setEnabled: NO];
215             [[self.muxSelectorPopup itemAtIndex: 8] setEnabled: YES];
216         } else if ([mode isEqualToString: @"MMSH"]) {
217             [self.streamAddressTextField setEnabled: YES];
218             [self.streamTTLTextField setEnabled: NO];
219             [self.streamTTLStepper setEnabled: NO];
220             [[self.muxSelectorPopup itemAtIndex: 0] setEnabled: NO];
221             [[self.muxSelectorPopup itemAtIndex: 1] setEnabled: NO];
222             [[self.muxSelectorPopup itemAtIndex: 2] setEnabled: NO];
223             [[self.muxSelectorPopup itemAtIndex: 3] setEnabled: NO];
224             [[self.muxSelectorPopup itemAtIndex: 4] setEnabled: NO];
225             [[self.muxSelectorPopup itemAtIndex: 5] setEnabled: YES];
226             [[self.muxSelectorPopup itemAtIndex: 6] setEnabled: NO];
227             [[self.muxSelectorPopup itemAtIndex: 7] setEnabled: NO];
228             [[self.muxSelectorPopup itemAtIndex: 8] setEnabled: NO];
229             [self.muxSelectorPopup selectItemAtIndex: 5];
230         } else if ([mode isEqualToString: @"UDP"]) {
231             [self.streamAddressTextField setEnabled: YES];
232             [self.streamTTLTextField setEnabled: YES];
233             [self.streamTTLStepper setEnabled: YES];
234             [[self.muxSelectorPopup itemAtIndex: 1] setEnabled: NO];
235             [[self.muxSelectorPopup itemAtIndex: 2] setEnabled: NO];
236             [[self.muxSelectorPopup itemAtIndex: 3] setEnabled: NO];
237             [[self.muxSelectorPopup itemAtIndex: 4] setEnabled: NO];
238             [[self.muxSelectorPopup itemAtIndex: 5] setEnabled: NO];
239             [[self.muxSelectorPopup itemAtIndex: 6] setEnabled: NO];
240             [[self.muxSelectorPopup itemAtIndex: 7] setEnabled: NO];
241             [[self.muxSelectorPopup itemAtIndex: 8] setEnabled: YES];
242             [self.sapCheckbox setEnabled: YES];
243             [self.channelNameTextField setEnabled: YES];
244         } else if ([mode isEqualToString: @"RTP"]) {
245             [self.streamAddressTextField setEnabled: YES];
246             [self.streamTTLTextField setEnabled: YES];
247             [self.streamTTLStepper setEnabled: YES];
248             [[self.muxSelectorPopup itemAtIndex: 0] setEnabled: NO];
249             [[self.muxSelectorPopup itemAtIndex: 1] setEnabled: NO];
250             [[self.muxSelectorPopup itemAtIndex: 2] setEnabled: NO];
251             [[self.muxSelectorPopup itemAtIndex: 3] setEnabled: NO];
252             [[self.muxSelectorPopup itemAtIndex: 4] setEnabled: NO];
253             [[self.muxSelectorPopup itemAtIndex: 5] setEnabled: NO];
254             [[self.muxSelectorPopup itemAtIndex: 6] setEnabled: NO];
255             [[self.muxSelectorPopup itemAtIndex: 7] setEnabled: NO];
256             [[self.muxSelectorPopup itemAtIndex: 8] setEnabled: YES];
257             [self.muxSelectorPopup selectItemAtIndex: 8];
258             [self.sapCheckbox setEnabled: YES];
259             [self.rtspCheckbox setEnabled: YES];
260             [self.httpCheckbox setEnabled: YES];
261             [self.fileCheckbox setEnabled: YES];
262             [self.channelNameTextField setEnabled: YES];
263         }
264     }
265
266     if (![[self.muxSelectorPopup selectedItem] isEnabled] && ![mode isEqualToString: @"RTP"])
267         [self.muxSelectorPopup selectItemAtIndex: 0];
268     else if (![[self.muxSelectorPopup selectedItem] isEnabled] && [mode isEqualToString: @"RTP"])
269         [self.muxSelectorPopup selectItemAtIndex: 8];
270
271     [self outputInfoChanged: nil];
272 }
273
274 - (IBAction)outputInfoChanged:(id)object
275 {
276     NSString *mode, *mux, *mux_string;
277     NSMutableString *announce = [NSMutableString stringWithString:@""];
278     NSMutableString *mrl_string = [NSMutableString stringWithString:@":sout=#"];
279
280     [mrl_string appendString: _transcode];
281     if ([self.displayOnLocalScreenCheckbox state] == NSOnState)
282         [mrl_string appendString: @"duplicate{dst=display,dst="];
283
284     mode = [[self.outputMethodMatrix selectedCell] title];
285     mux = [self.muxSelectorPopup titleOfSelectedItem];
286
287     if ([mux isEqualToString: @"AVI"]) mux_string = @"avi";
288     else if ([mux isEqualToString: @"Ogg"]) mux_string = @"ogg";
289     else if ([mux isEqualToString: @"MPEG PS"]) mux_string = @"ps";
290     else if ([mux isEqualToString: @"MPEG 4"]) mux_string = @"mp4";
291     else if ([mux isEqualToString: @"MPEG 1"]) mux_string = @"mpeg1";
292     else if ([mux isEqualToString: @"Quicktime"]) mux_string = @"mov";
293     else if ([mux isEqualToString: @"ASF"]) mux_string = @"asf";
294     else if ([mux isEqualToString: @"Raw"]) mux_string = @"raw";
295     else mux_string = @"ts";
296
297     if ([mode isEqualToString: _NS("File")]) {
298         if ([self.dumpCheckbox state] == NSOnState) {
299             _soutMRL = [NSArray arrayWithObjects:@":demux=dump",
300                         [NSString stringWithFormat:
301                         @":demuxdump-file=%@",
302                         [self.fileTextField stringValue]], nil];
303             return;
304         } else
305             [mrl_string appendFormat:@"standard{mux=%@,access=file{no-overwrite},dst=\"%@\"}",
306              mux_string,
307              [self.fileTextField stringValue]];
308     }
309     else if ([mode isEqualToString: _NS("Stream")]) {
310         mode = [self.streamTypePopup titleOfSelectedItem];
311
312         if ([mode isEqualToString: @"HTTP"])
313             mode = @"http";
314         else if ([mode isEqualToString: @"MMSH"]) {
315             if ([mux isEqualToString: @"ASF"])
316                 mux_string = @"asfh";
317             mode = @"mmsh";
318         } else if ([mode isEqualToString: @"UDP"]) {
319             mode = @"udp";
320             if ([self.sapCheckbox state] == NSOnState) {
321                 if (![[self.channelNameTextField stringValue] isEqualToString: @""])
322                     [announce appendFormat:@",sap,name=%@", [self.channelNameTextField stringValue]];
323                 else
324                     [announce appendFormat:@",sap"];
325             }
326         }
327         if (![mode isEqualToString: @"RTP"]) {
328             /* split up the hostname and the following path to paste the
329              * port correctly. Not need, if there isn't any path following the
330              * hostname. */
331             NSArray *urlItems = [[self.streamAddressTextField stringValue] componentsSeparatedByString: @"/"];
332             NSMutableString *finalStreamAddress = [[NSMutableString alloc] init];
333
334             if ([urlItems count] == 1)
335                 [finalStreamAddress appendFormat: @"\"%@:%@\"", [self.streamAddressTextField stringValue],[self.streamPortTextField stringValue]];
336             else {
337                 [finalStreamAddress appendFormat: @"\"%@:%@", [urlItems objectAtIndex:0], [self.streamPortTextField stringValue]];
338                 NSUInteger itemCount = [urlItems count];
339                 for (NSUInteger x = 0; x < itemCount; x++)
340                     [finalStreamAddress appendFormat: @"/%@", [urlItems objectAtIndex:x]];
341                 [finalStreamAddress appendString: @"\""];
342             }
343
344             [mrl_string appendFormat:
345                         @"standard{mux=%@,access=%@,dst=%@%@}",
346                         mux_string, mode, finalStreamAddress, announce];
347         } else {
348             NSString *stream_name;
349
350             if (![[self.channelNameTextField stringValue] isEqualToString: @""])
351                 stream_name = [NSString stringWithFormat:@",name=%@", [self.channelNameTextField stringValue]];
352             else
353                 stream_name = @"";
354
355             if ([self.sapCheckbox state] == NSOnState)
356                 [announce appendString: @",sdp=sap"];
357
358             if ([self.rtspCheckbox state] == NSOnState)
359                 [announce appendFormat:@",sdp=\"rtsp://%@\"",[self.sdpURLTextField stringValue]];
360
361             if ([self.httpCheckbox state] == NSOnState)
362                 [announce appendFormat:@",sdp=\"http://%@\"",[self.sdpURLTextField stringValue]];
363
364             if ([self.fileCheckbox state] == NSOnState)
365                 [announce appendFormat:@",sdp=\"file://%@\"",[self.sdpURLTextField stringValue]];
366
367             [mrl_string appendFormat:
368                         @"rtp{mux=ts,dst=\"%@\",port=%@%@%@}", [self.streamAddressTextField stringValue],
369                         [self.streamPortTextField stringValue], stream_name, announce];
370         }
371
372     }
373     if ([self.displayOnLocalScreenCheckbox state] == NSOnState)
374         [mrl_string appendString: @"}"];
375
376     _soutMRL = [NSArray arrayWithObject:mrl_string];
377 }
378
379 - (void)TTLChanged:(NSNotification *)notification
380 {
381     config_PutInt(VLCIntf, "ttl", [self.streamTTLTextField intValue]);
382 }
383
384 - (IBAction)outputFileBrowse:(id)sender
385 {
386     NSString *mux_string;
387     if ([[self.muxSelectorPopup titleOfSelectedItem] isEqualToString: @"MPEG PS"])
388         mux_string = @"vob";
389     else if ([[self.muxSelectorPopup titleOfSelectedItem] isEqualToString: @"MPEG 1"])
390         mux_string = @"mpg";
391     else if ([[self.muxSelectorPopup titleOfSelectedItem] isEqualToString: @"AVI"])
392         mux_string = @"avi";
393     else if ([[self.muxSelectorPopup titleOfSelectedItem] isEqualToString: @"ASF"])
394         mux_string = @"asf";
395     else if ([[self.muxSelectorPopup titleOfSelectedItem] isEqualToString: @"Ogg"])
396         mux_string = @"ogm";
397     else if ([[self.muxSelectorPopup titleOfSelectedItem] isEqualToString: @"MPEG 4"])
398         mux_string = @"mp4";
399     else if ([[self.muxSelectorPopup titleOfSelectedItem] isEqualToString: @"Quicktime"])
400         mux_string = @"mov";
401     else if ([[self.muxSelectorPopup titleOfSelectedItem] isEqualToString: @"Raw"])
402         mux_string = @"raw";
403     else
404         mux_string = @"ts";
405
406     NSString *name = [NSString stringWithFormat: @"vlc-output.%@", mux_string];
407
408     NSSavePanel *save_panel = [NSSavePanel savePanel];
409     [save_panel setTitle: _NS("Save File")];
410     [save_panel setPrompt: _NS("Save")];
411     [save_panel setNameFieldStringValue: name];
412
413     if ([save_panel runModal] == NSFileHandlingPanelOKButton) {
414         [self.fileTextField setStringValue: [[save_panel URL] path]];
415         [self outputInfoChanged: nil];
416     }
417 }
418
419 - (IBAction)streamPortStepperChanged:(id)sender
420 {
421     [self.streamPortTextField setIntValue:[self.streamPortStepper intValue]];
422     [self outputInfoChanged: nil];
423 }
424
425 - (IBAction)streamTTLStepperChanged:(id)sender
426 {
427     [self.streamTTLTextField setIntValue:[self.streamTTLStepper intValue]];
428     [self TTLChanged:nil];
429 }
430
431 - (IBAction)transcodeChanged:(id)sender
432 {
433     if ([self.transcodeVideoCheckbox state] == NSOnState) {
434         [self.transcodeVideoSelectorPopup setEnabled: YES];
435         [self.transcodeVideoBitrateComboBox setEnabled: YES];
436         [self.transcodeVideoScaleComboBox setEnabled: YES];
437     } else {
438         [self.transcodeVideoSelectorPopup setEnabled: NO];
439         [self.transcodeVideoBitrateComboBox setEnabled: NO];
440         [self.transcodeVideoScaleComboBox setEnabled: NO];
441     }
442     if ([self.transcodeAudioCheckbox state] == NSOnState) {
443         [self.transcodeAudioSelectorPopup setEnabled: YES];
444         [self.transcodeAudioBitrateComboBox setEnabled: YES];
445         [self.transcodeAudioChannelsComboBox setEnabled: YES];
446     } else {
447         [self.transcodeAudioSelectorPopup setEnabled: NO];
448         [self.transcodeAudioBitrateComboBox setEnabled: NO];
449         [self.transcodeAudioChannelsComboBox setEnabled: NO];
450     }
451
452     [self transcodeInfoChanged:nil];
453 }
454
455 - (IBAction)transcodeInfoChanged:(id)object
456 {
457     NSMutableString *transcode_string = [NSMutableString stringWithCapacity:200];
458
459     if ([self.transcodeVideoCheckbox state] == NSOnState ||
460         [self.transcodeAudioCheckbox state] == NSOnState) {
461         [transcode_string appendString:@"transcode{"];
462         if ([self.transcodeVideoCheckbox state] == NSOnState) {
463             [transcode_string appendFormat: @"vcodec=\"%@\",vb=\"%@\"" \
464                                                             ",scale=\"%@\"",
465                 [self.transcodeVideoSelectorPopup titleOfSelectedItem],
466                 [self.transcodeVideoBitrateComboBox stringValue],
467                 [self.transcodeVideoScaleComboBox stringValue]];
468             if ([self.transcodeAudioCheckbox state] == NSOnState)
469                 [transcode_string appendString: @","];
470         }
471         if ([self.transcodeAudioCheckbox state] == NSOnState) {
472             [transcode_string appendFormat: @"acodec=\"%@\",ab=\"%@\"",
473                 [self.transcodeAudioSelectorPopup titleOfSelectedItem],
474                 [self.transcodeAudioBitrateComboBox stringValue]];
475             if (![[self.transcodeAudioChannelsComboBox stringValue] isEqualToString: @""])
476                 [transcode_string appendFormat: @",channels=\"%@\"", [self.transcodeAudioChannelsComboBox stringValue]];
477         }
478         [transcode_string appendString:@"}:"];
479     }
480     else
481         [transcode_string setString: @""];
482
483     _transcode = [NSString stringWithString:transcode_string];
484     [self outputInfoChanged:nil];
485 }
486
487 - (IBAction)announceChanged:(id)sender
488 {
489     NSString *mode;
490     mode = [[self.streamTypePopup selectedCell] title];
491     [self.channelNameTextField setEnabled:[self.sapCheckbox state] || [mode isEqualToString: @"RTP"]];
492
493     if ([mode isEqualToString: @"RTP"]) {
494 /*        if ([[sender title] isEqualToString: _NS("SAP Announcement")]) {
495             [self.rtspCheckbox setState:NSOffState];
496             [self.httpCheckbox setState:NSOffState];
497         }*/
498         if ([[sender title] isEqualToString:_NS("RTSP Announcement")]) {
499 //            [self.sapCheckbox setState:NSOffState];
500             [self.httpCheckbox setState:NSOffState];
501             [self.fileCheckbox setState:NSOffState];
502         } else if ([[sender title] isEqualToString:_NS("HTTP Announcement")]) {
503 //            [self.sapCheckbox setState:NSOffState];
504             [self.rtspCheckbox setState:NSOffState];
505             [self.fileCheckbox setState:NSOffState];
506         } else if ([[sender title] isEqualToString:_NS("Export SDP as file")]) {
507             [self.rtspCheckbox setState:NSOffState];
508             [self.httpCheckbox setState:NSOffState];
509         }
510
511         if ([self.rtspCheckbox state] == NSOnState ||
512             [self.httpCheckbox state] == NSOnState ||
513             [self.fileCheckbox state] == NSOnState)
514             [self.sdpURLTextField setEnabled: YES];
515         else
516             [self.sdpURLTextField setEnabled: NO];
517     }
518     [self outputInfoChanged: nil];
519 }
520
521 @end