1 /*****************************************************************************
2 * sout.cpp : Stream output dialog ( old-style )
3 ****************************************************************************
4 * Copyright (C) 2007-2009 the VideoLAN team
5 *
6 * $Id: 1a6213bf35085f002096cfced0a7830a267aab40 $
7 *
8 * Authors: Clément Stenac <zorglub@videolan.org>
9 * Jean-Baptiste Kempf <jb@videolan.org>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * ( at your option ) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
24 *****************************************************************************/
25
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #include "dialogs/sout.hpp"
31 #include "util/qt_dirs.hpp"
32 #include "components/sout/sout_widgets.hpp"
33
34 #include <QString>
35 #include <QFileDialog>
36 #include <QToolButton>
37 #include <QSpinBox>
38 #include <assert.h>
39
SoutDialog(QWidget * parent,intf_thread_t * _p_intf,const QString & inputMRL)40 SoutDialog::SoutDialog( QWidget *parent, intf_thread_t *_p_intf, const QString& inputMRL )
41 : QWizard( parent )
42 {
43 p_intf = _p_intf;
44
45 setWindowTitle( qtr( "Stream Output" ) );
46 setWindowRole( "vlc-stream-output" );
47
48 /* UI stuff */
49 ui.setupUi( this );
50 ui.inputBox->setMRL( inputMRL );
51 ui.helpEdit->setPlainText( qtr("This wizard will allow you to stream or "
52 "convert your media for use locally, on your private network, "
53 "or on the Internet.\n"
54 "You should start by checking that source matches what you want "
55 "your input to be and then press the \"Next\" "
56 "button to continue.\n") );
57
58 ui.mrlEdit->setToolTip ( qtr( "Stream output string.\n"
59 "This is automatically generated "
60 "when you change the above settings,\n"
61 "but you can change it manually." ) ) ;
62
63 ui.destTab->setTabsClosable( true );
64 QTabBar* tb = ui.destTab->findChild<QTabBar*>();
65 if( tb != NULL ) tb->tabButton(0, QTabBar::RightSide)->hide();
66 CONNECT( ui.destTab, tabCloseRequested( int ), this, closeTab( int ) );
67 ui.destTab->setTabIcon( 0, QIcon( ":/buttons/playlist/playlist_add.svg" ) );
68
69 ui.destBox->addItem( qtr( "File" ) );
70 ui.destBox->addItem( "HTTP" );
71 ui.destBox->addItem( "MS-WMSP (MMSH)" );
72 ui.destBox->addItem( "RTSP" );
73 ui.destBox->addItem( "RTP / MPEG Transport Stream" );
74 ui.destBox->addItem( "RTP Audio/Video Profile" );
75 ui.destBox->addItem( "UDP (legacy)" );
76 ui.destBox->addItem( "Icecast" );
77
78 BUTTONACT( ui.addButton, addDest() );
79
80 // /* Connect everything to the updateMRL function */
81 #define CB( x ) CONNECT( ui.x, toggled( bool ), this, updateMRL() );
82 #define CT( x ) CONNECT( ui.x, textChanged( const QString& ), this, updateMRL() );
83 #define CS( x ) CONNECT( ui.x, valueChanged( int ), this, updateMRL() );
84 #define CC( x ) CONNECT( ui.x, currentIndexChanged( int ), this, updateMRL() );
85
86 /* Misc */
87 CB( soutAll );
88 CB( localOutput ); CB( transcodeBox );
89 CONNECT( ui.profileSelect, optionsChanged(), this, updateMRL() );
90
91 setButtonText( QWizard::BackButton, qtr("Back") );
92 setButtonText( QWizard::CancelButton, qtr("Cancel") );
93 setButtonText( QWizard::NextButton, qtr("Next") );
94 setButtonText( QWizard::FinishButton, qtr("Stream") );
95
96 #undef CC
97 #undef CS
98 #undef CT
99 #undef CB
100 }
101
closeTab(int i)102 void SoutDialog::closeTab( int i )
103 {
104 if( i == 0 ) return;
105
106 QWidget* temp = ui.destTab->widget( i );
107 ui.destTab->removeTab( i );
108 delete temp;
109 updateMRL();
110 }
111
addDest()112 void SoutDialog::addDest( )
113 {
114 VirtualDestBox *db;
115 QString caption;
116
117 switch( ui.destBox->currentIndex() )
118 {
119 case 0:
120 db = new FileDestBox( this, p_intf );
121 caption = qtr( "File" );
122 break;
123 case 1:
124 db = new HTTPDestBox( this );
125 caption = qfu( "HTTP" );
126 break;
127 case 2:
128 db = new MMSHDestBox( this );
129 caption = qfu( "WMSP" );
130 break;
131 case 3:
132 db = new RTSPDestBox( this );
133 caption = qfu( "RTSP" );
134 break;
135 case 4:
136 db = new RTPDestBox( this, "ts" );
137 caption = "RTP/TS";
138 break;
139 case 5:
140 db = new RTPDestBox( this );
141 caption = "RTP/AVP";
142 break;
143 case 6:
144 db = new UDPDestBox( this );
145 caption = "UDP";
146 break;
147 case 7:
148 db = new ICEDestBox( this );
149 caption = "Icecast";
150 break;
151 default:
152 vlc_assert_unreachable();
153 return;
154 }
155
156 int index = ui.destTab->addTab( db, caption );
157 CONNECT( db, mrlUpdated(), this, updateMRL() );
158 ui.destTab->setCurrentIndex( index );
159 updateMRL();
160 }
161
done(int r)162 void SoutDialog::done( int r )
163 {
164 mrl = ui.mrlEdit->toPlainText();
165 QWizard::done(r);
166 }
167
updateMRL()168 void SoutDialog::updateMRL()
169 {
170 QString qs_mux = ui.profileSelect->getMux();
171
172 SoutMrl smrl( ":sout=#" );
173 if( !ui.profileSelect->getTranscode().isEmpty() && ui.transcodeBox->isChecked() )
174 {
175 smrl.begin( ui.profileSelect->getTranscode() );
176 smrl.end();
177 }
178
179 bool multi = false;
180
181 if( ui.destTab->count() >= 3 ||
182 ( ui.destTab->count() == 2 && ui.localOutput->isChecked() ) )
183 multi = true;
184
185 if( multi )
186 smrl.begin( "duplicate" );
187
188 for( int i = 1; i < ui.destTab->count(); i++ )
189 {
190 VirtualDestBox *vdb = qobject_cast<VirtualDestBox *>(ui.destTab->widget( i ));
191 if( !vdb )
192 continue;
193
194 QString tempMRL = vdb->getMRL( qs_mux );
195 if( tempMRL.isEmpty() ) continue;
196
197 if( multi )
198 smrl.option( "dst", tempMRL );
199 else
200 {
201 smrl.begin( tempMRL);
202 smrl.end();
203 }
204 }
205 if( ui.localOutput->isChecked() )
206 {
207 if( multi )
208 smrl.option( "dst", "display" );
209 else
210 {
211 smrl.begin( "display" );
212 smrl.end();
213 }
214 }
215
216 if ( multi ) smrl.end();
217
218 mrl = smrl.getMrl();
219
220 if( ui.soutAll->isChecked() )
221 mrl.append( " :sout-all" );
222 else
223 mrl.append( " :no-sout-all" );
224
225 mrl.append( " :sout-keep" );
226
227 ui.mrlEdit->setPlainText( mrl );
228 }
229
230