mplayer-ruby 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Arthur Chiu
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,59 @@
1
+ = mplayer-ruby
2
+
3
+ A Ruby Wrapper for MPlayer. Controls MPlayer via the Slave Protocol.
4
+
5
+
6
+ See examples/ for usage.
7
+
8
+
9
+ == Installation
10
+
11
+
12
+ === MPlayer
13
+
14
+ ==== Linux
15
+
16
+ $ sudo apt-get install mplayer
17
+
18
+ ==== Mac OS X
19
+
20
+ ===== via Homebrew
21
+
22
+ $ brew install mplayer
23
+
24
+ ===== via download
25
+
26
+ download (Mac OS X Extended)[http://www.mplayerhq.hu/homepage/design7/news.html].
27
+
28
+ then create a symbolic link for mplayer.
29
+
30
+ $ sudo ln -s "/Applications/MPlayer OSX Extended.app/Contents/Resources/External_Binaries/mplayer.app/Contents/MacOS/mplayer" /usr/bin/mplayer
31
+
32
+ === MPlayer-ruby
33
+
34
+ It's hosted on gemcutter.org
35
+
36
+ $ sudo gem install mplayer-ruby
37
+
38
+
39
+
40
+ == TODO
41
+ * Complete Slave Protocol
42
+ * Complete Other Functionalities
43
+ * Create a Better README
44
+ * RDoc?
45
+ * Example Usages
46
+
47
+ == Note on Patches/Pull Requests
48
+
49
+ * Fork the project.
50
+ * Make your feature addition or bug fix.
51
+ * Add tests for it. This is important so I don't break it in a
52
+ future version unintentionally.
53
+ * Commit, do not mess with rakefile, version, or history.
54
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
55
+ * Send me a pull request. Bonus points for topic branches.
56
+
57
+ == Copyright
58
+
59
+ Copyright (c) 2010 Arthur Chiu. See LICENSE for details.
@@ -0,0 +1,68 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "mplayer-ruby"
8
+ gem.summary = %Q{Ruby wrapper for MPlayer}
9
+ gem.description = %Q{A Ruby wrapper for MPlayer}
10
+ gem.email = "mr.arthur.chiu@gmail.com"
11
+ gem.homepage = "http://github.com/achiu/mplayer-ruby"
12
+ gem.authors = ["Arthur Chiu"]
13
+ gem.add_development_dependency "riot", ">= 0.10.11"
14
+ gem.add_development_dependency "rr", ">=0.10.5"
15
+ gem.add_dependency "open4", ">=1.0.1"
16
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
17
+ end
18
+ Jeweler::GemcutterTasks.new
19
+ rescue LoadError
20
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
21
+ end
22
+
23
+ require 'rake/testtask'
24
+ Rake::TestTask.new(:test) do |test|
25
+ test.libs << 'lib' << 'test'
26
+ test.pattern = 'test/**/*_test.rb'
27
+ test.verbose = true
28
+ end
29
+
30
+ begin
31
+ require 'rcov/rcovtask'
32
+ Rcov::RcovTask.new do |test|
33
+ test.libs << 'test'
34
+ test.pattern = 'test/**/*_test.rb'
35
+ test.verbose = true
36
+ end
37
+ rescue LoadError
38
+ task :rcov do
39
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
40
+ end
41
+ end
42
+
43
+ task :test => :check_dependencies
44
+
45
+ begin
46
+ require 'reek/adapters/rake_task'
47
+ Reek::RakeTask.new do |t|
48
+ t.fail_on_error = true
49
+ t.verbose = false
50
+ t.source_files = 'lib/**/*.rb'
51
+ end
52
+ rescue LoadError
53
+ task :reek do
54
+ abort "Reek is not available. In order to run reek, you must: sudo gem install reek"
55
+ end
56
+ end
57
+
58
+ task :default => :test
59
+
60
+ require 'rake/rdoctask'
61
+ Rake::RDocTask.new do |rdoc|
62
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
63
+
64
+ rdoc.rdoc_dir = 'rdoc'
65
+ rdoc.title = "mplayer-ruby #{version}"
66
+ rdoc.rdoc_files.include('README*')
67
+ rdoc.rdoc_files.include('lib/**/*.rb')
68
+ end
data/TODO ADDED
@@ -0,0 +1,47 @@
1
+
2
+ Slave Commands:
3
+
4
+ balance Float
5
+ tv_start_scan
6
+ tv_step_channel Integer
7
+ tv_step_norm
8
+ tv_step_chanlist
9
+ tv_set_channel String
10
+ tv_last_channel
11
+ tv_set_freq Float
12
+ tv_step_freq Float
13
+ tv_set_norm String
14
+ tv_set_brightness Integer [Integer]
15
+ tv_set_contrast Integer [Integer]
16
+ tv_set_hue Integer [Integer]
17
+ tv_set_saturation Integer [Integer]
18
+ forced_subs_only [Integer]
19
+ switch_ratio [Float]
20
+ vo_fullscreen [Integer]
21
+ vo_ontop [Integer]
22
+ file_filter Integer
23
+ vo_rootwin [Integer]
24
+ vo_border [Integer]
25
+ screenshot [Integer]
26
+ panscan Float [Integer]
27
+ switch_vsync [Integer]
28
+ loadfile String [Integer]
29
+ loadlist String [Integer]
30
+ run String
31
+ change_rectangle Integer Integer
32
+ dvdnav String
33
+ get_vo_fullscreen
34
+ get_sub_visibility
35
+ key_down_event Integer
36
+ set_property String String
37
+ get_property String
38
+ step_property String [Float] [Integer]
39
+ seek_chapter Integer [Integer]
40
+ set_mouse_pos Integer Integer
41
+ vobsub_lang [Integer]
42
+ sub_log
43
+
44
+ Player Options
45
+ Audio Options
46
+ Decoding Options
47
+ all the Options...
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,60 @@
1
+ require File.join(File.dirname(__FILE__),'..','lib','mplayer-ruby')
2
+
3
+ $player = MPlayer::Slave.new '/Volumes/Storage/Music/segundo.ogg', :path => '/usr/bin/mplayer' #defauults to /usr/bin/mplayer
4
+
5
+ puts $player.volume :up
6
+ sleep 5
7
+ puts $player.volume :down
8
+ sleep 5
9
+ puts $player.volume :set, 60
10
+ sleep 5
11
+ load file and play immediately
12
+ puts $player.load_file "/Volumes/Storage/Music/primero.ogg", :no_append
13
+
14
+ sleep 10
15
+
16
+ # load file and queue
17
+ # load_file(file) defaults to :append
18
+ puts $player.load_file "/Volumes/Storage/Music/segundo.ogg", :append
19
+
20
+ sleep 10
21
+ # step forward
22
+ puts $player.next 1
23
+ sleep 10
24
+ # step backward
25
+ puts $player.back 1
26
+
27
+ sleep 10
28
+
29
+ # returns information on the file
30
+ $player.get :meta_artist
31
+ $player.get :meta_album
32
+ $player.get :meta_track
33
+ %w[time_pos time_length file_name video_codec video_bitrate video_resolution
34
+ audio_codec audio_bitrate audio_samples meta_title meta_artist meta_album
35
+ meta_year meta_comment meta_track meta_genre].each do |line|
36
+ puts $player.get line
37
+ end
38
+
39
+ # time_position. fields can also be called as methods
40
+ puts $player.time_position
41
+ puts $player.year
42
+
43
+ # mute
44
+ puts $player.mute :on
45
+ sleep 10
46
+ puts $player.mute # toggles back to off
47
+ # seek to position in song
48
+ puts $player.seek 2
49
+ puts $player.seek 10, :percent
50
+ puts $player.seek 20, :absolute
51
+
52
+ # sets the speed of playback
53
+ puts ($player.speed 2,:increment)
54
+ puts $player.speed 2,:multiply
55
+ puts $player.speed 1
56
+
57
+ # quits MPlayer
58
+ puts $player.quit
59
+
60
+
@@ -0,0 +1,6 @@
1
+ require 'rubygems'
2
+ require 'open4'
3
+ require 'active_support/core_ext/hash'
4
+ require File.dirname(__FILE__) + '/mplayer-ruby/slave_commands'
5
+ require File.dirname(__FILE__) + '/mplayer-ruby/slave_video_commands'
6
+ Dir[File.dirname(__FILE__) + '/mplayer-ruby/**/*.rb'].each { |lib| require lib }
@@ -0,0 +1,63 @@
1
+ module MPlayer
2
+ class Slave
3
+ attr_accessor :stdin
4
+ attr_reader :pid,:stdout,:stderr,:file
5
+ include MPlayer::SlaveCommands
6
+ include MPlayer::SlaveVideoCommands
7
+
8
+
9
+ # Initializes a new instance of MPlayer.
10
+ # set :path to point to the location of mplayer
11
+ # defaults to '/usr/bin/mplayer'
12
+ def initialize(file = "",options ={:path => '/usr/bin/mplayer'})
13
+ raise ArgumentError,"Invalid File" unless File.exists?(file)
14
+ @file = file
15
+ mplayer = "#{options[:path]} -slave -quiet #{@file}"
16
+ @pid,@stdin,@stdout,@stderr = Open4.popen4(mplayer)
17
+ until @stdout.gets.inspect =~ /playback/ do
18
+ end #fast forward to the desired output
19
+ end
20
+
21
+ # sends command to mplayer stdin and retrieves stdout.
22
+ # If match is provided, fast-forwards stdout to matching response.
23
+ def send(cmd,match = //)
24
+ @stdin.puts(cmd)
25
+ response = @stdout.gets
26
+ until response =~ match
27
+ response = @stdout.gets
28
+ end
29
+ response.gsub("\e[A\r\e[K","")
30
+ end
31
+
32
+ private
33
+
34
+ def select_cycle(command,value,match = //)
35
+ switch = case value
36
+ when :off then -1
37
+ when :cycle then -2
38
+ else value
39
+ end
40
+ send "#{command} #{switch}",match
41
+ end
42
+
43
+ def toggle(command,value,match = //)
44
+ cmd = case value
45
+ when :on then "#{command} 1"
46
+ when :off then "#{command} 0"
47
+ else "#{command}"
48
+ end
49
+ send cmd,match
50
+ end
51
+
52
+ def setting(command,value,type, match = //)
53
+ raise(ArgumentError,"Value out of Range -100..100") unless (-100..100).include?(value)
54
+ adjust_set command, value, type
55
+ end
56
+
57
+ def adjust_set(command,value,type = :relative, match = //)
58
+ switch = ( type == :relative ? 0 : 1 )
59
+ send "#{command} #{value} #{switch}",match
60
+ end
61
+
62
+ end
63
+ end
@@ -0,0 +1,188 @@
1
+ module MPlayer
2
+ module SlaveCommands
3
+ # Increase/decrease volume
4
+ # :up increase volume
5
+ # :down decreases volume
6
+ # :set sets the volume at <value>
7
+ def volume(action,value=30)
8
+ cmd =
9
+ case action
10
+ when :up then "volume 1"
11
+ when :down then "volume 0"
12
+ when :set then "volume #{value} 1"
13
+ else return false
14
+ end
15
+ resp = send cmd, /Volume/
16
+ resp.gsub("Volume: ","").gsub(" %\n","")
17
+ end
18
+
19
+ # Seek to some place in the file
20
+ # :relative is a relative seek of +/- <value> seconds (default).
21
+ # :perecent is a seek to <value> % in the file.
22
+ # :absolute is a seek to an absolute position of <value> seconds.
23
+ def seek(value,type = :relative)
24
+ command = case type
25
+ when :percent then "seek #{value} 1"
26
+ when :absolute then "seek #{value} 2"
27
+ else "seek #{value} 0"
28
+ end
29
+ resp = send command, /Position/
30
+ resp.gsub("Position: ","").gsub(" %\n","")
31
+ end
32
+
33
+ # Adjusts the current playback speed
34
+ # :increment adds <value> to the current speed
35
+ # :multiply multiplies the current speed by <value>
36
+ # :set sets the current speed to <value>.(default)
37
+ def speed(value,type = :set)
38
+ case type
39
+ when :increment then speed_incr(value)
40
+ when :multiply then speed_mult(value)
41
+ else speed_set(value)
42
+ end
43
+ end
44
+
45
+ # Adjust/set how many times the movie should be looped.
46
+ # :none means no loop
47
+ # :forever means loop forever.(default)
48
+ # :set sets the amount of times to loop. defaults to one loop.
49
+ def loop(action = :forever,value = 1)
50
+ send case action
51
+ when :none then "loop -1"
52
+ when :set then "loop #{value}"
53
+ else "loop 0"
54
+ end
55
+ end
56
+
57
+ # Go to the next/previous entry in the playtree.
58
+ #T he sign of <value> tells the direction.
59
+ # If no entry is available in the given direction it will do
60
+ # nothing unless :force
61
+ def pt_step(value,force = :no_force)
62
+ send(force == :force ? "pt_step #{value} 1" : "pt_step #{value} 0")
63
+ end
64
+
65
+ # goes to the next entry in the playlist denoted by value.
66
+ # No action will occur unless :force is specified
67
+ def next(value,force = :no_force)
68
+ pt_step value.abs, force
69
+ end
70
+
71
+ # goes to the previous entry in the playlist denoted by value.
72
+ # No action will occur unless :force is specified
73
+ def back(value,force = :no_force)
74
+ v = "-" + value.to_s.gsub("-","")
75
+ pt_step v, force
76
+ end
77
+
78
+ # Similar to pt_step but jumps to the next/previous entry in the parent list.
79
+ # Useful to break out of the inner loop in the playtree.
80
+ def pt_up_step(value,force = :no_force)
81
+ send(force == :force ? "pt_up_step #{value} 1" : "pt_up_step #{value} 0")
82
+ end
83
+
84
+ # Switch volume control between master and PCM.
85
+ def use_master; send("use_master"); end
86
+
87
+ # Toggle sound output muting or set it to [value] when [value] >= 0
88
+ # (1 == on, 0 == off).
89
+ def mute(value = nil)
90
+ resp = toggle :mute, value, /Mute/
91
+ resp.gsub("Mute: ","")
92
+ end
93
+
94
+ # returns information on file
95
+ # available values are:
96
+ # time_pos time_length file_name video_codec video_bitrate video_resolution
97
+ # audio_codec audio_bitrate audio_samples meta_title meta_artist meta_album
98
+ # meta_year meta_comment meta_track meta_genre
99
+ def get(value)
100
+ match = case value.to_s
101
+ when "time_pos" then "ANS_TIME_POSITION"
102
+ when "time_length" then "ANS_LENGTH"
103
+ when "file_name" then "ANS_FILENAME"
104
+ else "ANS_#{value.to_s.upcase}"
105
+ end
106
+ resp = send "get_#{value}",/#{match}/
107
+ resp.gsub("#{match}=","").gsub("'","")
108
+ end
109
+
110
+ # This gives methods for each of the fields that data can be extract on.
111
+ # Just to provide more syntactic sugar.
112
+ %w[time_pos time_length file_name video_codec video_bitrate video_resolution
113
+ audio_codec audio_bitrate audio_samples meta_title meta_artist meta_album
114
+ meta_year meta_comment meta_track meta_genre].each do |field|
115
+ define_method(field.to_sym) { get(field) }
116
+ end
117
+ alias :time_position :time_pos
118
+ alias :filename :file_name
119
+ alias :title :meta_title
120
+ alias :album :meta_album
121
+ alias :year :meta_year
122
+ alias :artist :meta_artist
123
+ alias :comment :meta_comment
124
+ alias :genre :meta_genre
125
+
126
+
127
+ # Loads the file into MPlayer
128
+ # :append loads the file and appends it to the current playlist
129
+ # :no_append will stop playback and play new loaded file
130
+ def load_file(file,append = :no_append)
131
+ raise ArgumentError,"Invalid File" unless File.exists? file
132
+ switch = (append == :append ? 1 : 0)
133
+ send "loadfile #{file} #{switch}"
134
+ end
135
+
136
+ # Loads the playlist into MPlayer
137
+ # :append loads the playlist and appends it to the current playlist
138
+ # :no_append will stop playback and play new loaded playlist
139
+ def load_list(file,append = :no_append)
140
+ raise ArgumentError,"Invalid File" unless File.exists? file
141
+ switch = (append == :append ? 1 : 0)
142
+ send "loadlist #{file} #{switch}"
143
+ end
144
+
145
+ # When more than one source is available it selects the next/previous one.
146
+ # ASX Playlist ONLY
147
+ def alt_src_step(value); send("alt_src_step #{value}"); end
148
+
149
+ # Add <value> to the current playback speed.
150
+ def speed_incr(value)
151
+ speed_setting :speed_incr, value
152
+ end
153
+
154
+ # Multiply the current speed by <value>.
155
+ def speed_mult(value)
156
+ speed_setting :speed_mult, value
157
+ end
158
+
159
+ # Set the speed to <value>.
160
+ # cannot be greater than 5
161
+ def speed_set(value)
162
+ speed_setting :speed_set, value
163
+ end
164
+
165
+ # Play one frame, then pause again.
166
+ def frame_step; send("frame_step"); end
167
+
168
+ # Write the current position into the EDL file.
169
+ def edl_mark; send("edl_mark"); end
170
+
171
+ # Pauses/Unpauses the file.
172
+ def pause; send("pause") ; end
173
+
174
+ # Quits MPlayer
175
+ def quit
176
+ send('quit')
177
+ @stdin.close
178
+ end
179
+
180
+ private
181
+
182
+ def speed_setting(command,value)
183
+ raise ArgumentError,"Value must be less than 6" unless value <= 5
184
+ send("#{command} #{value}",/Speed/).gsub("Speed: x ","")
185
+ end
186
+
187
+ end
188
+ end