0f11f9df6e5e705c988ffd5f872ff22dce1da9f9
[someplayer] / src / player / player.cpp
1 #include "player.h"
2 #include <phonon/MediaSource>
3
4 using namespace SomePlayer::Playback;
5 using namespace SomePlayer::DataObjects;
6
7 Player::Player(QObject *parent) :
8     QObject(parent)
9 {
10         _player = new Phonon::MediaObject(this);
11         _output = new Phonon::AudioOutput(Phonon::MusicCategory, this);
12         _player->setTickInterval(1000);
13         connect(_player, SIGNAL(stateChanged(Phonon::State,Phonon::State)), this, SLOT(_stateChanged(Phonon::State,Phonon::State)));
14         connect(_player, SIGNAL(tick(qint64)), this, SLOT(_tick(qint64)));
15         Phonon::createPath(_player, _output);
16         int seed = reinterpret_cast<int> (_player);
17         qsrand(seed);
18         _random = false;
19         _repeat = false;
20         _current = -1;
21 }
22
23 void Player::setTrackId(int id) {
24         _current = id;
25         if (!_history.isEmpty() && _history.top() != _current || _history.isEmpty()) {
26                 _history.push(_current);
27         }
28         _track = _playlist.tracks().at(_current);
29         _set_source();
30         _state = PLAYER_LOADING;
31         emit stateChanged(_state);
32 }
33
34 void Player::toggle() {
35         if (_state == PLAYER_PLAYING) { // pause
36                 _player->pause();
37                 _state = PLAYER_PAUSED;
38                 emit stateChanged(_state);
39         } else { //play
40                 play();
41         }
42 }
43
44 void Player::stop() {
45         _player->stop();
46         _state = PLAYER_STOPPED;
47         emit stateChanged(_state);
48 }
49
50 void Player::next() {
51         int count = _playlist.tracks().count();
52         if (count == 0) {
53                 stop(); // empty playlist
54                 return;
55         }
56         _history.push(_current % count);
57         if (!_queue.isEmpty()) {
58                 _current = _queue.dequeue();
59         } else if (!_prev_history.isEmpty()) {
60                 _current = _prev_history.pop();
61         } else {
62                 if (_random) {
63                         _current = (count + (qrand()  + qrand() + qrand()) % count) % count;
64                 } else {
65                         _current = _current + 1;
66                 }
67         }
68         if (_random && _history.count() >= count && !_repeat ||
69                 !_repeat && _current >= count) {
70                 _history.clear();
71                 stop();
72         } else {
73                 _current %= count;
74                 _track = _playlist.tracks().at(_current);
75                 _set_source();
76                 play();
77         }
78 }
79
80 void Player::_set_source() {
81         _player->setCurrentSource(Phonon::MediaSource(_track.source()));
82         emit trackChanged(_track);
83 }
84
85 void Player::prev() {
86         if (_history.count() > 0) {
87                 _prev_history.push(_current);
88                 _current = _history.pop();
89                 _track = _playlist.tracks().at(_current);
90         }
91         _set_source();
92         play();
93 }
94
95 void Player::_stateChanged(Phonon::State newState, Phonon::State oldState) {
96         switch (newState) {
97         case Phonon::PlayingState:
98                 if (_state == PLAYER_LOADING) {
99                         _state = PLAYER_PLAYING;
100                         emit stateChanged(_state);
101                 }
102                 break;
103         case Phonon::StoppedState:
104                 break;
105         case Phonon::LoadingState:
106                 break;
107         case Phonon::PausedState:
108                 if (_state == PLAYER_PLAYING) {
109                         next();
110                 } else if (_state == PLAYER_ERROR) {
111                         play();
112                 }
113                 break;
114         case Phonon::BufferingState:
115                 break;
116         case Phonon::ErrorState:
117                 _state = PLAYER_ERROR;
118                 qDebug() << _player->errorString();
119                 break;
120         }
121 }
122
123 void Player::_tick(qint64 ticks) {
124         int done = ticks/1000;
125         int all = _track.metadata().length();
126         emit tick(done, all);
127         if (done+2 == all) {
128                 _track.setCount(_track.count()+1);
129                 emit trackDone(_track);
130         }
131 }
132
133 void Player::setPlaylist(Playlist playlist) {
134         _playlist = playlist;
135         _history.clear();
136 }
137
138 void Player::seek(int s) {
139         _player->seek(s*1000);
140 }
141
142 void Player::play() {
143         _state = PLAYER_PLAYING;
144         emit stateChanged(_state);
145         if (_current == -1) {
146                 _current = 0;
147                 _track = _playlist.tracks().at(0);
148                 _set_source();
149         }
150         _player->play();
151 }
152
153 void Player::enqueue(int id) {
154         _queue.enqueue(id);
155 }