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
@@ -0,0 +1,71 @@
|
|
1
|
+
module ActiveVlc::LibVlc
|
2
|
+
# This is just a hack to have the libvlc_instance released when
|
3
|
+
# the Instance class is GC'ed
|
4
|
+
class InstancePtr < FFI::ManagedStruct
|
5
|
+
layout :nothing, :pointer
|
6
|
+
|
7
|
+
def self.release(ptr)
|
8
|
+
#puts "Releasing an InstancePtr #{ptr.inspect}"
|
9
|
+
Api.libvlc_release(ptr)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class Instance
|
14
|
+
attr_reader :exit_callback, :ptr
|
15
|
+
|
16
|
+
def initialize(args = [""])
|
17
|
+
argc = args.length
|
18
|
+
@argv = args.map{ |a| FFI::MemoryPointer.from_string a}
|
19
|
+
test = FFI::MemoryPointer.new(:pointer, argc)
|
20
|
+
test.put_array_of_pointer(0, @argv)
|
21
|
+
|
22
|
+
@ptr = InstancePtr.new Api.libvlc_new(argc, test)
|
23
|
+
raise "Unable to create a libvlc_instance_t" if @ptr.null?
|
24
|
+
end
|
25
|
+
|
26
|
+
def create_media(mrl)
|
27
|
+
if mrl =~ /\A[a-z]+:\/\/.+/
|
28
|
+
m = Api.libvlc_media_new_location(@ptr, mrl)
|
29
|
+
else
|
30
|
+
m = Api.libvlc_media_new_path(@ptr, mrl)
|
31
|
+
end
|
32
|
+
raise "Unable to create a libvlc_media_t" if m.null?
|
33
|
+
Media.new(m, mrl)
|
34
|
+
end
|
35
|
+
|
36
|
+
def create_media_list
|
37
|
+
ml = Api.libvlc_media_list_new(@ptr)
|
38
|
+
raise "Unable to create a libvlc_media_list_t" if ml.null?
|
39
|
+
MediaList.new(ml)
|
40
|
+
end
|
41
|
+
|
42
|
+
def create_list_player(list = nil, player = nil)
|
43
|
+
mlp = Api.libvlc_media_list_player_new(@ptr)
|
44
|
+
raise "Unable to create a libvlc_media_list_player_t" if mlp.null?
|
45
|
+
MediaListPlayer.new(mlp, list, player)
|
46
|
+
end
|
47
|
+
|
48
|
+
def create_player(media = nil)
|
49
|
+
if media and media.is_a?(Media)
|
50
|
+
MediaPlayer.new(media)
|
51
|
+
else
|
52
|
+
MediaPlayer.new self
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def wait!
|
57
|
+
Api.libvlc_wait(@ptr)
|
58
|
+
end
|
59
|
+
|
60
|
+
def at_exit(&block)
|
61
|
+
Api.libvlc_set_exit_handler(@ptr, nil, nil)
|
62
|
+
@exit_callback = block
|
63
|
+
Api.libvlc_set_exit_handler(@ptr, @exit_callback, nil)
|
64
|
+
end
|
65
|
+
|
66
|
+
def add_interface(name = nil)
|
67
|
+
Api.libvlc_add_intf(@ptr, name)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module ActiveVlc::LibVlc
|
2
|
+
# See InstancePtr in instance.rb
|
3
|
+
class MediaPtr < FFI::ManagedStruct
|
4
|
+
layout :nothing, :pointer
|
5
|
+
|
6
|
+
def self.release(ptr)
|
7
|
+
# puts "Releasing a MediaPtr #{ptr.inspect}"
|
8
|
+
Api.libvlc_media_release(ptr)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class Media
|
13
|
+
attr_reader :ptr, :mrl
|
14
|
+
|
15
|
+
def initialize(ptr, mrl)
|
16
|
+
@ptr = MediaPtr.new(ptr)
|
17
|
+
@mrl = mrl
|
18
|
+
end
|
19
|
+
|
20
|
+
def <<(option)
|
21
|
+
raise "option must be a String" unless option.is_a?(String)
|
22
|
+
|
23
|
+
Api.libvlc_media_add_option(@ptr, option)
|
24
|
+
self
|
25
|
+
end
|
26
|
+
|
27
|
+
def event_manager
|
28
|
+
EventManager.new Api.libvlc_media_event_manager(@ptr)
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module ActiveVlc::LibVlc
|
2
|
+
# See InstancePtr in instance.rb
|
3
|
+
class MediaListPtr < FFI::ManagedStruct
|
4
|
+
layout :media_list, :pointer
|
5
|
+
|
6
|
+
def self.release(ptr)
|
7
|
+
# puts "Releasing an MediaListPtr"
|
8
|
+
Api.libvlc_media_list_release(ptr)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class MediaList
|
13
|
+
attr_reader :ptr
|
14
|
+
|
15
|
+
def initialize(ptr)
|
16
|
+
@ptr = MediaListPtr.new(ptr)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Execute the given block with the media_list lock acquired.
|
20
|
+
def locked!
|
21
|
+
if block_given?
|
22
|
+
_lock!
|
23
|
+
res = yield
|
24
|
+
_unlock!
|
25
|
+
res
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def event_manager
|
30
|
+
EventManager.new Api.libvlc_media_list_event_manager(@ptr)
|
31
|
+
end
|
32
|
+
|
33
|
+
def media=(media)
|
34
|
+
Api.libvlc_media_list_set_media(@ptr, media.ptr)
|
35
|
+
end
|
36
|
+
|
37
|
+
def <<(media)
|
38
|
+
locked! { Api.libvlc_media_list_add_media(@ptr, media.ptr) }
|
39
|
+
end
|
40
|
+
|
41
|
+
def length
|
42
|
+
locked! { Api.libvlc_media_list_count(@ptr) }
|
43
|
+
end
|
44
|
+
|
45
|
+
protected
|
46
|
+
def _lock!
|
47
|
+
Api.libvlc_media_list_lock(@ptr)
|
48
|
+
end
|
49
|
+
def _unlock!
|
50
|
+
Api.libvlc_media_list_unlock(@ptr)
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module ActiveVlc::LibVlc
|
2
|
+
class MediaListPlayerPtr < FFI::ManagedStruct
|
3
|
+
layout :nothing, :pointer
|
4
|
+
|
5
|
+
def self.release(ptr)
|
6
|
+
# puts "Releasing a MediaListPlayerPtr #{ptr.inspect}"
|
7
|
+
Api.libvlc_media_list_player_release(ptr)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class MediaListPlayer
|
12
|
+
attr_reader :ptr, :player, :list
|
13
|
+
|
14
|
+
def initialize(ptr, media_list = nil, media_player = nil)
|
15
|
+
@ptr = MediaListPlayerPtr.new(ptr)
|
16
|
+
@list = media_list
|
17
|
+
@player = media_player
|
18
|
+
|
19
|
+
self.media_list = media_list if media_list
|
20
|
+
self.media_player = media_player if media_player
|
21
|
+
end
|
22
|
+
|
23
|
+
def media_list=(list)
|
24
|
+
if list and list.is_a?(MediaList)
|
25
|
+
@list = list
|
26
|
+
Api.libvlc_media_list_player_set_media_list(@ptr, list.ptr)
|
27
|
+
else
|
28
|
+
raise "You must provide a valid MediaList"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def event_manager
|
33
|
+
EventManager.new Api.libvlc_media_list_player_event_manager(@ptr)
|
34
|
+
end
|
35
|
+
|
36
|
+
def playing?
|
37
|
+
Api.libvlc_media_list_player_is_playing(@ptr) != 0
|
38
|
+
end
|
39
|
+
|
40
|
+
def media_player=(player)
|
41
|
+
if player.is_a?(MediaPlayer) and not playing?
|
42
|
+
raise "Player already has a media" if player.media
|
43
|
+
@player = player
|
44
|
+
Api.libvlc_media_list_player_set_media_player(@ptr, player.ptr)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def play
|
49
|
+
Api.libvlc_media_list_player_play(@ptr)
|
50
|
+
end
|
51
|
+
def pause
|
52
|
+
Api.libvlc_media_list_player_pause(@ptr)
|
53
|
+
end
|
54
|
+
def stop
|
55
|
+
Api.libvlc_media_list_player_stop(@ptr)
|
56
|
+
end
|
57
|
+
def next
|
58
|
+
Api.libvlc_media_list_player_next(@ptr)
|
59
|
+
end
|
60
|
+
def previous
|
61
|
+
Api.libvlc_media_list_player_previous(@ptr)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module ActiveVlc::LibVlc
|
2
|
+
# See InstancePtr in instance.rb
|
3
|
+
class MediaPlayerPtr < FFI::ManagedStruct
|
4
|
+
layout :media_list, :pointer
|
5
|
+
|
6
|
+
def self.release(ptr)
|
7
|
+
# puts "Releasing an MediaPlayerPtr"
|
8
|
+
Api.libvlc_media_player_release(ptr)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class MediaPlayer
|
13
|
+
attr_reader :ptr, :media
|
14
|
+
|
15
|
+
def initialize(vlc_or_media)
|
16
|
+
@media = nil
|
17
|
+
if vlc_or_media.is_a?(Media)
|
18
|
+
@media = vlc_or_media
|
19
|
+
@ptr = Api.libvlc_media_player_new_from_media(vlc_or_media.ptr)
|
20
|
+
else
|
21
|
+
@ptr = Api.libvlc_media_player_new(vlc_or_media.ptr)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def event_manager
|
26
|
+
event_manger = Api.libvlc_media_player_event_manager(@ptr)
|
27
|
+
raise "Unable to get EventManager for MediaPlayer #{@ptr.inspect}" unless event_manger
|
28
|
+
EventManager.new event_manger
|
29
|
+
end
|
30
|
+
|
31
|
+
def media=(new_media)
|
32
|
+
raise "You must provide a valid Media" unless new_media and new_media.is_a?(Media)
|
33
|
+
@media = new_media
|
34
|
+
Api.libvlc_media_player_set_media(@ptr, @media.ptr)
|
35
|
+
end
|
36
|
+
|
37
|
+
def play
|
38
|
+
if_media { Api.libvlc_media_player_play @ptr }
|
39
|
+
end
|
40
|
+
def stop
|
41
|
+
if_media { Api.libvlc_media_player_stop @ptr }
|
42
|
+
end
|
43
|
+
def pause
|
44
|
+
if_media { Api.libvlc_media_player_pause @ptr}
|
45
|
+
end
|
46
|
+
|
47
|
+
def playing?
|
48
|
+
Api.libvlc_media_player_is_playing @ptr
|
49
|
+
end
|
50
|
+
|
51
|
+
def state
|
52
|
+
Api.libvlc_media_player_get_state @ptr
|
53
|
+
end
|
54
|
+
|
55
|
+
protected
|
56
|
+
def if_media
|
57
|
+
if block_given?
|
58
|
+
raise "MediaPlayer: No media set" unless @media
|
59
|
+
yield
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
##
|
2
|
+
## libvlc.rb
|
3
|
+
## Login : <lta@still>
|
4
|
+
## Started on Wed Jun 12 20:46:52 2013 Lta Akr
|
5
|
+
## $Id$
|
6
|
+
##
|
7
|
+
## Author(s):
|
8
|
+
## - Lta Akr <>
|
9
|
+
##
|
10
|
+
## Copyright (C) 2013 Lta Akr
|
11
|
+
|
12
|
+
require "ffi"
|
13
|
+
|
14
|
+
module ActiveVlc
|
15
|
+
module LibVlc
|
16
|
+
VLC_SO_NAMES = [
|
17
|
+
'libvlc'.freeze,
|
18
|
+
'libvlc.so.5'.freeze
|
19
|
+
].freeze
|
20
|
+
VLCCORE_SO_NAMES = [
|
21
|
+
'libvlccore'.freeze,
|
22
|
+
'libvlccore.so.5'.freeze
|
23
|
+
].freeze
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
require 'activevlc/libvlc/api'
|
28
|
+
require 'activevlc/libvlc/media'
|
29
|
+
require 'activevlc/libvlc/instance'
|
30
|
+
require 'activevlc/libvlc/media_player'
|
31
|
+
require 'activevlc/libvlc/media_list'
|
32
|
+
require 'activevlc/libvlc/media_list_player'
|
33
|
+
require 'activevlc/libvlc/event_manager'
|
data/lib/activevlc/pipeline.rb
CHANGED
@@ -20,9 +20,11 @@ module ActiveVlc
|
|
20
20
|
|
21
21
|
attr_reader :input, :sout
|
22
22
|
|
23
|
-
def initialize(input_array_or_string)
|
23
|
+
def initialize(input_array_or_string = nil, &block)
|
24
24
|
@input = Stage::Input.new(input_array_or_string)
|
25
|
-
@sout = Stage::Stream.new
|
25
|
+
@sout = Stage::Stream.new # SOut = Stream Out
|
26
|
+
|
27
|
+
::ActiveVlc::DSL::Stream.new(@sout).instance_eval(&block) if block_given?
|
26
28
|
end
|
27
29
|
|
28
30
|
def fragment
|
@@ -0,0 +1,71 @@
|
|
1
|
+
#
|
2
|
+
# Small note about this file code's coverage
|
3
|
+
# Since most of the code is wan in another process
|
4
|
+
# (see #run), the code coverage cannot be reported.
|
5
|
+
# This file have around 100% of test code coverage
|
6
|
+
#
|
7
|
+
module ActiveVlc
|
8
|
+
class Runner
|
9
|
+
def initialize(pipeline, *args)
|
10
|
+
@pipeline = pipeline
|
11
|
+
@args = args
|
12
|
+
end
|
13
|
+
|
14
|
+
# Nobody can escape his faith.
|
15
|
+
def stop_runner!
|
16
|
+
@running = false
|
17
|
+
end
|
18
|
+
|
19
|
+
def run(fork = false)
|
20
|
+
if fork and Process.respond_to? :fork
|
21
|
+
pid = Process.fork { _run }
|
22
|
+
Process.wait pid
|
23
|
+
else
|
24
|
+
_run
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
protected
|
29
|
+
# Here we setup the media/list/player/event_manager
|
30
|
+
# to run the pipeline using LibVlc. There's a big unavoidable
|
31
|
+
# hack to run synchronously / 'join' the libvlc instance.
|
32
|
+
def _run
|
33
|
+
# Preparing instance/list/player/sout fragment/event manager
|
34
|
+
@api = LibVlc::Instance.new @args
|
35
|
+
sout = @pipeline.sout.fragment
|
36
|
+
list = @api.create_media_list
|
37
|
+
player = @api.create_player
|
38
|
+
events = player.event_manager
|
39
|
+
|
40
|
+
sout.gsub!('\'', '').gsub!('"', '')
|
41
|
+
|
42
|
+
# Building the medias with the right options
|
43
|
+
medias = @pipeline.input.inputs.map do |input|
|
44
|
+
#puts sout
|
45
|
+
@api.create_media(input) << sout
|
46
|
+
end
|
47
|
+
medias.each { |media| list << media }
|
48
|
+
list_player = @api.create_list_player list, player
|
49
|
+
|
50
|
+
# Set callbacks to 'know' when the processing is over
|
51
|
+
stop_events = [
|
52
|
+
:MediaPlayerPaused,
|
53
|
+
:MediaPlayerStopped,
|
54
|
+
:MediaPlayerEndReached,
|
55
|
+
:MediaPlayerEncounteredError
|
56
|
+
]
|
57
|
+
events.on(stop_events) { stop_runner! }
|
58
|
+
|
59
|
+
# Let's rock and roll
|
60
|
+
list_player.play
|
61
|
+
|
62
|
+
# Busy Wait loop hack to synchronize with libvlc which doesn't have
|
63
|
+
# any synchronous interface (due to it's profound asynchronous nature)
|
64
|
+
@running = true
|
65
|
+
while @running
|
66
|
+
sleep 0.5
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
data/lib/activevlc/version.rb
CHANGED
data/lib/activevlc.rb
CHANGED
@@ -1,7 +1,10 @@
|
|
1
|
+
module ActiveVlc
|
2
|
+
end
|
3
|
+
|
1
4
|
require 'active_support'
|
2
5
|
require 'activevlc/version'
|
3
6
|
require 'activevlc/pipeline'
|
4
7
|
require 'activevlc/dsl'
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
+
require 'activevlc/libvlc'
|
9
|
+
require 'activevlc/runner'
|
10
|
+
require 'activevlc/syntactic_sugar'
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe ActiveVlc::LibVlc::EventManager do
|
4
|
+
let(:vlc) { ActiveVlc::LibVlc::Instance.new [' ', '--play-and-exit'] }
|
5
|
+
let(:media) { vlc.create_media 'file:///tmp/test.mp4' }
|
6
|
+
let(:media2) { vlc.create_media '/tmp/test2.mp4' }
|
7
|
+
let(:player) { vlc.create_player }
|
8
|
+
let(:list) do
|
9
|
+
l = vlc.create_media_list
|
10
|
+
l << media
|
11
|
+
l << media2
|
12
|
+
l
|
13
|
+
end
|
14
|
+
let(:list_player) do
|
15
|
+
lp = vlc.create_list_player
|
16
|
+
lp.media_list = list
|
17
|
+
lp
|
18
|
+
end
|
19
|
+
let(:player_event) { player.event_manager }
|
20
|
+
let(:list_player_event) { list_player.event_manager }
|
21
|
+
|
22
|
+
it 'can be created' do
|
23
|
+
media.event_manager.should be_a_kind_of(ActiveVlc::LibVlc::EventManager)
|
24
|
+
list.event_manager.should be_a_kind_of(ActiveVlc::LibVlc::EventManager)
|
25
|
+
player.event_manager.should be_a_kind_of(ActiveVlc::LibVlc::EventManager)
|
26
|
+
list_player.event_manager.should be_a_kind_of(ActiveVlc::LibVlc::EventManager)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'registers and stores callbacks' do
|
30
|
+
event1 = ActiveVlc::LibVlc::Api::EventType[:MediaListPlayerStopped]
|
31
|
+
event2 = ActiveVlc::LibVlc::EventManager::EventType[:MediaListPlayerPlayed]
|
32
|
+
list_player_event.callbacks.keys.length.should eq(0)
|
33
|
+
list_player_event.on(event1) {}
|
34
|
+
list_player_event.on(event2) {}
|
35
|
+
list_player_event.on(:MediaListPlayerNextItemSet) {}
|
36
|
+
# For some reason the 'Played' event is invalid :-/ and the Stopped event
|
37
|
+
# is only triggered on very recent versions ...
|
38
|
+
list_player_event.callbacks.keys.length.should be >= 1
|
39
|
+
list_player.play
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'MediaPlayer\'s EventManger receives events' do
|
43
|
+
first_event = ActiveVlc::LibVlc::Api::EventType[:MediaPlayerMediaChanged]
|
44
|
+
last_event = ActiveVlc::LibVlc::Api::EventType[:MediaPlayerVout]
|
45
|
+
(first_event..last_event).to_a.each { |e| player_event.on(e) {} }
|
46
|
+
player.media = media
|
47
|
+
player_event.events_received.should eq(1)
|
48
|
+
player.play
|
49
|
+
sleep 0.25 # Avoid random deadlock in vlc :-/ and gives some time for vlc to run
|
50
|
+
player.stop
|
51
|
+
player_event.events_received.should eq(5)
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'MediaListPlayer\'s EventManger receives events' do
|
55
|
+
list_player_event.on(:MediaListPlayerNextItemSet) {}
|
56
|
+
list_player_event.on(:MediaListPlayerStopped) {}
|
57
|
+
list_player.play
|
58
|
+
list_player.stop
|
59
|
+
list_player_event.events_received.should be >= 1
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'calls registered callback' do
|
63
|
+
@cbk1_called = false
|
64
|
+
list_player_event.on(:MediaListPlayerNextItemSet) { @cbk1_called = true }
|
65
|
+
list_player.play
|
66
|
+
list_player.stop
|
67
|
+
@cbk1_called.should be_true
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'MediaPlayer receives event when assigned as MediaListPlayer\' player' do
|
71
|
+
first_event = ActiveVlc::LibVlc::Api::EventType[:MediaPlayerMediaChanged]
|
72
|
+
last_event = ActiveVlc::LibVlc::Api::EventType[:MediaPlayerVout]
|
73
|
+
(first_event..last_event).to_a.each { |e| player_event.on(e) {} }
|
74
|
+
list_player.media_player = player
|
75
|
+
list_player.play
|
76
|
+
sleep 0.25
|
77
|
+
list_player.stop
|
78
|
+
player_event.events_received.should eq(5)
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
data/spec/libvlc_spec.rb
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe ActiveVlc::LibVlc do
|
5
|
+
describe "Low-level binding" do
|
6
|
+
it 'binds C functions' do
|
7
|
+
[ :new, :release, :retain, :add_intf, :wait, :set_user_agent,
|
8
|
+
:get_version, :get_compiler, :free, :set_exit_handler ].each do |sym|
|
9
|
+
ActiveVlc::LibVlc::Api.respond_to?("libvlc_#{sym}")
|
10
|
+
.should be_true
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'create a libvlc instance' do
|
15
|
+
vlc = ActiveVlc::LibVlc::Api.libvlc_new(0, nil)
|
16
|
+
vlc.null?.should be_false
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'reports libvlc version' do
|
20
|
+
ActiveVlc::LibVlc::Api.libvlc_get_version.should match(/\d\.\d+\.\d+/)
|
21
|
+
ActiveVlc::LibVlc.version.should match(/\d\.\d+\.\d+/)
|
22
|
+
ActiveVlc::LibVlc.compiler.should match(/\d\.\d+\.\d+/)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe 'Ruby wrapper: Instance/MediaXXX/EventManger creation' do
|
27
|
+
let(:vlc) { ActiveVlc::LibVlc::Instance.new [' ', '--play-and-exit'] }
|
28
|
+
let(:media) { vlc.create_media 'file:///tmp/test.mp4' }
|
29
|
+
let(:media2) { vlc.create_media '/tmp/test2.mp4' }
|
30
|
+
let(:list) { vlc.create_media_list }
|
31
|
+
let(:list_player) { vlc.create_list_player }
|
32
|
+
|
33
|
+
it 'can creates an instance' do
|
34
|
+
vlc.should be_a_kind_of(ActiveVlc::LibVlc::Instance)
|
35
|
+
vlc.ptr.null?.should be_false
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'can creates a Media from an Instance using an MRL' do
|
39
|
+
media.should be_a_kind_of(ActiveVlc::LibVlc::Media)
|
40
|
+
media.ptr.null?.should be_false
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'can creates a Media from an Instance using a path' do
|
44
|
+
media_from_path = vlc.create_media('/tmp/pwet')
|
45
|
+
media_from_path.should be_a_kind_of(ActiveVlc::LibVlc::Media)
|
46
|
+
media_from_path.ptr.null?.should be_false
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'can set an option on a Media' do
|
50
|
+
media << ":sout='#display'"
|
51
|
+
expect { media << 42 }.to raise_error
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'can creates a MediaList from an Instance' do
|
55
|
+
list.should be_a_kind_of(ActiveVlc::LibVlc::MediaList)
|
56
|
+
list.ptr.null?.should be_false
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'allows setting media of a media list' do
|
60
|
+
list << media2
|
61
|
+
list.media = media
|
62
|
+
list.length.should eq(1)
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'allows adding media to a MediaList' do
|
66
|
+
list << media
|
67
|
+
list << media2
|
68
|
+
list.length.should eq(2)
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'allows the creation of a MediaListPlayer' do
|
72
|
+
list_player.should be_a_kind_of(ActiveVlc::LibVlc::MediaListPlayer)
|
73
|
+
list_player.ptr.null?.should be_false
|
74
|
+
list << media
|
75
|
+
list_player.media_list = list
|
76
|
+
expect {list_player.media_list = nil}.to raise_error
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'allows creation of a MediaPlayer with an Instance' do
|
80
|
+
player = vlc.create_player
|
81
|
+
player.should be_a_kind_of(ActiveVlc::LibVlc::MediaPlayer)
|
82
|
+
player.ptr.null?.should be_false
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'allows creation of a MediaPlayer with a Media' do
|
86
|
+
player = vlc.create_player media
|
87
|
+
player.should be_a_kind_of(ActiveVlc::LibVlc::MediaPlayer)
|
88
|
+
player.ptr.null?.should be_false
|
89
|
+
player.media.should be_a_kind_of(ActiveVlc::LibVlc::Media)
|
90
|
+
player.media.should be(media)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
data/spec/pipeline_spec.rb
CHANGED
@@ -71,7 +71,7 @@ describe ActiveVlc::Pipeline do
|
|
71
71
|
|
72
72
|
describe '\'duplicate_then_transcode\' pipeline' do
|
73
73
|
it 'is loaded' do
|
74
|
-
ActiveVlc::Pipeline
|
74
|
+
ActiveVlc::Pipeline::parse('spec/pipes/duplicate_then_transcode.rb').class
|
75
75
|
.should be(ActiveVlc::Pipeline)
|
76
76
|
end
|
77
77
|
|
@@ -81,4 +81,23 @@ describe ActiveVlc::Pipeline do
|
|
81
81
|
end
|
82
82
|
end
|
83
83
|
|
84
|
+
describe '\'no_input\' pipeline' do
|
85
|
+
it "is loaded" do
|
86
|
+
ActiveVlc::parse('spec/pipes/no_input.rb').class
|
87
|
+
.should be(ActiveVlc::Pipeline)
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'produce the correct fragment' do
|
91
|
+
expect(ActiveVlc::parse('spec/pipes/no_input.rb').fragment)
|
92
|
+
.to eq(" :sout=\"#transcode{acodec=vorbis}:standard{mux=ogg, dst='output.ogg'}\"")
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'can be assigned inputs' do
|
96
|
+
pipe = ActiveVlc::parse('spec/pipes/no_input.rb')
|
97
|
+
pipe.input << "input.mp4"
|
98
|
+
pipe.input << "input2.mp4"
|
99
|
+
pipe.fragment.should eq("input.mp4 input2.mp4 :sout=\"#transcode{acodec=vorbis}:standard{mux=ogg, dst='output.ogg'}\"")
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
84
103
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
##
|
2
|
+
## no_input.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 do
|
13
|
+
transcode do
|
14
|
+
audio :vorbis
|
15
|
+
end
|
16
|
+
to(:file) do
|
17
|
+
mux :ogg
|
18
|
+
dst 'output.ogg'
|
19
|
+
end
|
20
|
+
end
|