/* this file is part of the kmplayer application copyright (c) 2003 koos vriezen 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #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 *tqparent) : TQFrame (tqparent) { TQVBoxLayout *tqlayout = new TQVBoxLayout (this, 5); TQGridLayout *gridtqlayout = new TQGridLayout (tqlayout, 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")); gridtqlayout->addWidget (label, 0, 0); gridtqlayout->addWidget (bindaddress, 0, 1); label = new TQLabel (i18n ("Listen port:"), this); port = new TQLineEdit ("", this); gridtqlayout->addWidget (label, 1, 0); gridtqlayout->addWidget (port, 1, 1); label = new TQLabel (i18n ("Maximum connections:"), this); maxclients = new TQLineEdit ("", this); gridtqlayout->addWidget (label, 2, 0); gridtqlayout->addWidget (maxclients, 2, 1); label = new TQLabel (i18n ("Maximum bandwidth (kbit):"), this); maxbandwidth = new TQLineEdit ("", this); gridtqlayout->addWidget (label, 3, 0); gridtqlayout->addWidget (maxbandwidth, 3, 1); label = new TQLabel (i18n ("Temporary feed file:"), this); feedfile = new TQLineEdit ("", this); gridtqlayout->addWidget (label, 4, 0); gridtqlayout->addWidget (feedfile, 4, 1); label = new TQLabel (i18n ("Feed file size (kB):"), this); feedfilesize = new TQLineEdit ("", this); gridtqlayout->addWidget (label, 5, 0); gridtqlayout->addWidget (feedfilesize, 5, 1); tqlayout->addItem (new TQSpacerItem (0, 0, TQSizePolicy::Minimum, TQSizePolicy::Expanding)); } //----------------------------------------------------------------------------- #undef ADDPROPERTY #define ADDPROPERTY(label,qedit,gridtqlayout,row,tqparent) \ qedit = new TQLineEdit ("", tqparent); \ gridtqlayout->addWidget (new TQLabel (qedit, label, tqparent), row, 0); \ gridtqlayout->addWidget (qedit, row, 1); KDE_NO_CDTOR_EXPORT KMPlayerPrefBroadcastFormatPage::KMPlayerPrefBroadcastFormatPage (TQWidget *tqparent, FFServerSettingList & ffs) : TQFrame (tqparent, "BroadcastPage"), profiles (ffs) { TQHBoxLayout *tqlayout = new TQHBoxLayout (this, 5); TQGridLayout *formattqlayout = new TQGridLayout (11, 2, 2); formattqlayout->tqsetAlignment (TQt::AlignTop); TQVBoxLayout *lefttqlayout = new TQVBoxLayout (15); TQHBoxLayout *ledtqlayout = 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")); formattqlayout->addWidget (label, 0, 0); formattqlayout->addWidget (format, 0, 1); ADDPROPERTY (i18n ("Audio codec:"), audiocodec, formattqlayout, 1, this); ADDPROPERTY (i18n ("Audio bit rate (kbit):"), audiobitrate, formattqlayout, 2, this); ADDPROPERTY (i18n ("Audio sample rate (Hz):"), audiosamplerate, formattqlayout, 3, this); ADDPROPERTY (i18n ("Video codec:"), videocodec, formattqlayout, 4, this); ADDPROPERTY (i18n ("Video bit rate (kbit):"), videobitrate, formattqlayout, 5, this); ADDPROPERTY (i18n ("Quality (1-31):"), quality, formattqlayout, 6, this); ADDPROPERTY (i18n ("Frame rate (Hz):"), framerate, formattqlayout, 7, this); ADDPROPERTY (i18n ("Gop size:"), gopsize, formattqlayout, 8, this); ADDPROPERTY (i18n ("Width (pixels):"), moviewidth, formattqlayout, 9, this); ADDPROPERTY (i18n ("Height (pixels):"), movieheight, formattqlayout, 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 *profilestqlayout = 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 ())); profilestqlayout->addWidget (profile, 0, 0); profilestqlayout->setRowSpacing (4, 60); profilestqlayout->addMultiCellWidget (profilelist, 1, 4, 0, 0); profilestqlayout->addWidget (load, 1, 1); profilestqlayout->addWidget (save, 2, 1); profilestqlayout->addWidget (del, 3, 1); lefttqlayout->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); ledtqlayout->addWidget (startbutton); ledtqlayout->addItem (new TQSpacerItem (0, 0, TQSizePolicy::Expanding, TQSizePolicy::Minimum)); ledtqlayout->addWidget (serverled); ledtqlayout->addWidget (feedled); lefttqlayout->addLayout (ledtqlayout); TQFrame * line = new TQFrame (this); line->setFrameShape (TQFrame::HLine); lefttqlayout->addWidget (line); lefttqlayout->addWidget (label); lefttqlayout->addWidget (accesslist); lefttqlayout->addItem (new TQSpacerItem (0, 0, TQSizePolicy::Minimum, TQSizePolicy::Expanding)); tqlayout->addLayout (lefttqlayout); line = new TQFrame (this); line->setFrameShape (TQFrame::VLine); tqlayout->addWidget (line); tqlayout->addLayout (formattqlayout); tqlayout->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 (KProcess * process, const char * cmd = 0L) { if (!process || !process->isRunning ()) return true; do { if (cmd) process->writeStdin (cmd, strlen (cmd)); KProcessController::theKProcessController->waitForProcessExit (1); if (!process->isRunning ()) break; process->kill (SIGINT); KProcessController::theKProcessController->waitForProcessExit (3); if (!process->isRunning ()) break; process->kill (SIGTERM); KProcessController::theKProcessController->waitForProcessExit (1); if (!process->isRunning ()) break; process->kill (SIGKILL); KProcessController::theKProcessController->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 (KConfig * 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 (KConfig * config) { std::for_each (ffserversettingprofiles.begin (), ffserversettingprofiles.end (), KMPlayer::Deleter()); 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 * tqparent) { if (!m_configpage) { m_configpage = new KMPlayerPrefBroadcastFormatPage (tqparent, 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 #include static const char ffserverconf[] = "Port %d\nBindAddress %s\nMaxClients %d\nMaxBandwidth %d\n" "CustomLog -\nNoDaemon\n" "\nFile %s\nFileMaxSize %dK\nACL allow 127.0.0.1\n\n" "\nFeed kmplayer.ffm\n%s\n%s%s\n\n" "\nFormat status\nACL allow localhost\n\n"; KDE_NO_EXPORT void KMPlayerBroadcastConfig::startServer () { if (broadcasting ()) { stopServer (); return; } m_configpage->setCursor (TQCursor (TQt::WaitCursor)); m_ffserver_process = new KProcess; m_ffserver_process->setUseShell (true); connect (m_ffserver_process, TQT_SIGNAL (processExited (KProcess *)), this, TQT_SLOT (processStopped (KProcess *))); 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 (KProcess *, char *, int)), this, TQT_SLOT (processOutput (KProcess *, char *, int))); m_ffserver_process->start (KProcess::NotifyOnExit, KProcess::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 (KProcess * 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 (KProcess *, char *, int)), this, TQT_SLOT (processOutput (KProcess *, 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 (KProcess *, char *, int)), this, TQT_SLOT (processOutput (KProcess *, char *, int))); KMessageBox::error (m_configpage, i18n ("Failed to end ffserver process."), i18n ("Error")); processStopped (0L); } } } KDE_NO_EXPORT void KMPlayerBroadcastConfig::processStopped (KProcess *) { 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 (KConfig * 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 (KConfig * 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 * tqparent) { if (!m_configpage) m_configpage = new KMPlayerPrefBroadcastPage (tqparent); return m_configpage; } #include "kmplayerbroadcast.moc"