|
|
|
/* this file is part of the kmplayer application
|
|
|
|
copyright (c) 2003 koos vriezen <koos.vriezen@xs4all.nl>
|
|
|
|
|
|
|
|
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; see the file copying. if not, write to
|
|
|
|
the free software foundation, inc., 59 temple place - suite 330,
|
|
|
|
boston, ma 02110-1301, usa.
|
|
|
|
*/
|
|
|
|
#include <algorithm>
|
|
|
|
|
|
|
|
#include <tqlayout.h>
|
|
|
|
#include <tqlabel.h>
|
|
|
|
#include <tqpushbutton.h>
|
|
|
|
#include <tqtable.h>
|
|
|
|
#include <tqstringlist.h>
|
|
|
|
#include <tqcombobox.h>
|
|
|
|
#include <tqlistbox.h>
|
|
|
|
#include <tqlineedit.h>
|
|
|
|
#include <tqwhatsthis.h>
|
|
|
|
#include <tqtabwidget.h>
|
|
|
|
#include <tqcursor.h>
|
|
|
|
#include <tqdir.h>
|
|
|
|
#include <tqfile.h>
|
|
|
|
#include <tqtimer.h>
|
|
|
|
|
|
|
|
#include <tdelocale.h>
|
|
|
|
#include <kdebug.h>
|
|
|
|
#include <kled.h>
|
|
|
|
#include <tdeconfig.h>
|
|
|
|
#include <kprocess.h>
|
|
|
|
#include <kprocctrl.h>
|
|
|
|
#include <tdemessagebox.h>
|
|
|
|
|
|
|
|
#include "kmplayerbroadcast.h"
|
|
|
|
#include "kmplayerprocess.h"
|
|
|
|
#include "kmplayerview.h"
|
|
|
|
#include "kmplayerpartbase.h"
|
|
|
|
|
|
|
|
static const char * strBroadcast = "Broadcast";
|
|
|
|
static const char * strBindAddress = "Bind Address";
|
|
|
|
static const char * strFFServerPort = "FFServer Port";
|
|
|
|
static const char * strMaxClients = "Maximum Connections";
|
|
|
|
static const char * strMaxBandwidth = "Maximum Bandwidth";
|
|
|
|
static const char * strFeedFile = "Feed File";
|
|
|
|
static const char * strFeedFileSize = "Feed File Size";
|
|
|
|
//static const char * strFFServerSetting = "FFServer Setting";
|
|
|
|
static const char * strFFServerCustomSetting = "Custom Setting";
|
|
|
|
static const char * strFFServerProfiles = "Profiles";
|
|
|
|
|
|
|
|
|
|
|
|
KDE_NO_CDTOR_EXPORT FFServerSetting::FFServerSetting (int i, const TQString & n, const TQString & f, const TQString & ac, int abr, int asr, const TQString & vc, int vbr, int q, int fr, int gs, int w, int h)
|
|
|
|
: index (i), name (n), format (f), audiocodec (ac),
|
|
|
|
audiobitrate (abr > 0 ? TQString::number (abr) : TQString ()),
|
|
|
|
audiosamplerate (asr > 0 ? TQString::number (asr) : TQString ()),
|
|
|
|
videocodec (vc),
|
|
|
|
videobitrate (vbr > 0 ? TQString::number (vbr) : TQString ()),
|
|
|
|
quality (q > 0 ? TQString::number (q) : TQString ()),
|
|
|
|
framerate (fr > 0 ? TQString::number (fr) : TQString ()),
|
|
|
|
gopsize (gs > 0 ? TQString::number (gs) : TQString ()),
|
|
|
|
width (w > 0 ? TQString::number (w) : TQString ()),
|
|
|
|
height (h > 0 ? TQString::number (h) : TQString ()) {}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT FFServerSetting & FFServerSetting::operator = (const FFServerSetting & fs) {
|
|
|
|
format = fs.format;
|
|
|
|
audiocodec = fs.audiocodec;
|
|
|
|
audiobitrate = fs.audiobitrate;
|
|
|
|
audiosamplerate = fs.audiosamplerate;
|
|
|
|
videocodec = fs.videocodec;
|
|
|
|
videobitrate = fs.videobitrate;
|
|
|
|
quality = fs.quality;
|
|
|
|
framerate = fs.framerate;
|
|
|
|
gopsize = fs.gopsize;
|
|
|
|
width = fs.width;
|
|
|
|
height = fs.height;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT FFServerSetting & FFServerSetting::operator = (const TQStringList & sl) {
|
|
|
|
if (sl.count () < 11) {
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
TQStringList::const_iterator it = sl.begin ();
|
|
|
|
format = *it++;
|
|
|
|
audiocodec = *it++;
|
|
|
|
audiobitrate = *it++;
|
|
|
|
audiosamplerate = *it++;
|
|
|
|
videocodec = *it++;
|
|
|
|
videobitrate = *it++;
|
|
|
|
quality = *it++;
|
|
|
|
framerate = *it++;
|
|
|
|
gopsize = *it++;
|
|
|
|
width = *it++;
|
|
|
|
height = *it++;
|
|
|
|
acl.clear ();
|
|
|
|
TQStringList::const_iterator end( sl.end() );
|
|
|
|
for (; it != end; ++it)
|
|
|
|
acl.push_back (*it);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT TQString & FFServerSetting::ffconfig (TQString & buf) {
|
|
|
|
TQString nl ("\n");
|
|
|
|
buf = TQString ("Format ") + format + nl;
|
|
|
|
if (!audiocodec.isEmpty ())
|
|
|
|
buf += TQString ("AudioCodec ") + audiocodec + nl;
|
|
|
|
if (!audiobitrate.isEmpty ())
|
|
|
|
buf += TQString ("AudioBitRate ") + audiobitrate + nl;
|
|
|
|
if (!audiosamplerate.isEmpty () > 0)
|
|
|
|
buf += TQString ("AudioSampleRate ") + audiosamplerate + nl;
|
|
|
|
if (!videocodec.isEmpty ())
|
|
|
|
buf += TQString ("VideoCodec ") + videocodec + nl;
|
|
|
|
if (!videobitrate.isEmpty ())
|
|
|
|
buf += TQString ("VideoBitRate ") + videobitrate + nl;
|
|
|
|
if (!quality.isEmpty ())
|
|
|
|
buf += TQString ("VideoTQMin ") + quality + nl;
|
|
|
|
if (!framerate.isEmpty ())
|
|
|
|
buf += TQString ("VideoFrameRate ") + framerate + nl;
|
|
|
|
if (!gopsize.isEmpty ())
|
|
|
|
buf += TQString ("VideoGopSize ") + gopsize + nl;
|
|
|
|
if (!width.isEmpty () && !height.isEmpty ())
|
|
|
|
buf += TQString ("VideoSize ") + width + TQString ("x") + height + nl;
|
|
|
|
return buf;
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT const TQStringList FFServerSetting::list () {
|
|
|
|
TQStringList sl;
|
|
|
|
sl.push_back (format);
|
|
|
|
sl.push_back (audiocodec);
|
|
|
|
sl.push_back (audiobitrate);
|
|
|
|
sl.push_back (audiosamplerate);
|
|
|
|
sl.push_back (videocodec);
|
|
|
|
sl.push_back (videobitrate);
|
|
|
|
sl.push_back (quality);
|
|
|
|
sl.push_back (framerate);
|
|
|
|
sl.push_back (gopsize);
|
|
|
|
sl.push_back (width);
|
|
|
|
sl.push_back (height);
|
|
|
|
TQStringList::const_iterator it = acl.begin ();
|
|
|
|
TQStringList::const_iterator end( acl.end () );
|
|
|
|
for (; it != end; ++it)
|
|
|
|
sl.push_back (*it);
|
|
|
|
return sl;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
KDE_NO_CDTOR_EXPORT KMPlayerPrefBroadcastPage::KMPlayerPrefBroadcastPage (TQWidget *parent) : TQFrame (parent) {
|
|
|
|
TQVBoxLayout *layout = new TQVBoxLayout (this, 5);
|
|
|
|
TQGridLayout *gridlayout = new TQGridLayout (layout, 6, 2, 2);
|
|
|
|
TQLabel *label = new TQLabel (i18n ("Bind address:"), this);
|
|
|
|
bindaddress = new TQLineEdit ("", this);
|
|
|
|
TQWhatsThis::add (bindaddress, i18n ("If you have multiple network devices, you can limit access"));
|
|
|
|
gridlayout->addWidget (label, 0, 0);
|
|
|
|
gridlayout->addWidget (bindaddress, 0, 1);
|
|
|
|
label = new TQLabel (i18n ("Listen port:"), this);
|
|
|
|
port = new TQLineEdit ("", this);
|
|
|
|
gridlayout->addWidget (label, 1, 0);
|
|
|
|
gridlayout->addWidget (port, 1, 1);
|
|
|
|
label = new TQLabel (i18n ("Maximum connections:"), this);
|
|
|
|
maxclients = new TQLineEdit ("", this);
|
|
|
|
gridlayout->addWidget (label, 2, 0);
|
|
|
|
gridlayout->addWidget (maxclients, 2, 1);
|
|
|
|
label = new TQLabel (i18n ("Maximum bandwidth (kbit):"), this);
|
|
|
|
maxbandwidth = new TQLineEdit ("", this);
|
|
|
|
gridlayout->addWidget (label, 3, 0);
|
|
|
|
gridlayout->addWidget (maxbandwidth, 3, 1);
|
|
|
|
label = new TQLabel (i18n ("Temporary feed file:"), this);
|
|
|
|
feedfile = new TQLineEdit ("", this);
|
|
|
|
gridlayout->addWidget (label, 4, 0);
|
|
|
|
gridlayout->addWidget (feedfile, 4, 1);
|
|
|
|
label = new TQLabel (i18n ("Feed file size (kB):"), this);
|
|
|
|
feedfilesize = new TQLineEdit ("", this);
|
|
|
|
gridlayout->addWidget (label, 5, 0);
|
|
|
|
gridlayout->addWidget (feedfilesize, 5, 1);
|
|
|
|
layout->addItem (new TQSpacerItem (0, 0, TQSizePolicy::Minimum, TQSizePolicy::Expanding));
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
#undef ADDPROPERTY
|
|
|
|
#define ADDPROPERTY(label,qedit,gridlayout,row,parent) \
|
|
|
|
qedit = new TQLineEdit ("", parent); \
|
|
|
|
gridlayout->addWidget (new TQLabel (qedit, label, parent), row, 0); \
|
|
|
|
gridlayout->addWidget (qedit, row, 1);
|
|
|
|
|
|
|
|
KDE_NO_CDTOR_EXPORT KMPlayerPrefBroadcastFormatPage::KMPlayerPrefBroadcastFormatPage (TQWidget *parent, FFServerSettingList & ffs) : TQFrame (parent, "BroadcastPage"), profiles (ffs)
|
|
|
|
{
|
|
|
|
TQHBoxLayout *layout = new TQHBoxLayout (this, 5);
|
|
|
|
TQGridLayout *formatlayout = new TQGridLayout (11, 2, 2);
|
|
|
|
formatlayout->setAlignment (TQt::AlignTop);
|
|
|
|
TQVBoxLayout *leftlayout = new TQVBoxLayout (15);
|
|
|
|
TQHBoxLayout *ledlayout = new TQHBoxLayout (5);
|
|
|
|
format = new TQComboBox (this);
|
|
|
|
TQLabel * label = new TQLabel (format, i18n ("Format:"), this);
|
|
|
|
format->clear ();
|
|
|
|
format->insertItem (TQString ("asf"));
|
|
|
|
format->insertItem (TQString ("avi"));
|
|
|
|
format->insertItem (TQString ("mpjpeg"));
|
|
|
|
format->insertItem (TQString ("mpeg"));
|
|
|
|
format->insertItem (TQString ("rm"));
|
|
|
|
format->insertItem (TQString ("swf"));
|
|
|
|
TQWhatsThis::add (format, i18n ("Only avi, mpeg and rm work for mplayer playback"));
|
|
|
|
formatlayout->addWidget (label, 0, 0);
|
|
|
|
formatlayout->addWidget (format, 0, 1);
|
|
|
|
ADDPROPERTY (i18n ("Audio codec:"), audiocodec, formatlayout, 1, this);
|
|
|
|
ADDPROPERTY (i18n ("Audio bit rate (kbit):"), audiobitrate, formatlayout, 2, this);
|
|
|
|
ADDPROPERTY (i18n ("Audio sample rate (Hz):"), audiosamplerate, formatlayout, 3, this);
|
|
|
|
ADDPROPERTY (i18n ("Video codec:"), videocodec, formatlayout, 4, this);
|
|
|
|
ADDPROPERTY (i18n ("Video bit rate (kbit):"), videobitrate, formatlayout, 5, this);
|
|
|
|
ADDPROPERTY (i18n ("Quality (1-31):"), quality, formatlayout, 6, this);
|
|
|
|
ADDPROPERTY (i18n ("Frame rate (Hz):"), framerate, formatlayout, 7, this);
|
|
|
|
ADDPROPERTY (i18n ("Gop size:"), gopsize, formatlayout, 8, this);
|
|
|
|
ADDPROPERTY (i18n ("Width (pixels):"), moviewidth, formatlayout, 9, this);
|
|
|
|
ADDPROPERTY (i18n ("Height (pixels):"), movieheight, formatlayout, 10, this);
|
|
|
|
label = new TQLabel (i18n ("Allow access from:"), this);
|
|
|
|
accesslist = new TQTable (40, 1, this);
|
|
|
|
accesslist->verticalHeader ()->hide ();
|
|
|
|
accesslist->setLeftMargin (0);
|
|
|
|
accesslist->setColumnWidth (0, 250);
|
|
|
|
TQWhatsThis::add (accesslist, i18n ("'Single IP' or 'start-IP end-IP' for IP ranges"));
|
|
|
|
TQHeader *header = accesslist->horizontalHeader ();
|
|
|
|
header->setLabel (0, i18n ("Host/IP or IP Range"));
|
|
|
|
TQFrame *profileframe = new TQFrame (this);
|
|
|
|
TQGridLayout *profileslayout = new TQGridLayout (profileframe, 5, 2, 2);
|
|
|
|
profile = new TQLineEdit ("", profileframe);
|
|
|
|
connect (profile, TQT_SIGNAL(textChanged (const TQString &)),
|
|
|
|
this, TQT_SLOT (slotTextChanged (const TQString &)));
|
|
|
|
profilelist = new TQListBox (profileframe);
|
|
|
|
for (int i = 0; i < (int) profiles.size (); i++)
|
|
|
|
profilelist->insertItem (profiles[i]->name, i);
|
|
|
|
connect (profilelist, TQT_SIGNAL (selected (int)),
|
|
|
|
this, TQT_SLOT (slotIndexChanged (int)));
|
|
|
|
connect (profilelist, TQT_SIGNAL (highlighted (int)),
|
|
|
|
this, TQT_SLOT (slotItemHighlighted (int)));
|
|
|
|
load = new TQPushButton (i18n ("Load"), profileframe);
|
|
|
|
save = new TQPushButton (i18n ("Save"), profileframe);
|
|
|
|
del = new TQPushButton (i18n ("Delete"), profileframe);
|
|
|
|
load->setEnabled (false);
|
|
|
|
save->setEnabled (false);
|
|
|
|
del->setEnabled (false);
|
|
|
|
connect (load, TQT_SIGNAL (clicked ()), this, TQT_SLOT (slotLoad ()));
|
|
|
|
connect (save, TQT_SIGNAL (clicked ()), this, TQT_SLOT (slotSave ()));
|
|
|
|
connect (del, TQT_SIGNAL (clicked ()), this, TQT_SLOT (slotDelete ()));
|
|
|
|
profileslayout->addWidget (profile, 0, 0);
|
|
|
|
profileslayout->setRowSpacing (4, 60);
|
|
|
|
profileslayout->addMultiCellWidget (profilelist, 1, 4, 0, 0);
|
|
|
|
profileslayout->addWidget (load, 1, 1);
|
|
|
|
profileslayout->addWidget (save, 2, 1);
|
|
|
|
profileslayout->addWidget (del, 3, 1);
|
|
|
|
leftlayout->addWidget (profileframe);
|
|
|
|
startbutton = new TQPushButton (i18n ("Start"), this);
|
|
|
|
serverled = new KLed (TQt::green, KLed::Off, KLed::Raised, KLed::Circular, this);
|
|
|
|
feedled = new KLed (TQt::green, KLed::Off, KLed::Raised, KLed::Circular, this);
|
|
|
|
ledlayout->addWidget (startbutton);
|
|
|
|
ledlayout->addItem (new TQSpacerItem (0, 0, TQSizePolicy::Expanding, TQSizePolicy::Minimum));
|
|
|
|
ledlayout->addWidget (serverled);
|
|
|
|
ledlayout->addWidget (feedled);
|
|
|
|
leftlayout->addLayout (ledlayout);
|
|
|
|
TQFrame * line = new TQFrame (this);
|
|
|
|
line->setFrameShape (TQFrame::HLine);
|
|
|
|
leftlayout->addWidget (line);
|
|
|
|
leftlayout->addWidget (label);
|
|
|
|
leftlayout->addWidget (accesslist);
|
|
|
|
leftlayout->addItem (new TQSpacerItem (0, 0, TQSizePolicy::Minimum, TQSizePolicy::Expanding));
|
|
|
|
layout->addLayout (leftlayout);
|
|
|
|
line = new TQFrame (this);
|
|
|
|
line->setFrameShape (TQFrame::VLine);
|
|
|
|
layout->addWidget (line);
|
|
|
|
layout->addLayout (formatlayout);
|
|
|
|
layout->addItem (new TQSpacerItem (0, 0, TQSizePolicy::Minimum, TQSizePolicy::Expanding));
|
|
|
|
}
|
|
|
|
|
|
|
|
#undef ADDPROPERTY
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void KMPlayerPrefBroadcastFormatPage::setSettings (const FFServerSetting & fs) {
|
|
|
|
if (!fs.format.isEmpty ())
|
|
|
|
format->setCurrentText (fs.format);
|
|
|
|
audiocodec->setText (fs.audiocodec);
|
|
|
|
audiobitrate->setText (fs.audiobitrate);
|
|
|
|
audiosamplerate->setText (fs.audiosamplerate);
|
|
|
|
videocodec->setText (fs.videocodec);
|
|
|
|
videobitrate->setText (fs.videobitrate);
|
|
|
|
quality->setText (fs.quality);
|
|
|
|
framerate->setText (fs.framerate);
|
|
|
|
gopsize->setText (fs.gopsize);
|
|
|
|
moviewidth->setText (fs.width);
|
|
|
|
movieheight->setText (fs.height);
|
|
|
|
accesslist->setNumRows (0);
|
|
|
|
accesslist->setNumRows (50);
|
|
|
|
TQStringList::const_iterator it = fs.acl.begin ();
|
|
|
|
TQStringList::const_iterator end( fs.acl.end () );
|
|
|
|
for (int i = 0; it != end; ++i, ++it)
|
|
|
|
accesslist->setItem (i, 0, new TQTableItem (accesslist, TQTableItem::Always, *it));
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void KMPlayerPrefBroadcastFormatPage::getSettings (FFServerSetting & fs) {
|
|
|
|
fs.format = format->currentText ();
|
|
|
|
fs.audiocodec = audiocodec->text ();
|
|
|
|
fs.audiobitrate = audiobitrate->text ();
|
|
|
|
fs.audiosamplerate = audiosamplerate->text ();
|
|
|
|
fs.videocodec = videocodec->text ();
|
|
|
|
fs.videobitrate = videobitrate->text ();
|
|
|
|
fs.quality = quality->text ();
|
|
|
|
fs.framerate = framerate->text ();
|
|
|
|
fs.gopsize = gopsize->text ();
|
|
|
|
fs.width = moviewidth->text ();
|
|
|
|
fs.height = movieheight->text ();
|
|
|
|
fs.acl.clear ();
|
|
|
|
for (int i = 0; i < accesslist->numRows (); ++i) {
|
|
|
|
if (accesslist->item (i, 0) && !accesslist->item (i, 0)->text ().isEmpty ())
|
|
|
|
fs.acl.push_back (accesslist->item (i, 0)->text ());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void KMPlayerPrefBroadcastFormatPage::slotIndexChanged (int index) {
|
|
|
|
slotItemHighlighted (index);
|
|
|
|
if (index >= 0 && index < (int) profiles.size ())
|
|
|
|
setSettings (*profiles[index]);
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void KMPlayerPrefBroadcastFormatPage::slotTextChanged (const TQString & txt) {
|
|
|
|
save->setEnabled (txt.length ());
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void KMPlayerPrefBroadcastFormatPage::slotItemHighlighted (int index) {
|
|
|
|
if (index < 0 || index >= (int) profiles.size ()) {
|
|
|
|
load->setEnabled (false);
|
|
|
|
del->setEnabled (false);
|
|
|
|
} else {
|
|
|
|
profile->setText (profiles[profilelist->currentItem ()]->name);
|
|
|
|
load->setEnabled (true);
|
|
|
|
del->setEnabled (true);
|
|
|
|
slotTextChanged (profilelist->currentText ());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void KMPlayerPrefBroadcastFormatPage::slotSave () {
|
|
|
|
for (int i = 0; i < (int) profiles.size (); ++i)
|
|
|
|
if (profiles[i]->name == profile->text ()) {
|
|
|
|
getSettings (*profiles[i]);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
FFServerSetting * fs = new FFServerSetting;
|
|
|
|
fs->name = profile->text ();
|
|
|
|
getSettings (*fs);
|
|
|
|
profiles.push_back (fs);
|
|
|
|
profilelist->insertItem (fs->name);
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void KMPlayerPrefBroadcastFormatPage::slotLoad () {
|
|
|
|
setSettings (*profiles[profilelist->currentItem ()]);
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void KMPlayerPrefBroadcastFormatPage::slotDelete () {
|
|
|
|
FFServerSettingList::iterator it = profiles.begin();
|
|
|
|
for (int i = 0; i < profilelist->currentItem (); i++)
|
|
|
|
++it;
|
|
|
|
delete *it;
|
|
|
|
profiles.erase (it);
|
|
|
|
profilelist->removeItem (profilelist->currentItem ());
|
|
|
|
load->setEnabled (false);
|
|
|
|
del->setEnabled (false);
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
static bool stopProcess (TDEProcess * process, const char * cmd = 0L) {
|
|
|
|
if (!process || !process->isRunning ()) return true;
|
|
|
|
do {
|
|
|
|
if (cmd)
|
|
|
|
process->writeStdin (cmd, strlen (cmd));
|
|
|
|
TDEProcessController::theTDEProcessController->waitForProcessExit (1);
|
|
|
|
if (!process->isRunning ())
|
|
|
|
break;
|
|
|
|
process->kill (SIGINT);
|
|
|
|
TDEProcessController::theTDEProcessController->waitForProcessExit (3);
|
|
|
|
if (!process->isRunning ())
|
|
|
|
break;
|
|
|
|
process->kill (SIGTERM);
|
|
|
|
TDEProcessController::theTDEProcessController->waitForProcessExit (1);
|
|
|
|
if (!process->isRunning ())
|
|
|
|
break;
|
|
|
|
process->kill (SIGKILL);
|
|
|
|
TDEProcessController::theTDEProcessController->waitForProcessExit (1);
|
|
|
|
if (process->isRunning ()) {
|
|
|
|
return false; // give up
|
|
|
|
}
|
|
|
|
} while (false);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
KDE_NO_CDTOR_EXPORT KMPlayerBroadcastConfig::KMPlayerBroadcastConfig (KMPlayer::PartBase * player, KMPlayerFFServerConfig * fsc)
|
|
|
|
: m_player (player),
|
|
|
|
m_ffserverconfig (fsc),
|
|
|
|
m_ffmpeg_process (0L),
|
|
|
|
m_ffserver_process (0L),
|
|
|
|
m_endserver (true) {
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_CDTOR_EXPORT KMPlayerBroadcastConfig::~KMPlayerBroadcastConfig () {
|
|
|
|
stopServer ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void KMPlayerBroadcastConfig::write (TDEConfig * config) {
|
|
|
|
config->setGroup (strBroadcast);
|
|
|
|
config->writeEntry (strFFServerCustomSetting, ffserversettings.list (), ';');
|
|
|
|
TQStringList sl;
|
|
|
|
for (int i = 0; i < (int) ffserversettingprofiles.size (); i++) {
|
|
|
|
sl.push_back (ffserversettingprofiles[i]->name);
|
|
|
|
config->writeEntry (TQString ("Profile_") + ffserversettingprofiles[i]->name, ffserversettingprofiles[i]->list(), ';');
|
|
|
|
}
|
|
|
|
config->writeEntry (strFFServerProfiles, sl, ';');
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void KMPlayerBroadcastConfig::read (TDEConfig * config) {
|
|
|
|
std::for_each (ffserversettingprofiles.begin (), ffserversettingprofiles.end (), KMPlayer::Deleter<FFServerSetting>());
|
|
|
|
ffserversettingprofiles.clear ();
|
|
|
|
config->setGroup (strBroadcast);
|
|
|
|
ffserversettings = config->readListEntry (strFFServerCustomSetting, ';');
|
|
|
|
TQStringList profiles = config->readListEntry (strFFServerProfiles, ';');
|
|
|
|
TQStringList::iterator pr_it = profiles.begin ();
|
|
|
|
TQStringList::iterator pr_end( profiles.end () );
|
|
|
|
for (; pr_it != pr_end; ++pr_it) {
|
|
|
|
TQStringList sl = config->readListEntry (TQString ("Profile_") + *pr_it, ';');
|
|
|
|
if (sl.size () > 10) {
|
|
|
|
FFServerSetting * ffs = new FFServerSetting (sl);
|
|
|
|
ffs->name = *pr_it;
|
|
|
|
ffserversettingprofiles.push_back (ffs);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void KMPlayerBroadcastConfig::sync (bool fromUI) {
|
|
|
|
if (fromUI) {
|
|
|
|
m_configpage->getSettings(ffserversettings);
|
|
|
|
} else {
|
|
|
|
m_configpage->setSettings (ffserversettings);
|
|
|
|
m_configpage->profile->setText (TQString ());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void KMPlayerBroadcastConfig::prefLocation (TQString & item, TQString & icon, TQString & tab) {
|
|
|
|
item = i18n ("Broadcasting");
|
|
|
|
icon = TQString ("share");
|
|
|
|
tab = i18n ("Profiles");
|
|
|
|
}
|
|
|
|
|
|
|
|
TQFrame * KMPlayerBroadcastConfig::prefPage (TQWidget * parent) {
|
|
|
|
if (!m_configpage) {
|
|
|
|
m_configpage = new KMPlayerPrefBroadcastFormatPage (parent, ffserversettingprofiles);
|
|
|
|
connect (m_configpage->startbutton, TQT_SIGNAL (clicked ()), this, TQT_SLOT (startServer ()));
|
|
|
|
connect (m_player, TQT_SIGNAL (sourceChanged (KMPlayer::Source *, KMPlayer::Source *)), this, TQT_SLOT (sourceChanged (KMPlayer::Source *,KMPlayer::Source *)));
|
|
|
|
m_configpage->startbutton->setEnabled
|
|
|
|
(!m_player->source ()->videoDevice ().isEmpty ());
|
|
|
|
}
|
|
|
|
return m_configpage;
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT bool KMPlayerBroadcastConfig::broadcasting () const {
|
|
|
|
return m_ffserver_process && m_ffserver_process->isRunning ();
|
|
|
|
}
|
|
|
|
#include <tdeglobal.h>
|
|
|
|
#include <kstandarddirs.h>
|
|
|
|
|
|
|
|
static const char ffserverconf[] =
|
|
|
|
"Port %d\nBindAddress %s\nMaxClients %d\nMaxBandwidth %d\n"
|
|
|
|
"CustomLog -\nNoDaemon\n"
|
|
|
|
"<Feed kmplayer.ffm>\nFile %s\nFileMaxSize %dK\nACL allow 127.0.0.1\n</Feed>\n"
|
|
|
|
"<Stream video.%s>\nFeed kmplayer.ffm\n%s\n%s%s\n</Stream>\n"
|
|
|
|
"<Stream stat.html>\nFormat status\nACL allow localhost\n</Stream>\n";
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void KMPlayerBroadcastConfig::startServer () {
|
|
|
|
if (broadcasting ()) {
|
|
|
|
stopServer ();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
m_configpage->setCursor (TQCursor (TQt::WaitCursor));
|
|
|
|
m_ffserver_process = new TDEProcess;
|
|
|
|
m_ffserver_process->setUseShell (true);
|
|
|
|
connect (m_ffserver_process, TQT_SIGNAL (processExited (TDEProcess *)),
|
|
|
|
this, TQT_SLOT (processStopped (TDEProcess *)));
|
|
|
|
TQString conffile = locateLocal ("data", "kmplayer/ffserver.conf");
|
|
|
|
const char * noaudio = m_player->source ()->audioDevice ().isEmpty () ? "NoAudio" : "";
|
|
|
|
FFServerSetting ffs;
|
|
|
|
m_configpage->getSettings (ffs);
|
|
|
|
TQString acl;
|
|
|
|
TQStringList::iterator it = ffs.acl.begin ();
|
|
|
|
TQStringList::iterator end( ffs.acl.end () );
|
|
|
|
for (; it != end; ++it)
|
|
|
|
acl += TQString ("ACL allow ") + *it + TQString ("\n");
|
|
|
|
unlink (m_ffserverconfig->feedfile.ascii ());
|
|
|
|
TQFile qfile (conffile);
|
|
|
|
qfile.open (IO_WriteOnly);
|
|
|
|
TQString configdata;
|
|
|
|
TQString buf;
|
|
|
|
configdata.sprintf (ffserverconf, m_ffserverconfig->ffserverport, m_ffserverconfig->bindaddress.ascii (), m_ffserverconfig->maxclients, m_ffserverconfig->maxbandwidth, m_ffserverconfig->feedfile.ascii (), m_ffserverconfig->feedfilesize, ffs.format.ascii (), acl.ascii (), ffs.ffconfig (buf).ascii (), noaudio);
|
|
|
|
qfile.writeBlock (configdata.ascii (), configdata.length ());
|
|
|
|
qfile.close ();
|
|
|
|
kdDebug () << configdata << endl;
|
|
|
|
kdDebug () << "ffserver -f " << conffile << endl;
|
|
|
|
*m_ffserver_process << "ffserver -f " << conffile;
|
|
|
|
m_ffserver_out.truncate (0);
|
|
|
|
connect (m_ffserver_process,
|
|
|
|
TQT_SIGNAL (receivedStderr (TDEProcess *, char *, int)),
|
|
|
|
this, TQT_SLOT (processOutput (TDEProcess *, char *, int)));
|
|
|
|
m_ffserver_process->start (TDEProcess::NotifyOnExit, TDEProcess::Stderr);
|
|
|
|
if (m_ffserver_process->isRunning ()) {
|
|
|
|
m_configpage->startbutton->setText (i18n ("Stop"));
|
|
|
|
m_configpage->serverled->setState (KLed::On);
|
|
|
|
emit broadcastStarted ();
|
|
|
|
}
|
|
|
|
TQTimer::singleShot (500, this, TQT_SLOT (startFeed ()));
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void KMPlayerBroadcastConfig::stopServer () {
|
|
|
|
m_endserver = true;
|
|
|
|
if (m_ffmpeg_process)
|
|
|
|
m_ffmpeg_process->stop ();
|
|
|
|
if (!stopProcess (m_ffserver_process))
|
|
|
|
KMessageBox::error (m_configpage, i18n ("Failed to end ffserver process."), i18n ("Error"));
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void KMPlayerBroadcastConfig::processOutput (TDEProcess * p, char * s, int) {
|
|
|
|
if (p == m_ffserver_process)
|
|
|
|
m_ffserver_out += TQString (s);
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void KMPlayerBroadcastConfig::startFeed () {
|
|
|
|
if (!m_configpage) {
|
|
|
|
stopServer ();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
FFServerSetting ffs;
|
|
|
|
m_configpage->getSettings (ffs);
|
|
|
|
TQString ffurl;
|
|
|
|
if (!m_ffserver_process || !m_ffserver_process->isRunning ()) {
|
|
|
|
KMessageBox::error (m_configpage, i18n ("Failed to start ffserver.\n") + m_ffserver_out, i18n ("Error"));
|
|
|
|
goto bail_out;
|
|
|
|
}
|
|
|
|
disconnect (m_ffserver_process, TQT_SIGNAL (receivedStderr (TDEProcess *, char *, int)),
|
|
|
|
this, TQT_SLOT (processOutput (TDEProcess *, char *, int)));
|
|
|
|
if (m_ffmpeg_process)
|
|
|
|
m_ffmpeg_process->stop ();
|
|
|
|
delete m_ffmpeg_process;
|
|
|
|
m_ffmpeg_process = new KMPlayer::FFMpeg (m_player, m_player->settings ());
|
|
|
|
connect (m_ffmpeg_process, TQT_SIGNAL (stateChange (KMPlayer::Process::State, KMPlayer::Process::State)), this, TQT_SLOT (stateChange (KMPlayer::Process::State, KMPlayer::Process::State)));
|
|
|
|
ffurl.sprintf ("http://localhost:%d/kmplayer.ffm", m_ffserverconfig->ffserverport);
|
|
|
|
m_ffmpeg_process->setURL (KURL(ffurl));
|
|
|
|
if (!m_ffmpeg_process->play (m_player->source (), KMPlayer::NodePtr())) {
|
|
|
|
KMessageBox::error (m_configpage, i18n ("Failed to start ffmpeg."), i18n ("Error"));
|
|
|
|
stopProcess (m_ffserver_process);
|
|
|
|
goto bail_out;
|
|
|
|
}
|
|
|
|
if (m_ffmpeg_process->playing ()) {
|
|
|
|
m_ffserver_url.sprintf ("http://localhost:%d/video.%s", m_ffserverconfig->ffserverport, ffs.format.ascii ());
|
|
|
|
m_endserver = false;
|
|
|
|
m_configpage->feedled->setState (KLed::On);
|
|
|
|
m_player->openURL (KURL (m_ffserver_url));
|
|
|
|
} else
|
|
|
|
stopServer ();
|
|
|
|
bail_out:
|
|
|
|
m_configpage->setCursor (TQCursor (TQt::ArrowCursor));
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void KMPlayerBroadcastConfig::stateChange (KMPlayer::Process::State old, KMPlayer::Process::State state) {
|
|
|
|
if (state < KMPlayer::Process::Buffering && old >KMPlayer::Process::Ready) {
|
|
|
|
if (m_configpage)
|
|
|
|
m_configpage->feedled->setState (KLed::Off);
|
|
|
|
m_ffmpeg_process->deleteLater ();
|
|
|
|
m_ffmpeg_process = 0L;
|
|
|
|
kdDebug () << "ffmpeg process stopped " << m_endserver << endl;
|
|
|
|
if (m_endserver && !stopProcess (m_ffserver_process)) {
|
|
|
|
disconnect (m_ffserver_process,
|
|
|
|
TQT_SIGNAL (receivedStderr (TDEProcess *, char *, int)),
|
|
|
|
this, TQT_SLOT (processOutput (TDEProcess *, char *, int)));
|
|
|
|
KMessageBox::error (m_configpage, i18n ("Failed to end ffserver process."), i18n ("Error"));
|
|
|
|
processStopped (0L);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void KMPlayerBroadcastConfig::processStopped (TDEProcess *) {
|
|
|
|
kdDebug () << "ffserver process stopped" << endl;
|
|
|
|
if (m_configpage) {
|
|
|
|
m_configpage->serverled->setState (KLed::Off);
|
|
|
|
m_configpage->startbutton->setText (i18n ("Start"));
|
|
|
|
m_configpage->startbutton->setEnabled
|
|
|
|
(!m_player->source ()->videoDevice ().isEmpty ());
|
|
|
|
}
|
|
|
|
m_ffserver_process->deleteLater ();
|
|
|
|
m_ffserver_process = 0L;
|
|
|
|
emit broadcastStopped ();
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void KMPlayerBroadcastConfig::sourceChanged (KMPlayer::Source *, KMPlayer::Source * source) {
|
|
|
|
if (m_configpage)
|
|
|
|
m_configpage->startbutton->setEnabled (broadcasting () || (source && !source->videoDevice ().isEmpty ()));
|
|
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
KDE_NO_CDTOR_EXPORT KMPlayerFFServerConfig::KMPlayerFFServerConfig () {
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void KMPlayerFFServerConfig::write (TDEConfig * config) {
|
|
|
|
config->setGroup (strBroadcast);
|
|
|
|
config->writeEntry (strBindAddress, bindaddress);
|
|
|
|
config->writeEntry (strFFServerPort, ffserverport);
|
|
|
|
config->writeEntry (strMaxClients, maxclients);
|
|
|
|
config->writeEntry (strMaxBandwidth, maxbandwidth);
|
|
|
|
config->writePathEntry (strFeedFile, feedfile);
|
|
|
|
config->writeEntry (strFeedFileSize, feedfilesize);
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void KMPlayerFFServerConfig::read (TDEConfig * config) {
|
|
|
|
config->setGroup (strBroadcast);
|
|
|
|
bindaddress = config->readEntry (strBindAddress, "0.0.0.0");
|
|
|
|
ffserverport = config->readNumEntry (strFFServerPort, 8090);
|
|
|
|
maxclients = config->readNumEntry (strMaxClients, 10);
|
|
|
|
maxbandwidth = config->readNumEntry (strMaxBandwidth, 1000);
|
|
|
|
feedfile = config->readPathEntry (strFeedFile, "/tmp/kmplayer.ffm");
|
|
|
|
feedfilesize = config->readNumEntry (strFeedFileSize, 512);
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void KMPlayerFFServerConfig::sync (bool fromUI) {
|
|
|
|
if (fromUI) {
|
|
|
|
bindaddress = m_configpage->bindaddress->text ();
|
|
|
|
ffserverport = m_configpage->port->text ().toInt ();
|
|
|
|
maxclients = m_configpage->maxclients->text ().toInt ();
|
|
|
|
maxbandwidth = m_configpage->maxbandwidth->text ().toInt();
|
|
|
|
feedfile = m_configpage->feedfile->text ();
|
|
|
|
feedfilesize = m_configpage->feedfilesize->text ().toInt();
|
|
|
|
} else {
|
|
|
|
m_configpage->bindaddress->setText (bindaddress);
|
|
|
|
m_configpage->port->setText (TQString::number (ffserverport));
|
|
|
|
m_configpage->maxclients->setText (TQString::number (maxclients));
|
|
|
|
m_configpage->maxbandwidth->setText (TQString::number (maxbandwidth));
|
|
|
|
m_configpage->feedfile->setText (feedfile);
|
|
|
|
m_configpage->feedfilesize->setText (TQString::number (feedfilesize));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT void KMPlayerFFServerConfig::prefLocation (TQString & item, TQString & icon, TQString & tab) {
|
|
|
|
item = i18n ("Broadcasting");
|
|
|
|
icon = TQString ("share");
|
|
|
|
tab = i18n ("FFServer");
|
|
|
|
}
|
|
|
|
|
|
|
|
KDE_NO_EXPORT TQFrame *KMPlayerFFServerConfig::prefPage (TQWidget * parent) {
|
|
|
|
if (!m_configpage)
|
|
|
|
m_configpage = new KMPlayerPrefBroadcastPage (parent);
|
|
|
|
return m_configpage;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#include "kmplayerbroadcast.moc"
|