1 //===========================================
2 //  Lumina-DE source code
3 //  Copyright (c) 2015, Ken Moore
4 //  Available under the 3-clause BSD license
5 //  See the LICENSE file for full details
6 //===========================================
7 #include "MultimediaWidget.h"
8 #include "ui_MultimediaWidget.h"
9 
10 #include <QTimer>
11 
MultimediaWidget(QWidget * parent)12 MultimediaWidget::MultimediaWidget(QWidget *parent) : QWidget(parent), ui(new Ui::MultimediaWidget){
13   ui->setupUi(this); //load the designer file
14 
15   //Add in the special QMultimediaWidgets
16   mediaObj = new QMediaPlayer(this);
17     mediaObj->setVolume(100);
18     mediaObj->setNotifyInterval(500); //only every 1/2 second update
19   videoDisplay = new QVideoWidget(this);
20     videoDisplay->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
21     ui->videoLayout->addWidget(videoDisplay);
22     mediaObj->setVideoOutput(videoDisplay);
23     videoDisplay->setVisible(false);
24 
25   UpdateIcons();
26   UpdateText();
27 
28   //Connect the special signals/slots for the media object
29   connect(mediaObj, SIGNAL(durationChanged(qint64)), this, SLOT(playerDurationChanged(qint64)) );
30   connect(mediaObj, SIGNAL(seekableChanged(bool)), ui->playerSlider, SLOT(setEnabled(bool)) );
31   connect(mediaObj, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)), this, SLOT(playerStatusChanged(QMediaPlayer::MediaStatus)) );
32   connect(mediaObj, SIGNAL(positionChanged(qint64)), this, SLOT(playerTimeChanged(qint64)) );
33   connect(mediaObj, SIGNAL(stateChanged(QMediaPlayer::State)), this, SLOT(playerStateChanged(QMediaPlayer::State)) );
34   connect(mediaObj, SIGNAL(videoAvailableChanged(bool)), this, SLOT(playerVideoAvailable(bool)) );
35   connect(mediaObj, SIGNAL(error(QMediaPlayer::Error)), this, SLOT(playerError()) );
36 
37   //Disable some of the initial states
38   ui->tool_player_stop->setEnabled(false); //nothing to stop yet
39   ui->tool_player_pause->setVisible(false); //nothing to pause yet
40   ui->playerSlider->setEnabled(false); //nothing to seek yet
41 }
42 
~MultimediaWidget()43 MultimediaWidget::~MultimediaWidget(){
44 
45 }
46 
47 // ================
48 //    PUBLIC SLOTS
49 // ================
ClearPlaylist()50 void MultimediaWidget::ClearPlaylist(){
51   mediaObj->stop();
52   ui->combo_player_list->clear();
53 }
54 
LoadMultimedia(QList<LFileInfo> list)55 void MultimediaWidget::LoadMultimedia(QList<LFileInfo> list){
56   for(int i=0; i<list.length(); i++){
57     if(list[i].isAVFile()){ ui->combo_player_list->addItem(list[i].fileName(), list[i].absoluteFilePath() ); }
58   }
59 }
60 
Cleanup()61 void MultimediaWidget::Cleanup(){
62   mediaObj->stop(); //just make sure the player is stopped
63 }
64 
65 //Theme change functions
UpdateIcons()66 void MultimediaWidget::UpdateIcons(){
67   ui->tool_player_next->setIcon( LXDG::findIcon("media-skip-forward","") );
68   ui->tool_player_prev->setIcon( LXDG::findIcon("media-skip-backward","") );
69   ui->tool_player_pause->setIcon( LXDG::findIcon("media-playback-pause","") );
70   ui->tool_player_play->setIcon( LXDG::findIcon("media-playback-start","") );
71   ui->tool_player_stop->setIcon( LXDG::findIcon("media-playback-stop","") );
72 }
73 
UpdateText()74 void MultimediaWidget::UpdateText(){
75   ui->retranslateUi(this);
76 }
77 
78 
79 // =================
80 //       PRIVATE
81 // =================
msToText(qint64 ms)82 QString MultimediaWidget::msToText(qint64 ms){
83   QString disp;
84   if(ms>3600000){
85     disp.append( QString::number(ms/3600000)+":" );
86     ms = ms%3600000;
87   }
88   if(ms>60000){
89     disp.append( QString::number(ms/60000)+":" );
90     ms = ms%60000;
91   }else{
92     disp.append("0:");
93   }
94   if(ms>1000){
95     if(ms>=10000){ disp.append( QString::number(ms/1000) ); }
96     else{ disp.append( "0"+QString::number(ms/1000) ); }
97   }else{
98     disp.append("00");
99   }
100   return disp;
101 }
102 
103 // =================
104 //    PRIVATE SLOTS
105 // =================
playerStatusChanged(QMediaPlayer::MediaStatus stat)106 void MultimediaWidget::playerStatusChanged(QMediaPlayer::MediaStatus stat){
107   //Only use this for end-of-file detection - use the state detection otherwise
108   if(stat == QMediaPlayer::EndOfMedia){
109     if(!mediaObj->isMuted()){ playerFinished(); } //make sure it is not being seeked right now
110   }
111 }
112 
playerStateChanged(QMediaPlayer::State newstate)113 void MultimediaWidget::playerStateChanged(QMediaPlayer::State newstate){
114   //This function keeps track of updating the visuals of the player
115   bool running = false;
116   bool showVideo = false;
117   QString msg;
118   switch(newstate){
119     case QMediaPlayer::PlayingState:
120 	running=true;
121 	showVideo = mediaObj->isVideoAvailable();
122 	msg = "";//mediaObj->metaData(Phonon::TitleMetaData).join(" ");
123 	if(msg.simplified().isEmpty()){ msg = ui->combo_player_list->currentText(); }
124 	ui->label_player_novideo->setText(tr("Playing:")+"\n"+msg);
125 	break;
126     case QMediaPlayer::PausedState:
127 	showVideo=videoDisplay->isVisible(); //don't change the screen
128 	break;
129     case QMediaPlayer::StoppedState:
130 	ui->label_player_novideo->setText(tr("Stopped"));
131         break;
132   }
133   ui->tool_player_play->setVisible(!running);
134   ui->tool_player_pause->setVisible(running);
135   ui->tool_player_stop->setEnabled(running);
136   ui->label_player_novideo->setVisible(!showVideo);
137   videoDisplay->setVisible(showVideo);
138 }
139 
playerVideoAvailable(bool showVideo)140 void MultimediaWidget::playerVideoAvailable(bool showVideo){
141   ui->label_player_novideo->setVisible(!showVideo);
142   videoDisplay->setVisible(showVideo);
143 }
144 
playerDurationChanged(qint64 dur)145 void MultimediaWidget::playerDurationChanged(qint64 dur){
146     if(dur < 0){ return; } //not ready yet
147     ui->playerSlider->setMaximum(mediaObj->duration());
148     playerTTime = msToText(dur);
149 }
150 
playerTimeChanged(qint64 ctime)151 void MultimediaWidget::playerTimeChanged(qint64 ctime){
152   if(mediaObj->isMuted() || playerTTime.isEmpty() ){ return; } //currently being moved
153   ui->playerSlider->setSliderPosition(ctime);
154 }
155 
playerError()156 void MultimediaWidget::playerError(){
157   QString msg = QString(tr("Error Playing File: %1"));
158   msg = msg.arg( mediaObj->currentMedia().canonicalUrl().fileName() );
159   msg.append("\n"+mediaObj->errorString());
160   ui->label_player_novideo->setText(msg);
161 }
162 
playerFinished()163 void MultimediaWidget::playerFinished(){
164   if(ui->combo_player_list->currentIndex()<(ui->combo_player_list->count()-1) && ui->check_player_gotonext->isChecked()){
165     ui->combo_player_list->setCurrentIndex( ui->combo_player_list->currentIndex()+1 );
166     QTimer::singleShot(0,this,SLOT(on_tool_player_play_clicked()));
167   }else{
168     ui->label_player_novideo->setText(tr("Finished"));
169   }
170 }
171 
on_tool_player_play_clicked()172 void MultimediaWidget::on_tool_player_play_clicked(){
173   if(mediaObj->state()==QMediaPlayer::PausedState \
174       && mediaObj->currentMedia().canonicalUrl().fileName()==ui->combo_player_list->currentText() ){
175     mediaObj->play();
176   }else{
177     mediaObj->stop();
178     //Get the selected file path
179     QString filePath = ui->combo_player_list->currentData().toString();
180       mediaObj->setMedia( QUrl::fromLocalFile(filePath) );
181       playerTTime.clear();
182       ui->playerSlider->setEnabled(mediaObj->isSeekable());
183       mediaObj->play();
184   }
185 }
186 
on_combo_player_list_currentIndexChanged(int index)187 void MultimediaWidget::on_combo_player_list_currentIndexChanged(int index){
188   ui->tool_player_next->setEnabled( ui->combo_player_list->count() > (index+1) );
189   ui->tool_player_prev->setEnabled( (index-1) >= 0 );
190 }
191 
on_tool_player_next_clicked()192 void MultimediaWidget::on_tool_player_next_clicked(){
193   ui->combo_player_list->setCurrentIndex( ui->combo_player_list->currentIndex()+1);
194   if(mediaObj->state()!=QMediaPlayer::StoppedState){ on_tool_player_play_clicked(); }
195 }
196 
on_tool_player_prev_clicked()197 void MultimediaWidget::on_tool_player_prev_clicked(){
198   ui->combo_player_list->setCurrentIndex( ui->combo_player_list->currentIndex()-1);
199   if(mediaObj->state()!=QMediaPlayer::StoppedState){ on_tool_player_play_clicked(); }
200 }
201 
on_tool_player_pause_clicked()202 void MultimediaWidget::on_tool_player_pause_clicked(){
203   mediaObj->pause();
204 }
205 
on_tool_player_stop_clicked()206 void MultimediaWidget::on_tool_player_stop_clicked(){
207   mediaObj->stop();
208 }
209 
210 //Slider controls
on_playerSlider_sliderPressed()211 void MultimediaWidget::on_playerSlider_sliderPressed(){
212   mediaObj->setMuted(true);
213   mediaObj->pause();
214 }
on_playerSlider_sliderReleased()215 void MultimediaWidget::on_playerSlider_sliderReleased(){
216   if(mediaObj->state()==QMediaPlayer::PausedState){ mediaObj->play(); }
217   mediaObj->setMuted(false);
218 }
on_playerSlider_valueChanged(int val)219 void MultimediaWidget::on_playerSlider_valueChanged(int val){
220   ui->label_player_runstats->setText( msToText(val)+"/"+playerTTime );
221   if(mediaObj->isMuted()){ mediaObj->setPosition(val); } //currently seeking
222 }
223