activevlc 0.0.1 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2cfe489b2cfbfad5e9f2e34f8047568c0d0d2308
4
- data.tar.gz: bcb80b8ed6a3cd149d0a2d394885ee46ba780ca8
3
+ metadata.gz: e7277724b68e5a47757cd221b47c6522bc74cf0c
4
+ data.tar.gz: 19a56e502c9d73feb2c0fdeb114dcaf98162d665
5
5
  SHA512:
6
- metadata.gz: f7c078deb42fcad7eec5913ea57f994552e123e1293911b2e2c48eb52367e896d62b81e88371878d06a20604b362d073907312650ef45dd2d8f4f2227be11477
7
- data.tar.gz: 01ac07764a7d0b86bebc5b816f0a2f900391909214e93f74d08f14ee443286b1065d3ee7e0b43ba2c0d31ef3958eea704af5bacacbea99151336ffe116bb36fb
6
+ metadata.gz: eaf8db920f751616a47ba9a46bcc252684d04120cf82703071ce66f6bf46fa9896165f26c383fa66866b453c3a27a6f0aa139ee8a542a4238dfa4084c5887014
7
+ data.tar.gz: 01bf1845e930f5ad7ee4cf4e0a929a869b986e1fb3ddc94f8c33547d4dff0d6ea782906ce1f84e958151cd479de2d88360e62de7ee5e5e8b2b49071dc7da2f22
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - jruby-19mode # JRuby in 1.9 mode
6
+ before_install: 'sudo apt-get update && sudo apt-get install -y vlc-nox'
data/README.md CHANGED
@@ -1,25 +1,54 @@
1
1
  # ActiveVlc
2
2
 
3
- Do you know VLC, the famous media player ? I'm pretty sure you do !
3
+ [![Gem Version](https://badge.fury.io/rb/activevlc.png)](http://badge.fury.io/rb/activevlc)
4
+ [![Code Climate](https://codeclimate.com/github/elthariel/activevlc.png)](https://codeclimate.com/github/elthariel/activevlc)
5
+ [![Build Status](https://travis-ci.org/elthariel/activevlc.png?branch=master)](https://travis-ci.org/elthariel/activevlc)
6
+
7
+ Do you know VLC, the famous media player ? I'm pretty sure you do !
4
8
  Do you know this is also a pretty powerfull media processing and streaming framework ? Maybe...
5
- Do you understand something about the command line syntax to access vlc's underlying
9
+ Do you understand something about the command line syntax to access vlc's underlying
6
10
  powers ? If you don't this tool is for you !
7
11
 
8
- ActiveVlc provides a simple syntax to configure and run transcoding/streaming/processing
12
+ ActiveVlc provides a simple syntax to configure and run transcoding/streaming/processing
9
13
  operations using VLC. Here's a simple example :
10
14
 
15
+ ## Installation
16
+
17
+ First and foremost, you must have VLC and libvlc installed on your system and
18
+ the vlc binary must be in your PATH since we doesn't provide yet a cool
19
+ configuration system for this (contribution welcomed !)
20
+
21
+ Add this line to your application's Gemfile:
22
+
23
+ gem 'activevlc'
24
+
25
+ And then execute:
26
+
27
+ $ bundle
28
+
29
+ Or use the master branch on GitHub to test de development version by replacing
30
+ the line in your Gemfile by this one:
31
+
32
+ gem 'activevlc', github: 'elthariel/activevlc'
33
+
34
+ Or install it yourself as:
35
+
36
+ $ gem install activevlc
37
+
11
38
  ## Example
12
39
 
13
- Let's say you want to read an mp4 file, transcode it using different options, save the result to
40
+ ### Command line
41
+
42
+ Let's say you want to read an mp4 file, transcode it using different options, save the result to
14
43
  another file while displaying it to control what's happening. Using the standard vlc's chain syntax
15
44
  you'd have to write
16
45
 
17
46
  vlc input.mp4 :sout="#transcode{deinterlace, acodec=aac, ab=128, channels=2, vcodec=h264, venc=x264{bpyramid=strict, bframes=4, no-cabac}, vb=512}:duplicate{dst=standard{mux=mp4, dst='output.mp4'}, dst=display}"
18
-
47
+
19
48
  Not very readable isn't it ? Let's try the same with ActiveVlc :
20
49
 
21
50
  ```ruby
22
- AtiveVlc::Pipeline.for 'input.mp4' do
51
+ AtiveVlc::pipe do
23
52
  transcode do
24
53
  deinterlace
25
54
  audio :aac do
@@ -45,45 +74,71 @@ AtiveVlc::Pipeline.for 'input.mp4' do
45
74
  end
46
75
  ```
47
76
 
48
- This sintax might be a lot more verbose than the original vlc's one,
77
+ This sintax might be a lot more verbose than the original vlc's one,
49
78
  it is still A LOT more readable and understandable, and since this is plain ruby
50
79
  you can add comment and arbitrary code !
51
80
  Then you can run it using :
52
81
 
53
- activevlc exec /path/to/the/pipeline.rb
54
-
55
- ## Development status
82
+ activevlc exec /path/to/the/pipeline.rb input.mp4
56
83
 
57
- This gem is not yet published yet and is still under active
58
- development althought it might already be usable for many usages
84
+ ### From Ruby code
59
85
 
60
- ## Installation
86
+ You can also use ActiveVlc programmatically from your ruby code :
61
87
 
62
- First and foremost, you must have VLC installed on your system and the
63
- vlc binary must be in your PATH since we doesn't provide yet a cool
64
- configuration system for this (contribution welcomed !)
88
+ ```ruby
89
+ def my_encoding_method(input, output)
90
+ # Create the pipeline.
91
+ pipe = ActiveVlc::pipe input do
92
+ transcode do
93
+ # Same syntax as above, also see spec/pipes
94
+ end
95
+ to :file, output
96
+ end
65
97
 
66
- Add this line to your application's Gemfile:
98
+ # Run it synchronously
99
+ ActiveVlc::Runner.new(pipe).run
100
+ # Your transcoding operation is over (except if there were strong errors)
101
+ end
102
+ ```
67
103
 
68
- gem 'activevlc'
104
+ ## Development status
69
105
 
70
- And then execute:
106
+ This gem is still under active development
107
+ althought it might already be usable for many usages.
71
108
 
72
- $ bundle
109
+ If you have any trouble, idea or question, please use GitHub issue
110
+ system. If you have an idea with code attached to it, got to the
111
+ 'Contributing' section below.
73
112
 
74
- Or install it yourself as:
113
+ ## Supported system/rubies
75
114
 
76
- $ gem install activevlc
115
+ Ruby 1.8 is _NOT_ supported.
116
+
117
+ This gem is developped using MRI 2.0.0 on Debian 7 / Ubuntu 13.04 but it should work OOB on MRI 1.9 and other GNU/Linux systems.
118
+
119
+ Altough there might me some threading issues between the interpreter and libvlc, the specs are eported to pass against :
120
+ * Jruby (1.7)
121
+ * Rubinius (head) (with some minor problems)
122
+
123
+ I doesn't have access to any OSX boxes so but it should work as well, please let me know if you encounter any issue.
77
124
 
78
125
  ## Usage
79
126
 
80
- Currently, the best documentation is to have a look to the spec (/spec/pipes)
127
+ Currently, the best documentation is to have a look to the spec (/spec/pipes)
81
128
  or to run the CLI tool to get the embedded help.
82
129
 
130
+ ## Known Issues
131
+
132
+ * We use a pretty ugly hack to be able to run pipelines synchronously
133
+ * You cannot (yet) configure output(s) from the command line, only with ruby
134
+ * There's currently almost no error reporting except from the one vlc's outputting on STDOUT. Vlc's logging and error reporting is pretty complex, i still need to take some time to figure it out.
135
+
83
136
  ## Contributing
84
137
 
85
138
  1. Fork it
86
139
  2. Create your feature branch (`git checkout -b my-new-feature`)
87
- 3. Commit your changes (`git commit -am 'Add some feature'`)
88
- 4. Push to the branch (`git push origin my-new-feature`)
89
- 5. Create new Pull Request
140
+ 3. Write some specs for your feature
141
+ 4. Implements your feature and make your test pass
142
+ 5. Commit your changes (`git commit -am 'Add some feature'`)
143
+ 6. Push to the branch (`git push origin my-new-feature`)
144
+ 7. Create new Pull Request
data/Rakefile CHANGED
@@ -1 +1,6 @@
1
1
  require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/TODO.md CHANGED
@@ -6,7 +6,6 @@ TODO file for ActiveVlc
6
6
  - Preset support (this is also a cool way of documenting vlc's features
7
7
  - vlc team suggestions (jb/etix)
8
8
  - Some syntactic sugar for http-live will be helpfull, pay attention to this shitty module
9
- - duplicate -> transcode, transcode -> duplicate
10
9
  - Long-term ideas
11
10
  - carrierwave integration
12
11
 
data/activevlc.gemspec CHANGED
@@ -19,11 +19,12 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ["lib"]
20
20
 
21
21
  spec.add_development_dependency "bundler", "~> 1.3"
22
- spec.add_development_dependency "rspec", "~> 2.6"
22
+ spec.add_development_dependency "rspec", "~> 2.14"
23
23
  spec.add_development_dependency "simplecov"
24
24
  spec.add_development_dependency "rake"
25
- spec.add_development_dependency "debugger"
25
+ #spec.add_development_dependency "debugger"
26
26
 
27
27
  spec.add_dependency 'thor'
28
28
  spec.add_dependency 'activesupport'
29
+ spec.add_dependency 'ffi'
29
30
  end
data/examples/basic.rb ADDED
@@ -0,0 +1,14 @@
1
+ ##
2
+ ## basic.rb
3
+ ## Login : <lta@still>
4
+ ## Started on Wed Jun 12 14:41:04 2013 Lta Akr
5
+ ## $Id$
6
+ ##
7
+ ## Author(s):
8
+ ## - Lta Akr <>
9
+ ##
10
+ ## Copyright (C) 2013 Lta Akr
11
+
12
+ # Basic pipe for rspec testing
13
+
14
+ ActiveVlc::Pipeline.for 'input.mp4'
@@ -0,0 +1,18 @@
1
+ ##
2
+ ## duplicate.rb
3
+ ## Login : <lta@still>
4
+ ## Started on Wed Sep 4 17:29:45 2013 Lta Akr
5
+ ## $Id$
6
+ ##
7
+ ## Author(s):
8
+ ## - Lta Akr <>
9
+ ##
10
+ ## Copyright (C) 2013 Lta Akr
11
+
12
+ # input.mp3 :sout="#duplicate{dst=display, dst=std{dst='output.mp3'}}"
13
+ ActiveVlc::Pipeline.for 'input.mp3' do
14
+ duplicate do
15
+ to :display
16
+ to file: 'output.mp3'
17
+ end
18
+ end
@@ -0,0 +1,29 @@
1
+ ##
2
+ ## duplicate_then_transcode.rb
3
+ ## Login : <lta@still>
4
+ ## Started on Tue Sep 10 18:30:41 2013 Lta Akr
5
+ ## $Id$
6
+ ##
7
+ ## Author(s):
8
+ ## - Lta Akr <>
9
+ ##
10
+ ## Copyright (C) 2013 Lta Akr
11
+
12
+ ActiveVlc::Pipeline.for 'input.mp4' do
13
+ duplicate do
14
+ to :chain do
15
+ #debugger
16
+ transcode do
17
+ audio :aac
18
+ video :h264
19
+ subtitle :svcd
20
+ end
21
+ to :file do
22
+ mux :mp4
23
+ dst 'output.mp4'
24
+ end
25
+ end
26
+ to :display
27
+ end
28
+ end
29
+
@@ -0,0 +1,25 @@
1
+ ##
2
+ ## transcode_and_display.rb
3
+ ## Login : <lta@still>
4
+ ## Started on Wed Jun 12 14:45:36 2013 Lta Akr
5
+ ## $Id$
6
+ ##
7
+ ## Author(s):
8
+ ## - Lta Akr <>
9
+ ##
10
+ ## Copyright (C) 2013 Lta Akr
11
+
12
+ ActiveVlc::pipe_for 'input.mp4' do
13
+ transcode do
14
+ audio :aac
15
+ video :h264
16
+ subtitle :svcd
17
+ end
18
+ duplicate do
19
+ to :file do
20
+ mux :mp4
21
+ dst 'output.mp4'
22
+ end
23
+ to :display
24
+ end
25
+ end
@@ -0,0 +1,36 @@
1
+ ##
2
+ ## transcode_and_display.rb
3
+ ## Login : <lta@still>
4
+ ## Started on Wed Jun 12 14:45:36 2013 Lta Akr
5
+ ## $Id$
6
+ ##
7
+ ## Author(s):
8
+ ## - Lta Akr <>
9
+ ##
10
+ ## Copyright (C) 2013 Lta Akr
11
+
12
+ ActiveVlc::Pipeline.for 'input.mp4' do
13
+ gather
14
+ transcode do
15
+ deinterlace
16
+ audio :aac do
17
+ bitrate 128 # 128 kpbs
18
+ channels 2
19
+ end
20
+ video :h264 do
21
+ encoder :x264 do
22
+ bpyramid :strict
23
+ bframes 4
24
+ cabac false
25
+ end
26
+ bitrate 512 # 512 kbps
27
+ end
28
+ end
29
+ duplicate do
30
+ to :file do
31
+ mux :mp4
32
+ dst 'output.mp4'
33
+ end
34
+ to :display
35
+ end
36
+ end
data/lib/activevlc/cli.rb CHANGED
@@ -29,10 +29,10 @@ module ActiveVlc
29
29
  puts "ActiveVlc version #{ActiveVlc::VERSION}"
30
30
  end
31
31
 
32
- desc 'vlc SUBCOMMAND ...ARGS', 'vlc specific commands'
32
+ desc 'vlc ', 'VLC specific commands. See activevlc help vlc for details'
33
33
  subcommand 'vlc', ActiveVlc::CLI::Vlc
34
34
 
35
- desc 'fragment PIPE_PATH', 'Outputs vlc :sout=chain fragment for the pipe defined in \'PIPE_PATH\' file'
35
+ desc 'fragment path', 'Outputs vlc \':sout=...\' string for the pipeline defined in the \'path\' file'
36
36
  def fragment(path)
37
37
  if File.readable?(path)
38
38
  pipe = eval(File.read(path))
@@ -43,11 +43,12 @@ module ActiveVlc
43
43
  end
44
44
  end
45
45
 
46
- desc 'exec PIPE_PATH', 'Run the PIPE_PATH pipe file in VLC'
47
- def exec(path)
46
+ desc 'exec path [input_file_1 [input_file_2] [...]]', 'Launch vlc executable to run the pipeline described in path file'
47
+ def exec(path, *inputs)
48
48
  if File.readable?(path)
49
49
  begin
50
- pipe = eval(File.read(path))
50
+ pipe = ActiveVlc::parse(path)
51
+ pipe.inputs << inputs
51
52
  fragment = pipe.fragment
52
53
  rescue
53
54
  puts "Error while parsing pipe file"
@@ -60,7 +61,25 @@ module ActiveVlc
60
61
  exit $?.exitstatus
61
62
  end
62
63
 
63
- desc 'dump PIPE_PATH', 'Dump the internal representation of the pipeline defined in the file PIPE_PATH'
64
+ desc 'run path [input_file_1 [input_file_2] [...]]', 'Run the path pipeline using LibVlc (usually better than exec)'
65
+ def run(path, *inputs)
66
+ if File.readable?(path)
67
+ begin
68
+ pipe = ActiveVlc::parse(path)
69
+ pipe.inputs << inputs
70
+ fragment = pipe.fragment
71
+ rescue
72
+ puts "Error while parsing pipe file"
73
+ exit 43
74
+ end
75
+ ActiveVlc::Runner.new(pipe).run
76
+ else
77
+ puts "Error: file [#{path}] doesn't exist or reading permission denied."
78
+ end
79
+ exit 0
80
+ end
81
+
82
+ desc 'dump path', 'Dump the internal representation of the pipeline defined in the file path'
64
83
  def dump(path)
65
84
  if File.readable?(path)
66
85
  puts eval(File.read(path)).dump
@@ -0,0 +1,196 @@
1
+ ##
2
+ ## api.rb
3
+ ## Login : <lta@still>
4
+ ## Started on Wed Jun 12 14:45:36 2013 Lta Akr
5
+ ## $Id$
6
+ ##
7
+ ## Author(s):
8
+ ## - Lta Akr <>
9
+ ##
10
+ ## Copyright (C) 2013 Lta Akr
11
+
12
+ module ActiveVlc::LibVlc
13
+ def self.version
14
+ Api.libvlc_get_version
15
+ end
16
+ def self.compiler
17
+ Api.libvlc_get_compiler
18
+ end
19
+
20
+ module Api
21
+ extend FFI::Library
22
+ ffi_lib ActiveVlc::LibVlc::VLC_SO_NAMES
23
+
24
+ #
25
+ # Core functions
26
+ #
27
+ callback :exit_handler, [:pointer], :void
28
+
29
+ core_functions = {
30
+ new: [[:int, :pointer], :pointer],
31
+ release: [[:pointer], :void],
32
+ retain: [[:pointer], :void],
33
+ add_intf: [[:pointer, :string], :int],
34
+ set_exit_handler: [[:pointer, :exit_handler, :pointer], :void],
35
+ wait: [[:pointer], :void],
36
+ set_user_agent: [[:pointer, :string, :string], :void],
37
+ get_version: [[], :string],
38
+ get_compiler: [[], :string],
39
+ free: [[:pointer], :void]
40
+ }
41
+
42
+ #
43
+ # Media functions
44
+ #
45
+ media_functions = {
46
+ media_new_location: [[:pointer, :string], :pointer],
47
+ media_new_path: [[:pointer, :string], :pointer],
48
+ media_add_option: [[:pointer, :string], :void],
49
+ media_add_option_flag: [[:pointer, :string, :int], :void],
50
+ media_duplicate: [[:pointer], :pointer],
51
+ media_event_manager: [[:pointer], :pointer],
52
+ media_retain: [[:pointer], :void],
53
+ media_release: [[:pointer], :void],
54
+ media_get_mrl: [[:pointer], :string]
55
+ }
56
+
57
+ #
58
+ # Media List functions
59
+ #
60
+ media_list_functions = {
61
+ media_list_new: [[:pointer], :pointer],
62
+ media_list_retain: [[:pointer], :void],
63
+ media_list_release: [[:pointer], :void],
64
+ media_list_lock: [[:pointer], :void],
65
+ media_list_unlock: [[:pointer], :void],
66
+ media_list_event_manager: [[:pointer], :pointer],
67
+ media_list_set_media: [[:pointer, :pointer], :void],
68
+ media_list_add_media: [[:pointer, :pointer], :int],
69
+ media_list_insert_media: [[:pointer, :pointer, :int], :int],
70
+ media_list_count: [[:pointer], :int]
71
+ }
72
+
73
+
74
+ #
75
+ # Media Player functions and type
76
+ #
77
+ PlayerState = enum(:NothingSpecial,
78
+ :Opening,
79
+ :Buffering,
80
+ :Playing,
81
+ :Paused,
82
+ :Stopped,
83
+ :Ended,
84
+ :Error)
85
+
86
+ media_player_functions = {
87
+ media_player_new: [[:pointer], :pointer],
88
+ media_player_new_from_media: [[:pointer], :pointer],
89
+ media_player_retain: [[:pointer], :void],
90
+ media_player_release: [[:pointer], :void],
91
+ media_player_set_media: [[:pointer, :pointer], :void],
92
+ media_player_get_media: [[:pointer], :pointer],
93
+ media_player_event_manager: [[:pointer], :pointer],
94
+ media_player_is_playing: [[:pointer], :int],
95
+ media_player_play: [[:pointer], :int],
96
+ media_player_pause: [[:pointer], :void],
97
+ media_player_stop: [[:pointer], :void],
98
+ media_player_get_state: [[:pointer], PlayerState]
99
+ }
100
+
101
+ #
102
+ # Media List Player functions
103
+ #
104
+ media_list_player_functions = {
105
+ media_list_player_new: [[:pointer], :pointer],
106
+ media_list_player_retain: [[:pointer], :void],
107
+ media_list_player_release: [[:pointer], :void],
108
+ media_list_player_event_manager: [[:pointer], :pointer],
109
+ media_list_player_set_media_list: [[:pointer, :pointer], :void],
110
+ media_list_player_set_media_player: [[:pointer, :pointer], :void],
111
+ media_list_player_play: [[:pointer], :void],
112
+ media_list_player_pause: [[:pointer], :void],
113
+ media_list_player_stop: [[:pointer], :void],
114
+ media_list_player_next: [[:pointer], :void],
115
+ media_list_player_previous: [[:pointer], :void],
116
+ media_list_player_is_playing: [[:pointer], :int]
117
+ }
118
+
119
+ #
120
+ # Event manager functions and types
121
+ #
122
+ callback :event_handler, [:pointer, :pointer], :void
123
+
124
+ EventType = enum(
125
+ :MediaMetaChanged, 0,
126
+ :MediaSubItemAdded,
127
+ :MediaDurationChanged,
128
+ :MediaParsedChanged,
129
+ :MediaFreed,
130
+ :MediaStateChanged,
131
+
132
+ :MediaPlayerMediaChanged, 0x100,
133
+ :MediaPlayerNothingSpecial,
134
+ :MediaPlayerOpening,
135
+ :MediaPlayerBuffering,
136
+ :MediaPlayerPlaying,
137
+ :MediaPlayerPaused,
138
+ :MediaPlayerStopped,
139
+ :MediaPlayerForward,
140
+ :MediaPlayerBackward,
141
+ :MediaPlayerEndReached,
142
+ :MediaPlayerEncounteredError,
143
+ :MediaPlayerTimeChanged,
144
+ :MediaPlayerPositionChanged,
145
+ :MediaPlayerSeekableChanged,
146
+ :MediaPlayerPausableChanged,
147
+ :MediaPlayerTitleChanged,
148
+ :MediaPlayerSnapshotTaken,
149
+ :MediaPlayerLengthChanged,
150
+ :MediaPlayerVout,
151
+
152
+ :MediaListItemAdded, 0x200,
153
+ :MediaListWillAddItem,
154
+ :MediaListItemDeleted,
155
+ :MediaListWillDeleteItem,
156
+
157
+ :MediaListViewItemAdded, 0x300,
158
+ :MediaListViewWillAddItem,
159
+ :MediaListViewItemDeleted,
160
+ :MediaListViewWillDeleteItem,
161
+
162
+ :MediaListPlayerPlayed, 0x400,
163
+ :MediaListPlayerNextItemSet,
164
+ :MediaListPlayerStopped,
165
+
166
+ :MediaDiscovererStarted, 0x500,
167
+ :MediaDiscovererEnded,
168
+
169
+ :VlmMediaAdded, 0x600,
170
+ :VlmMediaRemoved,
171
+ :VlmMediaChanged,
172
+ :VlmMediaInstanceStarted,
173
+ :VlmMediaInstanceStopped,
174
+ :VlmMediaInstanceStatusInit,
175
+ :VlmMediaInstanceStatusOpening,
176
+ :VlmMediaInstanceStatusPlaying,
177
+ :VlmMediaInstanceStatusPause,
178
+ :VlmMediaInstanceStatusEnd,
179
+ :VlmMediaInstanceStatusError
180
+ )
181
+
182
+ event_manager_functions = {
183
+ event_attach: [[:pointer, EventType, :event_handler, :pointer], :int],
184
+ event_detach: [[:pointer, EventType, :event_handler, :pointer], :void],
185
+ event_type_name: [[:int], :string]
186
+ }
187
+
188
+ # Here we use all these data and actually attache the functions.
189
+ [ core_functions, media_functions, media_list_functions, media_player_functions,
190
+ media_list_player_functions, event_manager_functions].each do |functions|
191
+ functions.each do |symbol, args|
192
+ attach_function "libvlc_#{symbol}".to_sym, args[0], args[1]
193
+ end
194
+ end
195
+ end
196
+ end
@@ -0,0 +1,53 @@
1
+ module ActiveVlc::LibVlc
2
+ class Event < FFI::Struct
3
+ layout :type, :int,
4
+ :object, :pointer
5
+ end
6
+
7
+ class EventManager
8
+ EventType = Api::EventType
9
+
10
+ attr_reader :callbacks, :events_received
11
+
12
+ def initialize(ptr)
13
+ @ptr = ptr
14
+ @callbacks = {}
15
+ @events_received = 0
16
+
17
+ @event_handler = Proc.new { |event, void| _event(event, void) }
18
+ end
19
+
20
+ def on(types, &block)
21
+ event_is_valid = true
22
+ types = [types] unless types.is_a? Array
23
+ # Get the enum value if we gat a Symbol or String
24
+
25
+ types.each do |type|
26
+ if type.is_a?(String) or type.is_a?(Symbol)
27
+ type = EventType[type.to_sym]
28
+ end
29
+
30
+ # If this is the first callback for this type, register the :event_handler
31
+ # using vlc's API and create the proc array for that 'type'.
32
+ unless @callbacks[type]
33
+ event_is_valid = Api.libvlc_event_attach(@ptr, type, @event_handler, nil) == 0
34
+ @callbacks[type] = Array.new if event_is_valid
35
+ end
36
+ @callbacks[type].push block if event_is_valid
37
+ end
38
+ end
39
+
40
+ protected
41
+ def _event(event, void)
42
+ event = Event.new(event)
43
+ type = EventType[event[:type]]
44
+
45
+ @events_received += 1;
46
+
47
+ puts "Received event (#{@events_received}): #{EventType[event[:type]]}"
48
+
49
+ return unless @callbacks[event[:type]].is_a? Array
50
+ @callbacks[event[:type]].each { |proc| proc.call(type) }
51
+ end
52
+ end
53
+ end