ruby-mpris 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/COPYING +56 -0
- data/NEWS +2 -0
- data/README +35 -0
- data/Rakefile +87 -0
- data/examples/capabilities_test.rb +23 -0
- data/examples/identify.rb +17 -0
- data/examples/metadata.rb +16 -0
- data/examples/play_track.rb +17 -0
- data/examples/playerkeys.rb +60 -0
- data/examples/status_test.rb +57 -0
- data/examples/tracklist.rb +42 -0
- data/examples/volume_test.rb +22 -0
- data/lib/mpris/player.rb +166 -0
- data/lib/mpris/tracklist.rb +100 -0
- data/lib/mpris.rb +106 -0
- metadata +77 -0
data/COPYING
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
ruby-mpris is copyrighted free software by Nicholas J Humfrey <njh@aelius.com>.
|
2
|
+
You can redistribute it and/or modify it under either the terms of the GPL
|
3
|
+
version 2 (see the file GPL), or the conditions below:
|
4
|
+
|
5
|
+
1. You may make and give away verbatim copies of the source form of the
|
6
|
+
software without restriction, provided that you duplicate all of the
|
7
|
+
original copyright notices and associated disclaimers.
|
8
|
+
|
9
|
+
2. You may modify your copy of the software in any way, provided that
|
10
|
+
you do at least ONE of the following:
|
11
|
+
|
12
|
+
a) place your modifications in the Public Domain or otherwise
|
13
|
+
make them Freely Available, such as by posting said
|
14
|
+
modifications to Usenet or an equivalent medium, or by allowing
|
15
|
+
the author to include your modifications in the software.
|
16
|
+
|
17
|
+
b) use the modified software only within your corporation or
|
18
|
+
organization.
|
19
|
+
|
20
|
+
c) give non-standard binaries non-standard names, with
|
21
|
+
instructions on where to get the original software distribution.
|
22
|
+
|
23
|
+
d) make other distribution arrangements with the author.
|
24
|
+
|
25
|
+
3. You may distribute the software in object code or binary form,
|
26
|
+
provided that you do at least ONE of the following:
|
27
|
+
|
28
|
+
a) distribute the binaries and library files of the software,
|
29
|
+
together with instructions (in the manual page or equivalent)
|
30
|
+
on where to get the original distribution.
|
31
|
+
|
32
|
+
b) accompany the distribution with the machine-readable source of
|
33
|
+
the software.
|
34
|
+
|
35
|
+
c) give non-standard binaries non-standard names, with
|
36
|
+
instructions on where to get the original software distribution.
|
37
|
+
|
38
|
+
d) make other distribution arrangements with the author.
|
39
|
+
|
40
|
+
4. You may modify and include the part of the software into any other
|
41
|
+
software (possibly commercial). But some files in the distribution
|
42
|
+
are not written by the author, so that they are not under these terms.
|
43
|
+
|
44
|
+
For the list of those files and their copying conditions, see the
|
45
|
+
file LEGAL.
|
46
|
+
|
47
|
+
5. The scripts and library files supplied as input to or produced as
|
48
|
+
output from the software do not automatically fall under the
|
49
|
+
copyright of the software, but belong to whomever generated them,
|
50
|
+
and may be sold commercially, and may be aggregated with this
|
51
|
+
software.
|
52
|
+
|
53
|
+
6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
|
54
|
+
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
55
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
56
|
+
PURPOSE.
|
data/README
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
== ruby-mpris
|
2
|
+
|
3
|
+
The ruby-mpris gem allows you to control media players that follow the MPRIS specification.
|
4
|
+
|
5
|
+
RubyForge Project Page http://rubyforge.org/projects/mpris/
|
6
|
+
|
7
|
+
== Dependancies
|
8
|
+
|
9
|
+
ruby-dbus performs all the hard work behind the scenes. You can download it from: http://trac.luon.net/ruby-dbus/
|
10
|
+
|
11
|
+
== Installing
|
12
|
+
|
13
|
+
You may get the latest stable version from Rubyforge. Source gems are also available.
|
14
|
+
|
15
|
+
$ gem install mpris
|
16
|
+
|
17
|
+
=== Loading ruby-mpris gem Itself
|
18
|
+
|
19
|
+
You have installed the gem already, yeah?
|
20
|
+
|
21
|
+
require 'rubygems'
|
22
|
+
require 'mpris'
|
23
|
+
|
24
|
+
|
25
|
+
== Resources
|
26
|
+
|
27
|
+
http://www.mpris.org
|
28
|
+
|
29
|
+
== Contact
|
30
|
+
|
31
|
+
Author:: Nicholas J Humfrey
|
32
|
+
Email:: njh@aelius.com
|
33
|
+
Home Page:: http://www.aelius.com/njh/
|
34
|
+
License:: Distributes under the same terms as Ruby
|
35
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/clean'
|
4
|
+
require 'rake/gempackagetask'
|
5
|
+
require 'rake/rdoctask'
|
6
|
+
require 'rake/testtask'
|
7
|
+
|
8
|
+
NAME = "ruby-mpris"
|
9
|
+
VERS = "0.1.0"
|
10
|
+
CLEAN.include ['pkg', 'rdoc']
|
11
|
+
|
12
|
+
Gem::manage_gems
|
13
|
+
|
14
|
+
spec = Gem::Specification.new do |s|
|
15
|
+
s.name = NAME
|
16
|
+
s.version = VERS
|
17
|
+
s.author = "Nicholas J Humfrey"
|
18
|
+
s.email = "njh@aelius.com"
|
19
|
+
s.homepage = "http://mpris.rubyforge.org"
|
20
|
+
s.platform = Gem::Platform::RUBY
|
21
|
+
s.summary = "A library to control MPRIS based Media Players"
|
22
|
+
s.rubyforge_project = "mpris"
|
23
|
+
s.description = "The mpris gem allows you to control media players that follow the MPRIS specification."
|
24
|
+
s.files = FileList["Rakefile", "lib/mpris.rb", "lib/mpris/*", "examples/*"]
|
25
|
+
s.require_path = "lib"
|
26
|
+
|
27
|
+
# rdoc
|
28
|
+
s.has_rdoc = true
|
29
|
+
s.extra_rdoc_files = ["README", "NEWS", "COPYING"]
|
30
|
+
|
31
|
+
# Dependencies
|
32
|
+
#s.add_dependency "ruby-dbus" - sadly ruby-dbus isn't avilable as a gem
|
33
|
+
s.add_dependency "rake"
|
34
|
+
end
|
35
|
+
|
36
|
+
desc "Default: package up the gem."
|
37
|
+
task :default => :package
|
38
|
+
|
39
|
+
task :build_package => [:repackage]
|
40
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
41
|
+
pkg.need_zip = false
|
42
|
+
pkg.need_tar = true
|
43
|
+
pkg.gem_spec = spec
|
44
|
+
end
|
45
|
+
|
46
|
+
desc "Run :package and install the resulting .gem"
|
47
|
+
task :install => :package do
|
48
|
+
sh %{sudo gem install --local pkg/#{NAME}-#{VERS}.gem}
|
49
|
+
end
|
50
|
+
|
51
|
+
desc "Run :clean and uninstall the .gem"
|
52
|
+
task :uninstall => :clean do
|
53
|
+
sh %{sudo gem uninstall #{NAME}}
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
|
58
|
+
## Testing
|
59
|
+
#desc "Run all the specification tests"
|
60
|
+
#Rake::TestTask.new(:spec) do |t|
|
61
|
+
# t.warning = true
|
62
|
+
# t.verbose = true
|
63
|
+
# t.pattern = 'spec/*_spec.rb'
|
64
|
+
#end
|
65
|
+
|
66
|
+
desc "Check the syntax of all ruby files"
|
67
|
+
task :check_syntax do
|
68
|
+
`find . -name "*.rb" |xargs -n1 ruby -c |grep -v "Syntax OK"`
|
69
|
+
puts "* Done"
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
|
74
|
+
## Documentation
|
75
|
+
desc "Generate documentation for the library"
|
76
|
+
Rake::RDocTask.new("rdoc") { |rdoc|
|
77
|
+
rdoc.rdoc_dir = 'rdoc'
|
78
|
+
rdoc.title = "ruby-mpris Documentation"
|
79
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
80
|
+
rdoc.main = "README"
|
81
|
+
rdoc.rdoc_files.include("README", "NEWS", "COPYING", "lib/mpris.rb", "lib/mpris/*.rb")
|
82
|
+
}
|
83
|
+
|
84
|
+
desc "Upload rdoc to rubyforge"
|
85
|
+
task :upload_rdoc => [:rdoc] do
|
86
|
+
sh %{/usr/bin/scp -r -p rdoc/* mpris.rubyforge.org:/var/www/gforge-projects/mpris}
|
87
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
#
|
3
|
+
# Script to display the cababilites of the media player.
|
4
|
+
#
|
5
|
+
# Author:: Nicholas J Humfrey (mailto:njh@aelius.com)
|
6
|
+
# Copyright:: Copyright (c) 2008 Nicholas J Humfrey
|
7
|
+
# License:: Distributes under the same terms as Ruby
|
8
|
+
#
|
9
|
+
|
10
|
+
$:.unshift File.dirname(__FILE__)+'/../lib'
|
11
|
+
|
12
|
+
require 'mpris'
|
13
|
+
|
14
|
+
|
15
|
+
mpris = Mpris.new
|
16
|
+
puts "Checking capabilites:"
|
17
|
+
puts " can_go_next?: #{mpris.player.can_go_next?}"
|
18
|
+
puts " can_go_prev?: #{mpris.player.can_go_prev?}"
|
19
|
+
puts " can_pause?: #{mpris.player.can_pause?}"
|
20
|
+
puts " can_play?: #{mpris.player.can_play?}"
|
21
|
+
puts " can_seek?: #{mpris.player.can_seek?}"
|
22
|
+
puts " can_provide_metadata?: #{mpris.player.can_provide_metadata?}"
|
23
|
+
puts " has_tracklist?: #{mpris.player.has_tracklist?}"
|
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
#
|
3
|
+
# Script to display name of the media player and supported MPRIS API version.
|
4
|
+
#
|
5
|
+
# Author:: Nicholas J Humfrey (mailto:njh@aelius.com)
|
6
|
+
# Copyright:: Copyright (c) 2008 Nicholas J Humfrey
|
7
|
+
# License:: Distributes under the same terms as Ruby
|
8
|
+
#
|
9
|
+
|
10
|
+
$:.unshift File.dirname(__FILE__)+'/../lib'
|
11
|
+
|
12
|
+
require 'mpris'
|
13
|
+
|
14
|
+
|
15
|
+
mpris = Mpris.new
|
16
|
+
puts "Identity: #{mpris.identity}"
|
17
|
+
puts "MPRIS API Version: #{mpris.mpris_version}"
|
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
#
|
3
|
+
# Script to display the metadata hash for the currently playing track.
|
4
|
+
#
|
5
|
+
# Author:: Nicholas J Humfrey (mailto:njh@aelius.com)
|
6
|
+
# Copyright:: Copyright (c) 2008 Nicholas J Humfrey
|
7
|
+
# License:: Distributes under the same terms as Ruby
|
8
|
+
#
|
9
|
+
|
10
|
+
$:.unshift File.dirname(__FILE__)+'/../lib'
|
11
|
+
|
12
|
+
require 'mpris'
|
13
|
+
require 'pp'
|
14
|
+
|
15
|
+
mpris = Mpris.new
|
16
|
+
pp mpris.player.metadata
|
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
#
|
3
|
+
# Script to immediately start playing a track in the media player.
|
4
|
+
#
|
5
|
+
# Author:: Nicholas J Humfrey (mailto:njh@aelius.com)
|
6
|
+
# Copyright:: Copyright (c) 2008 Nicholas J Humfrey
|
7
|
+
# License:: Distributes under the same terms as Ruby
|
8
|
+
#
|
9
|
+
|
10
|
+
$:.unshift File.dirname(__FILE__)+'/../lib'
|
11
|
+
|
12
|
+
require 'mpris'
|
13
|
+
|
14
|
+
raise "Usage: play_track.rb <filename>" unless (ARGV.size == 1)
|
15
|
+
|
16
|
+
mpris = Mpris.new
|
17
|
+
mpris.tracklist.add_track( ARGV[0], true )
|
@@ -0,0 +1,60 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
#
|
3
|
+
# Interactive console script to control the media player.
|
4
|
+
#
|
5
|
+
# Author:: Nicholas J Humfrey (mailto:njh@aelius.com)
|
6
|
+
# Copyright:: Copyright (c) 2008 Nicholas J Humfrey
|
7
|
+
# License:: Distributes under the same terms as Ruby
|
8
|
+
#
|
9
|
+
|
10
|
+
$:.unshift File.dirname(__FILE__)+'/../lib'
|
11
|
+
|
12
|
+
require 'rubygems'
|
13
|
+
require 'highline'
|
14
|
+
require 'mpris'
|
15
|
+
|
16
|
+
|
17
|
+
mpris = Mpris.new
|
18
|
+
|
19
|
+
puts "p:play space:pause s:stop [:prev ]:next q:quit"
|
20
|
+
puts "+:volume_up -:volume_down x:exit"
|
21
|
+
|
22
|
+
begin
|
23
|
+
c = HighLine::SystemExtensions::get_character
|
24
|
+
|
25
|
+
case c
|
26
|
+
when 112 then
|
27
|
+
puts "Play"
|
28
|
+
mpris.player.play
|
29
|
+
when 113 then
|
30
|
+
puts "Quit"
|
31
|
+
mpris.quit
|
32
|
+
when 32 then
|
33
|
+
puts "Pause"
|
34
|
+
mpris.player.pause
|
35
|
+
when 115 then
|
36
|
+
puts "Stop"
|
37
|
+
mpris.player.stop
|
38
|
+
when 91 then
|
39
|
+
puts "Previous"
|
40
|
+
mpris.player.previous
|
41
|
+
when 93 then
|
42
|
+
puts "Next"
|
43
|
+
mpris.player.next
|
44
|
+
when 43 then
|
45
|
+
vol = mpris.player.volume+5
|
46
|
+
puts "Volume Up (#{vol})"
|
47
|
+
mpris.player.volume = vol
|
48
|
+
when 45 then
|
49
|
+
vol = mpris.player.volume-5
|
50
|
+
puts "Volume Down (#{vol})"
|
51
|
+
mpris.player.volume = vol
|
52
|
+
when 114 then
|
53
|
+
repeat = !mpris.player.repeat
|
54
|
+
puts "Repeat=#{repeat}"
|
55
|
+
mpris.player.repeat = repeat
|
56
|
+
else
|
57
|
+
puts "Unhandled key press: #{c}"
|
58
|
+
end
|
59
|
+
|
60
|
+
end until (c == 120)
|
@@ -0,0 +1,57 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
#
|
3
|
+
# Script to test the repeat/loop/random getters and setters.
|
4
|
+
#
|
5
|
+
# Author:: Nicholas J Humfrey (mailto:njh@aelius.com)
|
6
|
+
# Copyright:: Copyright (c) 2008 Nicholas J Humfrey
|
7
|
+
# License:: Distributes under the same terms as Ruby
|
8
|
+
#
|
9
|
+
|
10
|
+
$:.unshift File.dirname(__FILE__)+'/../lib'
|
11
|
+
|
12
|
+
require 'mpris'
|
13
|
+
|
14
|
+
|
15
|
+
mpris = Mpris.new
|
16
|
+
|
17
|
+
|
18
|
+
puts "Enabling looping."
|
19
|
+
mpris.tracklist.loop = true
|
20
|
+
puts " Looping status: #{mpris.tracklist.loop}"
|
21
|
+
|
22
|
+
puts "Disabling looping."
|
23
|
+
mpris.tracklist.loop = false
|
24
|
+
puts " Looping status: #{mpris.tracklist.loop}"
|
25
|
+
|
26
|
+
puts "Enabling random."
|
27
|
+
mpris.tracklist.random = true
|
28
|
+
puts " Random status: #{mpris.tracklist.random}"
|
29
|
+
|
30
|
+
puts "Disabling random."
|
31
|
+
mpris.tracklist.random = false
|
32
|
+
puts " Random status: #{mpris.tracklist.random}"
|
33
|
+
|
34
|
+
puts "Enabling repeating."
|
35
|
+
mpris.player.repeat = true
|
36
|
+
puts " Looping status: #{mpris.player.repeat}"
|
37
|
+
|
38
|
+
puts "Disabling repeating."
|
39
|
+
mpris.player.repeat = false
|
40
|
+
puts " Looping status: #{mpris.player.repeat}"
|
41
|
+
|
42
|
+
|
43
|
+
puts "Stopping playback..."
|
44
|
+
mpris.player.stop
|
45
|
+
puts " Mpris::Player::STOPPED: #{Mpris::Player::STOPPED}"
|
46
|
+
puts " Playback status: #{mpris.player.status}"
|
47
|
+
|
48
|
+
puts "Starting playback..."
|
49
|
+
mpris.player.play
|
50
|
+
puts " Mpris::Player::PLAYING: #{Mpris::Player::PLAYING}"
|
51
|
+
puts " Playback status: #{mpris.player.status}"
|
52
|
+
|
53
|
+
# Current crashes VLC:
|
54
|
+
#puts "Pausing playback..."
|
55
|
+
#mpris.player.pause
|
56
|
+
#puts " Mpris::Player::PAUSED: #{Mpris::Player::PAUSED}"
|
57
|
+
#puts " Playback status: #{mpris.player.status}"
|
@@ -0,0 +1,42 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
#
|
3
|
+
# Script to display the URI, artist and title for the tracks on the tracklist.
|
4
|
+
#
|
5
|
+
# Author:: Nicholas J Humfrey (mailto:njh@aelius.com)
|
6
|
+
# Copyright:: Copyright (c) 2008 Nicholas J Humfrey
|
7
|
+
# License:: Distributes under the same terms as Ruby
|
8
|
+
#
|
9
|
+
|
10
|
+
$:.unshift File.dirname(__FILE__)+'/../lib'
|
11
|
+
|
12
|
+
require 'mpris'
|
13
|
+
|
14
|
+
mpris = Mpris.new
|
15
|
+
|
16
|
+
# Get the number of tracks on the tracklist
|
17
|
+
len = mpris.tracklist.length
|
18
|
+
if (len <= 0)
|
19
|
+
puts "There are no tracks on the tracklist."
|
20
|
+
|
21
|
+
else
|
22
|
+
|
23
|
+
# Get the number of the currently playing track
|
24
|
+
current = mpris.tracklist.current_track
|
25
|
+
|
26
|
+
i=0
|
27
|
+
while (i<len) do
|
28
|
+
|
29
|
+
# Print asterisk next to currently playing track
|
30
|
+
if (i==current)
|
31
|
+
print "* "
|
32
|
+
else
|
33
|
+
print " "
|
34
|
+
end
|
35
|
+
|
36
|
+
# There is a bug in VLC, which makes tracklist start at 1
|
37
|
+
meta = mpris.tracklist.metadata(i+1)
|
38
|
+
puts "#{i}: #{meta['URI']} (#{meta['artist']} - #{meta['title']})"
|
39
|
+
i+=1
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
#
|
3
|
+
# Script to test getting/setting the playback volume of the media player.
|
4
|
+
#
|
5
|
+
# Author:: Nicholas J Humfrey (mailto:njh@aelius.com)
|
6
|
+
# Copyright:: Copyright (c) 2008 Nicholas J Humfrey
|
7
|
+
# License:: Distributes under the same terms as Ruby
|
8
|
+
#
|
9
|
+
|
10
|
+
$:.unshift File.dirname(__FILE__)+'/../lib'
|
11
|
+
|
12
|
+
require 'mpris'
|
13
|
+
|
14
|
+
|
15
|
+
mpris = Mpris.new
|
16
|
+
|
17
|
+
# Test to set and get the playback volume of the media player
|
18
|
+
for vol_in in 0..150
|
19
|
+
mpris.player.volume = vol_in
|
20
|
+
vol_out = mpris.player.volume
|
21
|
+
puts "Setting volume to: #{vol_in}, got back: #{vol_out}."
|
22
|
+
end
|
data/lib/mpris/player.rb
ADDED
@@ -0,0 +1,166 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
#
|
3
|
+
# MPRIS is the Media Player Remote Interfacing Specification.
|
4
|
+
#
|
5
|
+
# Author:: Nicholas J Humfrey (mailto:njh@aelius.com)
|
6
|
+
# Copyright:: Copyright (c) 2008 Nicholas J Humfrey
|
7
|
+
# License:: Distributes under the same terms as Ruby
|
8
|
+
#
|
9
|
+
|
10
|
+
class Mpris
|
11
|
+
|
12
|
+
# This class represents the player itself.
|
13
|
+
class Player
|
14
|
+
|
15
|
+
PLAYING = 0
|
16
|
+
PAUSED = 1
|
17
|
+
STOPPED = 2
|
18
|
+
|
19
|
+
# A player object should only be created directly by its parent Mpris
|
20
|
+
def initialize( service, parent ) #:nodoc:
|
21
|
+
@service = service
|
22
|
+
@parent = parent
|
23
|
+
|
24
|
+
# Check the service implements the MediaPlayer interface
|
25
|
+
object = @service.object("/Player")
|
26
|
+
object.introspect
|
27
|
+
unless object.has_iface? Mpris::MPRIS_INTERFACE
|
28
|
+
raise(Mpris::InterfaceNotImplementedException,
|
29
|
+
"#{service_name} does not implement the MediaPlayer interface on /.")
|
30
|
+
end
|
31
|
+
@interface = object[Mpris::MPRIS_INTERFACE]
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
# Goes to the next item in the TrackList.
|
36
|
+
def next
|
37
|
+
@interface.Next
|
38
|
+
end
|
39
|
+
|
40
|
+
# Goes to the previous item in the TrackList.
|
41
|
+
def previous
|
42
|
+
@interface.Prev
|
43
|
+
end
|
44
|
+
|
45
|
+
# If playing�: pause. If paused�: unpause.
|
46
|
+
def pause
|
47
|
+
@interface.Pause
|
48
|
+
end
|
49
|
+
|
50
|
+
# Stop playback.
|
51
|
+
def stop
|
52
|
+
@interface.Stop
|
53
|
+
end
|
54
|
+
|
55
|
+
# If playing�: rewind to the beginning of current track, else�: start playing.
|
56
|
+
def play
|
57
|
+
@interface.Play
|
58
|
+
end
|
59
|
+
|
60
|
+
# Gives all metadata available for the current item.
|
61
|
+
# Metadata is returned as key,values pairs in a Hash.
|
62
|
+
def metadata
|
63
|
+
return @interface.GetMetadata.first
|
64
|
+
end
|
65
|
+
|
66
|
+
# Toggle the current track repeat.
|
67
|
+
# true to repeat the current track, false to stop repeating.
|
68
|
+
def repeat=(bool)
|
69
|
+
@interface.Repeat(bool)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Returns the current repeat status.
|
73
|
+
#
|
74
|
+
# true: repeat the current element.
|
75
|
+
# false: go to the next element once the current has finished playing.
|
76
|
+
def repeat
|
77
|
+
# Thrid integer in array is repeat status
|
78
|
+
return @interface.GetStatus.first[2] == 1
|
79
|
+
end
|
80
|
+
|
81
|
+
# Return the playing status of "Media Player".
|
82
|
+
# Mpris::Player::PLAYING / Mpris::Player::PAUSED / Mpris::Player::STOPPED
|
83
|
+
def status
|
84
|
+
return @interface.GetStatus.first[0]
|
85
|
+
end
|
86
|
+
|
87
|
+
# Check if there is a next track, or at least something that equals to it
|
88
|
+
# (that is, the remote can call the 'Next' method on the interface, and
|
89
|
+
# expect something to happen.
|
90
|
+
def can_go_next?
|
91
|
+
return capability(0)
|
92
|
+
end
|
93
|
+
|
94
|
+
# Check if there is a previous track.
|
95
|
+
def can_go_prev?
|
96
|
+
return capability(1)
|
97
|
+
end
|
98
|
+
|
99
|
+
# Check if it is possible to pause. This might not always be possible,
|
100
|
+
# and is a hint for frontends as to what to indicate.
|
101
|
+
def can_pause?
|
102
|
+
return capability(2)
|
103
|
+
end
|
104
|
+
|
105
|
+
# Whether playback can currently be started. This might not be the case
|
106
|
+
# if e.g. the playlist is empty in a player, or similar conditions.
|
107
|
+
def can_play?
|
108
|
+
return capability(3)
|
109
|
+
end
|
110
|
+
|
111
|
+
# Whether seeking is possible with the currently played stream.
|
112
|
+
def can_seek?
|
113
|
+
return capability(4)
|
114
|
+
end
|
115
|
+
|
116
|
+
# Whether metadata can be acquired for the currently played stream/source.
|
117
|
+
def can_provide_metadata?
|
118
|
+
return capability(5)
|
119
|
+
end
|
120
|
+
|
121
|
+
# Whether the media player can hold a list of several items.
|
122
|
+
def has_tracklist?
|
123
|
+
return capability(6)
|
124
|
+
end
|
125
|
+
|
126
|
+
# Sets the volume (argument must be in [0;100])
|
127
|
+
def volume=(vol)
|
128
|
+
vol = vol.to_i
|
129
|
+
raise(ArgumentError,"Volume cannot be negative") if (vol<0)
|
130
|
+
@interface.VolumeSet(vol)
|
131
|
+
end
|
132
|
+
|
133
|
+
# Returns the current volume (must be in [0;100])
|
134
|
+
def volume
|
135
|
+
return @interface.VolumeGet.first
|
136
|
+
end
|
137
|
+
|
138
|
+
# Sets the playing position (argument must be in [0;<track_length>]
|
139
|
+
# in milliseconds)
|
140
|
+
def position=(time)
|
141
|
+
time = time.to_i
|
142
|
+
raise(ArgumentError,"Position cannot be negative") if (time<0)
|
143
|
+
@interface.PositionSet(time)
|
144
|
+
end
|
145
|
+
|
146
|
+
# Returns the playing position (will be [0;<track_length>] in milliseconds).
|
147
|
+
def position
|
148
|
+
return @interface.PositionGet.first
|
149
|
+
end
|
150
|
+
|
151
|
+
private
|
152
|
+
|
153
|
+
# Hack so that tracklist can access our interface
|
154
|
+
def interface
|
155
|
+
return @interface
|
156
|
+
end
|
157
|
+
|
158
|
+
# Return the specified bit value from the capabilties bitfield
|
159
|
+
def capability(bit)
|
160
|
+
# FIXME: cache capabilities (for a short period)
|
161
|
+
return ((@interface.GetCaps.first >> bit) & 0x01) == 0x01
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
165
|
+
|
166
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
#
|
3
|
+
# MPRIS is the Media Player Remote Interfacing Specification.
|
4
|
+
#
|
5
|
+
# Author:: Nicholas J Humfrey (mailto:njh@aelius.com)
|
6
|
+
# Copyright:: Copyright (c) 2008 Nicholas J Humfrey
|
7
|
+
# License:: Distributes under the same terms as Ruby
|
8
|
+
#
|
9
|
+
|
10
|
+
class Mpris
|
11
|
+
|
12
|
+
# This class represents the Media Player's tracklist.
|
13
|
+
#
|
14
|
+
# Note that if player.has_tracklist? is false, the methods described below
|
15
|
+
# will be implemented as no-ops, except metadata (which is valid only if given
|
16
|
+
# argument is 0), current_track (which always returns 0),
|
17
|
+
# length (which will return 0 or 1), and add_track.
|
18
|
+
#
|
19
|
+
class TrackList
|
20
|
+
|
21
|
+
# A tracklist object should only be created directly by its parent Mpris
|
22
|
+
def initialize( service, parent ) #:nodoc:
|
23
|
+
@service = service
|
24
|
+
@parent = parent
|
25
|
+
|
26
|
+
# Check the service implements the MediaPlayer interface
|
27
|
+
object = @service.object("/TrackList")
|
28
|
+
object.introspect
|
29
|
+
unless object.has_iface? Mpris::MPRIS_INTERFACE
|
30
|
+
raise(Mpris::InterfaceNotImplementedException,
|
31
|
+
"#{service_name} does not implement the MediaPlayer interface on /.")
|
32
|
+
end
|
33
|
+
@interface = object[Mpris::MPRIS_INTERFACE]
|
34
|
+
end
|
35
|
+
|
36
|
+
# Gives all metadata available for item at given position in the TrackList, counting from 0.
|
37
|
+
#
|
38
|
+
# Metadata is returned as key,values pairs in a Hash
|
39
|
+
#
|
40
|
+
# The pos argument is the position in the TrackList of the item of which the metadata is requested.
|
41
|
+
def metadata(pos)
|
42
|
+
return @interface.GetMetadata(pos).first
|
43
|
+
end
|
44
|
+
|
45
|
+
# Return the position of current URI in the TrackList The return value is zero-based,
|
46
|
+
# so the position of the first URI in the TrackList is 0. The behavior of this method is
|
47
|
+
# unspecified if there are zero items in the TrackList.
|
48
|
+
def current_track
|
49
|
+
return @interface.GetCurrentTrack.first
|
50
|
+
end
|
51
|
+
|
52
|
+
# Returns the number of items in the TrackList.
|
53
|
+
def length
|
54
|
+
return @interface.GetLength.first
|
55
|
+
end
|
56
|
+
|
57
|
+
# Appends an URI in the TrackList.
|
58
|
+
#
|
59
|
+
# Returns 0 if successful
|
60
|
+
def add_track(uri,play_immediately=false)
|
61
|
+
@interface.AddTrack(uri,play_immediately)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Removes an URI from the TrackList.
|
65
|
+
#
|
66
|
+
# pos is the position in the tracklist of the item to remove.
|
67
|
+
def delete_track(pos)
|
68
|
+
@interface.DeleteTrack(pos)
|
69
|
+
end
|
70
|
+
|
71
|
+
# Set the tracklist looping status. true to loop, false to stop looping.
|
72
|
+
def loop=(bool)
|
73
|
+
@interface.SetLoop(bool)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Returns tracklist looping status.
|
77
|
+
def loop
|
78
|
+
# Hack to get the player interface
|
79
|
+
player_iface = @parent.player.send(:interface)
|
80
|
+
# Fourth integrer in array is the looping status
|
81
|
+
return player_iface.GetStatus.first[3] #== 1
|
82
|
+
end
|
83
|
+
|
84
|
+
# Set the tracklist shuffle / random status. It may or may not play tracks only once.
|
85
|
+
# true to play randomly / shuffle tracklist, false to play normally / reorder tracklist.
|
86
|
+
def random=(bool)
|
87
|
+
@interface.SetRandom(bool)
|
88
|
+
end
|
89
|
+
|
90
|
+
# Returns the tracklist shuffle / random status.
|
91
|
+
def random
|
92
|
+
# Hack to get the player interface
|
93
|
+
player_iface = @parent.player.send(:interface)
|
94
|
+
# Second integrer in array is the random status
|
95
|
+
return player_iface.GetStatus.first[1] #== 1
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
data/lib/mpris.rb
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
#
|
3
|
+
# MPRIS is the Media Player Remote Interfacing Specification.
|
4
|
+
#
|
5
|
+
# Author:: Nicholas J Humfrey (mailto:njh@aelius.com)
|
6
|
+
# Copyright:: Copyright (c) 2008 Nicholas J Humfrey
|
7
|
+
# License:: Distributes under the same terms as Ruby
|
8
|
+
#
|
9
|
+
|
10
|
+
require 'dbus'
|
11
|
+
require 'mpris/player'
|
12
|
+
require 'mpris/tracklist'
|
13
|
+
|
14
|
+
|
15
|
+
# This is the base MPRIS class. It creates the #Player and #Tracklist objects
|
16
|
+
# automatically, which are accessible via the attribute readers.
|
17
|
+
class Mpris
|
18
|
+
attr_reader :player
|
19
|
+
attr_reader :tracklist
|
20
|
+
|
21
|
+
MPRIS_SERVICE_PREFIX = 'org.mpris'
|
22
|
+
MPRIS_INTERFACE = 'org.freedesktop.MediaPlayer'
|
23
|
+
|
24
|
+
# Create a new Mpris instance.
|
25
|
+
# By default it will return the first MPRIS enabled player found
|
26
|
+
# on the Session Bus.
|
27
|
+
#
|
28
|
+
# The dbus_address parameter can be use to specify a different dbus, for
|
29
|
+
# example 'unix:path=/var/run/dbus_socket'.
|
30
|
+
#
|
31
|
+
# The service_name parameter can be used to specify a specifc MediaPlayer,
|
32
|
+
# for example 'org.mpris.vlc'.
|
33
|
+
def initialize( dbus_address=nil, service_name=nil )
|
34
|
+
|
35
|
+
# FIXME: support passing in a dbus object, instead of a dbus address
|
36
|
+
if dbus_address.nil?
|
37
|
+
# Use the default session bus
|
38
|
+
@dbus = DBus::SessionBus.instance
|
39
|
+
else
|
40
|
+
@dbus = DBus::Connection.new(dbus_address)
|
41
|
+
@dbus.connect
|
42
|
+
#self.send_hello
|
43
|
+
end
|
44
|
+
|
45
|
+
# Look for service name, if one isn't given
|
46
|
+
if service_name.nil?
|
47
|
+
service_names = @dbus.proxy.ListNames[0]
|
48
|
+
service_names.each { |n|
|
49
|
+
if (n =~ /^org.mpris/)
|
50
|
+
service_name = n
|
51
|
+
break
|
52
|
+
end
|
53
|
+
}
|
54
|
+
|
55
|
+
# Did we find one?
|
56
|
+
if service_name.nil?
|
57
|
+
raise( ServiceNotFoundException, "No MPRIS service found on D-Bus." )
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Get the service
|
62
|
+
@service = @dbus.service(service_name)
|
63
|
+
|
64
|
+
# Check the service implements the MediaPlayer interface
|
65
|
+
root_object = @service.object("/")
|
66
|
+
root_object.introspect
|
67
|
+
unless root_object.has_iface? MPRIS_INTERFACE
|
68
|
+
raise(InterfaceNotImplementedException,
|
69
|
+
"#{service_name} does not implement the MediaPlayer interface on /." )
|
70
|
+
end
|
71
|
+
@interface = root_object[MPRIS_INTERFACE]
|
72
|
+
|
73
|
+
# Create the player object
|
74
|
+
@player = Mpris::Player.new(@service, self)
|
75
|
+
|
76
|
+
# Create a tracklist object
|
77
|
+
@tracklist = Mpris::TrackList.new(@service, self)
|
78
|
+
end
|
79
|
+
|
80
|
+
# Identify the "media player" as in "VLC 0.9.0", "bmpx 0.34.9", "Audacious 1.4.0" ...
|
81
|
+
#
|
82
|
+
# Returns a string containing the media player identification.
|
83
|
+
def identity
|
84
|
+
return @interface.Identity
|
85
|
+
end
|
86
|
+
|
87
|
+
# Makes the "Media Player" exit.
|
88
|
+
def quit
|
89
|
+
@interface.Quit
|
90
|
+
end
|
91
|
+
|
92
|
+
# Returns the version of the MPRIS spec being implemented as major.major
|
93
|
+
def mpris_version
|
94
|
+
return @interface.MprisVersion.first.join('.')
|
95
|
+
end
|
96
|
+
|
97
|
+
|
98
|
+
# Exception raised if no Mpris service is found on the D-Bus.
|
99
|
+
class ServiceNotFoundException < Exception
|
100
|
+
end
|
101
|
+
|
102
|
+
# Exception raised if MediaPlayer interface isn't implemented.
|
103
|
+
class InterfaceNotImplementedException < Exception
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
metadata
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ruby-mpris
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Nicholas J Humfrey
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-04-27 00:00:00 +01:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rake
|
17
|
+
version_requirement:
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: "0"
|
23
|
+
version:
|
24
|
+
description: The mpris gem allows you to control media players that follow the MPRIS specification.
|
25
|
+
email: njh@aelius.com
|
26
|
+
executables: []
|
27
|
+
|
28
|
+
extensions: []
|
29
|
+
|
30
|
+
extra_rdoc_files:
|
31
|
+
- README
|
32
|
+
- NEWS
|
33
|
+
- COPYING
|
34
|
+
files:
|
35
|
+
- Rakefile
|
36
|
+
- lib/mpris.rb
|
37
|
+
- lib/mpris/player.rb
|
38
|
+
- lib/mpris/tracklist.rb
|
39
|
+
- examples/capabilities_test.rb
|
40
|
+
- examples/identify.rb
|
41
|
+
- examples/metadata.rb
|
42
|
+
- examples/play_track.rb
|
43
|
+
- examples/playerkeys.rb
|
44
|
+
- examples/status_test.rb
|
45
|
+
- examples/tracklist.rb
|
46
|
+
- examples/volume_test.rb
|
47
|
+
- README
|
48
|
+
- NEWS
|
49
|
+
- COPYING
|
50
|
+
has_rdoc: true
|
51
|
+
homepage: http://mpris.rubyforge.org
|
52
|
+
post_install_message:
|
53
|
+
rdoc_options: []
|
54
|
+
|
55
|
+
require_paths:
|
56
|
+
- lib
|
57
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: "0"
|
62
|
+
version:
|
63
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: "0"
|
68
|
+
version:
|
69
|
+
requirements: []
|
70
|
+
|
71
|
+
rubyforge_project: mpris
|
72
|
+
rubygems_version: 1.0.1
|
73
|
+
signing_key:
|
74
|
+
specification_version: 2
|
75
|
+
summary: A library to control MPRIS based Media Players
|
76
|
+
test_files: []
|
77
|
+
|