activevlc 0.0.1 → 0.0.3
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.
- checksums.yaml +4 -4
- data/.travis.yml +6 -0
- data/README.md +81 -26
- data/Rakefile +5 -0
- data/TODO.md +0 -1
- data/activevlc.gemspec +3 -2
- data/examples/basic.rb +14 -0
- data/examples/duplicate.rb +18 -0
- data/examples/duplicate_then_transcode.rb +29 -0
- data/examples/transcode_and_display.rb +25 -0
- data/examples/transcode_and_display_with_options.rb +36 -0
- data/lib/activevlc/cli.rb +25 -6
- data/lib/activevlc/libvlc/api.rb +196 -0
- data/lib/activevlc/libvlc/event_manager.rb +53 -0
- data/lib/activevlc/libvlc/instance.rb +71 -0
- data/lib/activevlc/libvlc/media.rb +32 -0
- data/lib/activevlc/libvlc/media_list.rb +55 -0
- data/lib/activevlc/libvlc/media_list_player.rb +64 -0
- data/lib/activevlc/libvlc/media_player.rb +63 -0
- data/lib/activevlc/libvlc.rb +33 -0
- data/lib/activevlc/pipeline.rb +4 -2
- data/lib/activevlc/pipeline_dump.rb +0 -2
- data/lib/activevlc/runner.rb +71 -0
- data/lib/activevlc/stage/input.rb +1 -0
- data/lib/activevlc/syntactic_sugar.rb +11 -0
- data/lib/activevlc/version.rb +1 -1
- data/lib/activevlc.rb +6 -3
- data/spec/event_manager_spec.rb +81 -0
- data/spec/libvlc_spec.rb +93 -0
- data/spec/pipeline_spec.rb +20 -1
- data/spec/pipes/no_input.rb +20 -0
- data/spec/pipes/transcode_and_display.rb +1 -1
- data/spec/runner_spec.rb +34 -0
- data/spec/samples/click.wav +0 -0
- data/spec/spec_helper.rb +24 -11
- metadata +34 -9
- data/examples/design.rb +0 -84
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e7277724b68e5a47757cd221b47c6522bc74cf0c
|
4
|
+
data.tar.gz: 19a56e502c9d73feb2c0fdeb114dcaf98162d665
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eaf8db920f751616a47ba9a46bcc252684d04120cf82703071ce66f6bf46fa9896165f26c383fa66866b453c3a27a6f0aa139ee8a542a4238dfa4084c5887014
|
7
|
+
data.tar.gz: 01bf1845e930f5ad7ee4cf4e0a929a869b986e1fb3ddc94f8c33547d4dff0d6ea782906ce1f84e958151cd479de2d88360e62de7ee5e5e8b2b49071dc7da2f22
|
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -1,25 +1,54 @@
|
|
1
1
|
# ActiveVlc
|
2
2
|
|
3
|
-
|
3
|
+
[](http://badge.fury.io/rb/activevlc)
|
4
|
+
[](https://codeclimate.com/github/elthariel/activevlc)
|
5
|
+
[](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
|
-
|
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::
|
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
|
-
|
58
|
-
development althought it might already be usable for many usages
|
84
|
+
### From Ruby code
|
59
85
|
|
60
|
-
|
86
|
+
You can also use ActiveVlc programmatically from your ruby code :
|
61
87
|
|
62
|
-
|
63
|
-
|
64
|
-
|
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
|
-
|
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
|
-
|
104
|
+
## Development status
|
69
105
|
|
70
|
-
|
106
|
+
This gem is still under active development
|
107
|
+
althought it might already be usable for many usages.
|
71
108
|
|
72
|
-
|
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
|
-
|
113
|
+
## Supported system/rubies
|
75
114
|
|
76
|
-
|
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.
|
88
|
-
4.
|
89
|
-
5.
|
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
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.
|
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
|
32
|
+
desc 'vlc ', 'VLC specific commands. See activevlc help vlc for details'
|
33
33
|
subcommand 'vlc', ActiveVlc::CLI::Vlc
|
34
34
|
|
35
|
-
desc 'fragment
|
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
|
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 =
|
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 '
|
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
|