00001
00034 #include "beedo.h"
00035
00036 #include <iostream>
00037 #include <stdexcept>
00038 #include <unistd.h>
00039 #include <QFile>
00040 #include <QIcon>
00041 #include <QLayout>
00042 #include <QTimer>
00043 #include <QUrl>
00044 #include <AudioOutput>
00045 #include <MediaObject>
00046 #include <MediaSource>
00047 #include <VideoWidget>
00048
00049 #include "exceptionhandler.h"
00050
00051 using namespace AlarmNotifications;
00052
00053 Beedo& Beedo::instance()
00054 {
00055
00056 static Beedo global_instance;
00057 return global_instance;
00058 }
00059
00060 Beedo::Beedo()
00061 : QObject ( nullptr ),
00062 _go ( false ),
00063 _display ( nullptr ),
00064 _audio ( nullptr ),
00065 _media ( nullptr ),
00066 _video ( nullptr )
00067 {
00068 #ifndef BEEDOOLDQTFALLBACK
00069 createMediaObjects();
00070 #else
00071 QFile videoresource ( QString::fromUtf8 ( ":/beedo.ogv" ) );
00072 videoresource.open ( QIODevice::ReadOnly );
00073 _videobuffer.open ( QIODevice::ReadWrite );
00074 _videobuffer.write ( videoresource.readAll() );
00075 _videobuffer.seek ( 0 );
00076 #endif
00077
00078 connect ( this, SIGNAL ( signalPlay() ), this, SLOT ( playAlarmVideo() ) );
00079 connect ( this, SIGNAL ( signalStop() ), this, SLOT ( stopAlarmVideo() ) );
00080 }
00081
00082 Beedo::~Beedo()
00083 {
00084 destroy();
00085
00086 }
00087
00088 void Beedo::createMediaObjects()
00089 {
00090 _display = new QWidget (
00091 nullptr,
00092 Qt::Widget |
00093 Qt::X11BypassWindowManagerHint |
00094 Qt::CustomizeWindowHint |
00095 Qt::WindowStaysOnTopHint
00096 );
00097 _media = new Phonon::MediaObject ( nullptr );
00098 _audio = new Phonon::AudioOutput ( Phonon::NotificationCategory, nullptr );
00099 _video = new Phonon::VideoWidget ( _display );
00100 _mediaToAudio = Phonon::createPath ( _media, _audio );
00101 _mediaToVideo = Phonon::createPath ( _media, _video );
00102 const QSize widgetsize ( 256, 256 );
00103 const QRect widgetrect ( QPoint ( 0,0 ),widgetsize );
00104 _display->setGeometry ( widgetrect );
00105 _display->setMinimumSize ( widgetsize );
00106 _display->setMinimumSize ( widgetsize );
00107 _video->setGeometry ( widgetrect );
00108 _video->setMinimumSize ( widgetsize );
00109 _video->setMaximumSize ( widgetsize );
00110 _display->setWindowIcon ( QIcon::fromTheme ( QString::fromUtf8 ( "dialog-warning" ) ) );
00111 connect ( _media, SIGNAL ( stateChanged ( Phonon::State,Phonon::State ) ), this, SLOT ( phononStateChange ( Phonon::State,Phonon::State ) ) );
00112 }
00113
00114 void Beedo::destroyMediaObjects()
00115 {
00116 if ( _media == nullptr || _audio == nullptr || _video == nullptr || _display == nullptr )
00117 return;
00118 _media->stop();
00119 _media->clearQueue();
00120 _media->clear();
00121 _mediaToAudio.disconnect();
00122 _mediaToVideo.disconnect();
00123 _video->hide();
00124 delete _display;
00125 _display = nullptr;
00126 delete _audio;
00127 _audio = nullptr;
00128 delete _media;
00129 _media = nullptr;
00130 }
00131
00132 void Beedo::destroy()
00133 {
00134 _go = false;
00135 destroyMediaObjects();
00136 }
00137
00138 void Beedo::start_internal() noexcept
00139 {
00140 try
00141 {
00142 if ( _go )
00143 return;
00144 _go = true;
00145 emit signalPlay();
00146 }
00147 catch ( std::exception& e )
00148 {
00149 ExceptionHandler ( e, "Beedo::start_internal()" );
00150 }
00151 catch ( ... )
00152 {
00153 ExceptionHandler ( "Beedo::start_internal()" );
00154 }
00155 }
00156
00157 void Beedo::stop_internal() noexcept
00158 {
00159 try
00160 {
00161 if ( !_go )
00162 return;
00163 _go = false;
00164 emit signalStop();
00165 }
00166 catch ( std::exception& e )
00167 {
00168 ExceptionHandler ( e, "Beedo::stop_internal()" );
00169 }
00170 catch ( ... )
00171 {
00172 ExceptionHandler ( "Beedo::stop_internal()" );
00173 }
00174 }
00175
00176 void Beedo::playAlarmVideo()
00177 {
00178 #ifdef BEEDOOLDQTFALLBACK
00179 destroyMediaObjects();
00180 createMediaObjects();
00181 #endif
00182
00183 #ifndef BEEDOOLDQTFALLBACK
00184 _media->setCurrentSource ( QUrl ( QString::fromUtf8 ( "qrc:/beedo.ogv" ) ) );
00185 #else
00186 _videobuffer.seek ( 0 );
00187 _media->setCurrentSource ( &_videobuffer );
00188 #endif
00189 #ifndef BEEDOOLDQTFALLBACK
00190 while ( _media->state() == Phonon::LoadingState )
00191 usleep ( 10*1000 );
00192 usleep ( 500*1000 );
00193 #else
00194
00195 usleep ( 750*1000 );
00196 #endif
00197 if ( !_media->isValid() )
00198 std::cout << "Cannot play \"Beedo\" video resource!" << std::endl;
00199 _display->show();
00200 _media->play();
00201 }
00202
00203 void Beedo::stopAlarmVideo()
00204 {
00205 _media->stop();
00206 }
00207
00208 void Beedo::phononStateChange ( const Phonon::State newState, const Phonon::State oldState )
00209 {
00210 if ( newState == Phonon::PlayingState && oldState != Phonon::PlayingState )
00211 _display->show();
00212 if ( newState != Phonon::PlayingState && oldState == Phonon::PlayingState && !_go )
00213 _display->hide();
00214 if ( newState != Phonon::PlayingState && oldState == Phonon::PlayingState && _go )
00215 QTimer::singleShot ( 0, this, SLOT ( playAlarmVideo() ) );
00216 }
00217
00218 #include "beedo.moc"