7eecd0eaffbc4b1697b72007615c5fada576a2d4
[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 }
21
22 void Player::setTrackId(int id) {
23         _current = id;
24         if (!_history.isEmpty() && _history.top() != _current || _history.isEmpty()) {
25                 _history.push(_current);
26         }
27         _track = _playlist.tracks().at(_current);
28         _set_source();
29         _state = PLAYER_LOADING;
30         emit stateChanged(_state);
31 }
32
33 void Player::toggle() {
34         if (_state == PLAYER_PLAYING) { // pause
35                 _player->pause();
36                 _state = PLAYER_PAUSED;
37                 emit stateChanged(_state);
38         } else { //play
39                 play();
40         }
41 }
42
43 void Player::stop() {
44         _player->stop();
45         _state = PLAYER_STOPPED;
46         emit stateChanged(_state);
47 }
48
49 void Player::next() {
50         int count = _playlist.tracks().count();
51         if (count == 0) {
52                 stop(); // empty playlist
53                 return;
54         }
55         _history.push(_current % count);
56         if (!_queue.isEmpty()) {
57                 _current = _queue.dequeue();
58         } else {
59                 if (_random) {
60                         _current = (count + (qrand()  + qrand() + qrand()) % count) % count;
61                 } else {
62                         _current = _current + 1;
63                 }
64         }
65         if (_random && _history.count() >= count && !_repeat ||
66                 !_repeat && _current >= count) {
67                 _history.clear();
68                 stop();
69         } else {
70                 _current %= count;
71                 _track = _playlist.tracks().at(_current);
72                 _set_source();
73                 play();
74         }
75 }
76
77 void Player::_set_source() {
78         _player->setCurrentSource(Phonon::MediaSource(_track.source()));
79         emit trackChanged(_track);
80 }
81
82 void Player::prev() {
83         if (_history.count() > 0) {
84                 _queue.push_front(_current);
85                 _current = _history.pop();
86                 _track = _playlist.tracks().at(_current);
87         }
88         _set_source();
89         play();
90 }
91
92 void Player::_stateChanged(Phonon::State newState, Phonon::State oldState) {
93         switch (newState) {
94         case Phonon::PlayingState:
95                 if (_state == PLAYER_LOADING) {
96                         _state = PLAYER_PLAYING;
97                         emit stateChanged(_state);
98                 }
99                 break;
100         case Phonon::StoppedState:
101                 break;
102         case Phonon::LoadingState:
103                 break;
104         case Phonon::PausedState:
105                 if (_state == PLAYER_PLAYING) {
106                         next();
107                 } else if (_state == PLAYER_ERROR) {
108                         play();
109                 }
110                 break;
111         case Phonon::BufferingState:
112                 break;
113         case Phonon::ErrorState:
114                 _state = PLAYER_ERROR;
115                 qDebug() << _player->errorString();
116                 break;
117         }
118 }
119
120 void Player::_tick(qint64 ticks) {
121         int done = ticks/1000;
122         int all = _track.metadata().length();
123         emit tick(done, all);
124         if (done+2 == all) {
125                 _track.setCount(_track.count()+1);
126                 emit trackDone(_track);
127         }
128 }
129
130 void Player::setPlaylist(Playlist playlist) {
131         _playlist = playlist;
132         _history.clear();
133 }
134
135 void Player::seek(int s) {
136         _player->seek(s*1000);
137 }
138
139 void Player::play() {
140         _player->play();
141         _state = PLAYER_PLAYING;
142         emit stateChanged(_state);
143 }
144
145 void Player::enqueue(int id) {
146         _queue.enqueue(id);
147 }