add option -d in order to indicate the path to configuration files
[zik.git] / data / player.rb
blobb547b1a7455dea2a2501dcea36f1e2f1c9733ba4
1 =begin
2 Copyright 2007-2008 Vincent Carmona
4 This file is part of ZiK.
6     ZiK is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
11     ZiK is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
16     You should have received a copy of the GNU General Public License
17     along with ZiK; if not, write to the Free Software
18     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19 =end
20 class GstError < Exception
21 end
23 class Player
24         attr_accessor :current
25         attr_writer :repeat
26         attr_reader :order
27         def initialize(list,preference)
28                 @playlist=list.path
29                 @current=preference['current']
30                 @playing=false
31                 @radio=false
32                 @shuffle=preference['shuffle']
33                 if @shuffle
34                         @current=0
35                 end
36                 @repeat=preference['repeat']
37                 @order=[]
38                 for i in 0..@playlist.length-1
39                         @order.push(i)
40                 end
41                 if @shuffle
42                         @order=@order.sort_by{rand}
43                 end
44                 
45                 @playbin=Gst::ElementFactory.make('playbin')
46                 @playbin.ready
47                 
48                 if !@playlist[@current].nil?
49                         @playbin.uri='file://'+@playlist[@current]
50                 end
51                 @playbin.bus.add_watch { | message | got_bus_message(message) }
52         end
53         
54         def playing?
55                 @playing
56         end
57         
58         def radio?
59                 @radio
60         end
61         
62         def got_bus_message(message)
63                 case message.get_type
64                         when Gst::Message::MessageType::ERROR
65                                 $stderr.puts 'Gst error'
66                                 @playbin.stop
67                                 raise GstError.new if @radio
68                         when Gst::Message::MessageType::EOS
69                                 self.next_s
70                 end
71                 true #Without this line, only the first message is processed
72         end
73         
74         def add
75                 played=@order[0..@current]
76                 length=@order.length
77                 not_played=@order[@current+1..length-1]
78                 if not_played.nil?
79                         not_played=[]
80                 end
81                 for i in length..@playlist.length-1
82                         not_played.push(i)
83                 end
84                 if @shuffle
85                         not_played=not_played.sort_by{rand}                     
86                 end
87                 @order=played+not_played
88         end
89         
90         def del(select)
91                 select.each{|sel|
92                         i=0
93                         @order.each{|n|
94                                 case (n <=> sel)
95                                         when 0 then
96                                                 @order[i]=nil
97                                         when 1 then
98                                                 @order[i]-=1
99                                 end
100                                 i+=1
101                                 }
102                         @order.compact!
103                         case sel <=> @order[@current]
104                                 when 0 then
105                                         stop
106                                         play
107                                 when -1 then
108                                         @current-=1
109                                 when nil then#@order[@current] returns nil if playing the last song.
110                                         @current-=1
111                                         next_s if sel==@order[@current]+1#if deleting the last song
112                         end
113                         }
114         end
115         
116         def del_all
117                 stop
118                 @order.clear
119                 @current=0
120         end
121         
122         def toggle_shuffle#Jouer ou pas les chansons déjà jouées?
123                 @shuffle=!@shuffle
124                 if @shuffle
125                         @order=@order.sort_by{rand}
126                         temp=@order.index(@current)
127                         @current=temp
128                         @current=0 if @current.nil?
129                 else
130                         @current=@order[@current]
131                         @current=0 if @current.nil?
132                         @order.sort!
133                 end
134         end
136         def play(song=nil)
137                 begin
138                         @playing=true
139                         @radio=false
140                         if song.nil?
141                                 n=@order[@current]
142                         else
143                                 n=song
144                                 @current=@order.index(n)
145                         end
146                         name=@playlist[n]
147                         @playbin.uri='file://'+name
148                         @playbin.play
149                         puts "Playing... #{name}"
150                 rescue
151                         $stderr.puts "Error playing file://#{name}"
152                 end
153         end
154         
155         def play_radio(radio)
156                 begin
157                         @radio=true;@playing=true
158                         @playbin.stop
159                         @playbin.uri=radio
160                         @playbin.play
161                         puts "Playing... #{radio}"
162                         #puts @playbin.stream_info
163                 rescue
164                         $stderr.puts "Cannot play #{radio}"
165                 end
166         end
167         
168         def pause
169                 @playbin.pause
170                 puts 'Pause.'
171                 @playing=false
172         end
173         
174         def stop
175                 @playbin.stop
176                 @playing=false
177         end
178         
179         def next_s
180                 if @current < @playlist.length-1
181                         @current+=1
182                         stop
183                         play
184                 else
185                         if @repeat
186                                 @playbin.stop
187                                 @current=0
188                                 play
189                         else
190                                 puts 'End of playlist.'
191                                 stop
192                         end
193                 end
194         end
195         
196         def prev
197                 if @current > 0
198                         @current-=1
199                         @playbin.stop
200                         play
201                 else
202                         if @repeat
203                                 @playbin.stop
204                                 @current=@order.length-1
205                                 play
206                         else
207                         puts 'Begin of playlist.'
208                         end
209                 end
210         end
211         
212         def volume
213                 @playbin.volume
214         end
215         def volume=(n)
216                 @playbin.volume=n
217         end
218         def vol_up
219                 if @playbin.volume>0.9
220                         @playbin.volume=1
221                 else
222                         @playbin.volume+=0.1
223                 end
224         end
225         def vol_down
226                 if @playbin.volume<0.1
227                         @playbin.volume=0
228                 else
229                         @playbin.volume-=0.1
230                 end
231         end
232         
233         def position
234                 @playbin.query_position[1]/1000000000
235         end
236         
237         def position=(pos)
238                 @playbin.seek(1.0, Gst::Format::Type::TIME,Gst::Seek::FLAG_FLUSH.to_i | Gst::Seek::FLAG_KEY_UNIT.to_i,Gst::Seek::TYPE_SET,
239                 pos*1000000000,Gst::Seek::TYPE_NONE,-1)#Code from the Gst binding examples (cf:video-player)
240         end