clutter-gstreamer 2.0.2 → 2.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Rakefile +2 -1
- data/lib/clutter-gst.rb +1 -1
- data/sample/media-actions-pause.png +0 -0
- data/sample/media-actions-start.png +0 -0
- data/sample/vid-panel.png +0 -0
- data/sample/video-player.rb +383 -0
- data/sample/video-sink-navigation.rb +99 -0
- data/sample/video-sink.rb +88 -0
- data/test/run-test.rb +10 -2
- data/test/test-clutter-gst.rb +23 -0
- metadata +21 -22
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: de50d5902f788eae4af9d33e9c0298dfdaf4ae04
|
4
|
+
data.tar.gz: fddb5322c7a78e14fae279be768e51e02e0ce307
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a9919fe3c945f32de4be3bb53c98e149d6921850809163854af9f2fcd7be8c682ebccc3b550b90225d9d1726b1655f1fc4e740bfc6c0b2b38e0e4ca789e1b50e
|
7
|
+
data.tar.gz: 0c18308da9ee260abad972c9d54b3c55a682395f62ab76cc112d465a2cbc695f18a45a5fe36f9b6da55fabd4656bcc5185a958e764615fffcc28eae09d3537a2
|
data/Rakefile
CHANGED
@@ -46,12 +46,13 @@ package_task = GNOME2::Rake::PackageTask.new do |package|
|
|
46
46
|
:name => "clutter-gst",
|
47
47
|
:download_site => :gnome,
|
48
48
|
:label => "Clutter-GStreamer",
|
49
|
-
:version => "2.0.
|
49
|
+
:version => "2.0.8",
|
50
50
|
:compression_method => "xz",
|
51
51
|
:windows => {
|
52
52
|
:configure_args => [
|
53
53
|
"--enable-introspection",
|
54
54
|
],
|
55
|
+
:built_file => "bin/libclutter-gst-2.0-0.dll",
|
55
56
|
},
|
56
57
|
}
|
57
58
|
]
|
data/lib/clutter-gst.rb
CHANGED
@@ -64,7 +64,7 @@ module ClutterGst
|
|
64
64
|
1 + @init_arguments.size,
|
65
65
|
[$0] + @init_arguments,
|
66
66
|
]
|
67
|
-
error, argc, argv = init.invoke(arguments)
|
67
|
+
error, argc, argv = init.invoke(:arguments => arguments)
|
68
68
|
@init_arguments.replace(argv)
|
69
69
|
if error.to_i <= 0
|
70
70
|
raise InitError, "failed to initialize Clutter-GStreamer: #{error.name}"
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,383 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This sample code is a port of clutter-gst/examples/video-player.c. The
|
4
|
+
# image files used in this sample code are copied from clutter-gst/examples.
|
5
|
+
# They are licensed under the terms of the GNU Lesser General Public
|
6
|
+
# License, version 2.1 or (at your option) later.
|
7
|
+
#
|
8
|
+
# The original header:
|
9
|
+
# video-player.c - A simple video player with an OSD.
|
10
|
+
#
|
11
|
+
# Copyright (C) 2007,2008 OpenedHand
|
12
|
+
# Copyright (C) 2013 Collabora
|
13
|
+
#
|
14
|
+
# Copyright (C) 2013 Ruby-GNOME2 Project Team
|
15
|
+
#
|
16
|
+
# This library is free software; you can redistribute it and/or
|
17
|
+
# modify it under the terms of the GNU Lesser General Public
|
18
|
+
# License as published by the Free Software Foundation; either
|
19
|
+
# version 2.1 of the License, or (at your option) any later version.
|
20
|
+
#
|
21
|
+
# This library is distributed in the hope that it will be useful,
|
22
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
23
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
24
|
+
# Lesser General Public License for more details.
|
25
|
+
#
|
26
|
+
# You should have received a copy of the GNU Lesser General Public
|
27
|
+
# License along with this library; if not, write to the Free Software
|
28
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
29
|
+
|
30
|
+
# NOTE: This sample code is for libclutter-gst (a library by C) 2.0.2.
|
31
|
+
|
32
|
+
require "optparse"
|
33
|
+
|
34
|
+
require "clutter-gst"
|
35
|
+
|
36
|
+
SEEK_H = 14
|
37
|
+
SEEK_W = 440
|
38
|
+
|
39
|
+
GST_PLAY_FLAG_VIS = (1 << 3)
|
40
|
+
|
41
|
+
class VideoApp
|
42
|
+
attr_accessor :stage
|
43
|
+
attr_accessor :vtexture
|
44
|
+
attr_accessor :control, :control_bg, :control_label
|
45
|
+
attr_accessor :control_play, :control_pause
|
46
|
+
attr_accessor :control_seek1, :control_seek2, :control_seekbar
|
47
|
+
attr_accessor :controls_showing, :paused, :mouse_in_window
|
48
|
+
attr_accessor :controls_timeout
|
49
|
+
def initialize
|
50
|
+
@controls_showing = false
|
51
|
+
@paused = false
|
52
|
+
@mouse_in_window = false
|
53
|
+
@controls_timeout = 0
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
opt_fullscreen = false
|
58
|
+
opt_loop = false
|
59
|
+
|
60
|
+
parser = OptionParser.new
|
61
|
+
parser.on("-f", "--[no-]fullscreen",
|
62
|
+
"Start the player in fullscreen",
|
63
|
+
"(#{opt_fullscreen})") do |boolean|
|
64
|
+
opt_fullscreen = boolean
|
65
|
+
end
|
66
|
+
parser.on("-l", "--[no-]loop",
|
67
|
+
"Start the video again once reached EOS",
|
68
|
+
"(#{opt_loop})") do |boolean|
|
69
|
+
opt_loop = boolean
|
70
|
+
end
|
71
|
+
parser.parse!
|
72
|
+
|
73
|
+
def controls_timeout_cb(app)
|
74
|
+
app.controls_timeout = 0
|
75
|
+
show_controls(app, false)
|
76
|
+
false
|
77
|
+
end
|
78
|
+
|
79
|
+
def actor_animate(actor, mode, duration, first_property, *args)
|
80
|
+
actor.save_easing_state
|
81
|
+
actor.easing_mode = mode
|
82
|
+
actor.easing_duration = duration
|
83
|
+
|
84
|
+
actor.set_property(first_property, args.first)
|
85
|
+
end
|
86
|
+
|
87
|
+
def show_controls(app, vis)
|
88
|
+
return if app.control.nil?
|
89
|
+
|
90
|
+
if vis == true && app.controls_showing == true
|
91
|
+
if app.controls_timeout == 0
|
92
|
+
app.controls_timeout = GLib::Timeout.add_seconds(5) do
|
93
|
+
controls_timeout_cb(app)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
return
|
97
|
+
end
|
98
|
+
|
99
|
+
if vis == true && app.controls_showing == false
|
100
|
+
app.controls_showing = true
|
101
|
+
app.stage.show_cursor
|
102
|
+
actor_animate(app.control, :ease_out_quint, 250, "opacity", 224)
|
103
|
+
return
|
104
|
+
end
|
105
|
+
|
106
|
+
if vis == false && app.controls_showing == true
|
107
|
+
app.controls_showing = false
|
108
|
+
if app.mouse_in_window
|
109
|
+
app.stage.hide_cursor
|
110
|
+
end
|
111
|
+
actor_animate(app.control, :ease_out_quint, 250, "opacity", 0)
|
112
|
+
return
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def toggle_pause_state(app)
|
117
|
+
return if app.vtexture.nil?
|
118
|
+
|
119
|
+
if app.paused
|
120
|
+
app.vtexture.playing = true
|
121
|
+
app.paused = false
|
122
|
+
app.control_play.hide
|
123
|
+
app.control_pause.show
|
124
|
+
else
|
125
|
+
app.vtexture.playing = false
|
126
|
+
app.paused = true
|
127
|
+
app.control_pause.hide
|
128
|
+
app.control_play.show
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def position_controls(app, controls)
|
133
|
+
stage_width, stage_height = app.stage.size
|
134
|
+
bg_width, bg_height = app.control.size
|
135
|
+
|
136
|
+
x = ((stage_width - bg_width) / 2).floor
|
137
|
+
y = stage_height - bg_height - 28
|
138
|
+
|
139
|
+
controls.set_position(x, y)
|
140
|
+
end
|
141
|
+
|
142
|
+
def new_rectangle_with_color(color)
|
143
|
+
actor = Clutter::Actor.new
|
144
|
+
actor.background_color = color
|
145
|
+
actor
|
146
|
+
end
|
147
|
+
|
148
|
+
stage_color = Clutter::Color.new(0, 0, 0, 0)
|
149
|
+
control_color1 = Clutter::Color.new(73, 74, 77, 0xee)
|
150
|
+
control_color2 = Clutter::Color.new(0xcc, 0xcc, 0xcc, 0xff)
|
151
|
+
|
152
|
+
if ARGV.length < 1
|
153
|
+
puts "Usage: #{$0} [OPTIONS] <video file> - A simple video player"
|
154
|
+
exit(false)
|
155
|
+
end
|
156
|
+
|
157
|
+
stage = Clutter::Stage.new
|
158
|
+
stage.background_color = Clutter::Color.new(0, 0, 0, 0)
|
159
|
+
stage.set_size(768, 576)
|
160
|
+
stage.set_minimum_size(640, 480)
|
161
|
+
stage.fullscreen = true if opt_fullscreen
|
162
|
+
|
163
|
+
app = VideoApp.new
|
164
|
+
app.stage = stage
|
165
|
+
app.vtexture = ClutterGst::VideoTexture.new
|
166
|
+
|
167
|
+
raise "failed to create vtexture" if app.vtexture.nil?
|
168
|
+
|
169
|
+
# By default ClutterGst seeks to the nearest key frame (faster). However
|
170
|
+
# it has the weird effect that when you click on the progress bar, the fill
|
171
|
+
# goes to the key frame position that can be quite far from where you
|
172
|
+
# clicked. Using the ACCURATE flag tells playbin2 to seek to the actual
|
173
|
+
# frame
|
174
|
+
app.vtexture.seek_flags = :accurate
|
175
|
+
|
176
|
+
app.vtexture.signal_connect("eos") do |media, app|
|
177
|
+
if opt_loop
|
178
|
+
media.progress = 0.0
|
179
|
+
media.playing = true
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
stage.signal_connect("allocation-changed") do |stage, box, flags|
|
184
|
+
position_controls(app, app.control)
|
185
|
+
show_controls(app, true)
|
186
|
+
end
|
187
|
+
|
188
|
+
stage.signal_connect("destroy") do
|
189
|
+
Clutter.main_quit
|
190
|
+
end
|
191
|
+
|
192
|
+
# Handle it ourselves so can scale up for fullscreen better
|
193
|
+
app.vtexture.signal_connect_after("size-change") do |texture, base_width, base_height|
|
194
|
+
stage_width, stage_height = stage.size
|
195
|
+
|
196
|
+
# base_width and base_height are the actual dimensions of the buffers before
|
197
|
+
# taking the pixel aspect ratio into account. We need to get the actual
|
198
|
+
# size of the texture to display
|
199
|
+
frame_width, frame_height = texture.size
|
200
|
+
|
201
|
+
new_height = (frame_height * stage_width) / frame_width
|
202
|
+
if new_height <= stage_height
|
203
|
+
new_width = stage_width
|
204
|
+
new_x = 0
|
205
|
+
new_y = (stage_height - new_height) / 2
|
206
|
+
else
|
207
|
+
new_width = (frame_width * stage_height) / frame_height
|
208
|
+
new_height = stage_height
|
209
|
+
new_x = (stage_width - new_width) / 2
|
210
|
+
new_y = 0
|
211
|
+
end
|
212
|
+
texture.set_position(new_x, new_y)
|
213
|
+
texture.set_size(new_width, new_height)
|
214
|
+
end
|
215
|
+
|
216
|
+
# Load up out video texture
|
217
|
+
app.vtexture.filename = ARGV[0]
|
218
|
+
|
219
|
+
# Set up things so that a visualisation is played if there's no video
|
220
|
+
pipe = app.vtexture.pipeline
|
221
|
+
raise "Unable to get gstreamer pipeline!" unless pipe
|
222
|
+
|
223
|
+
# TODO: want to not require Gst.init
|
224
|
+
# prepare Gst's methods (e.g. iterate_sinks)
|
225
|
+
Gst.init
|
226
|
+
|
227
|
+
iter = pipe.iterate_sinks
|
228
|
+
raise "Unable to iterate over sinks!" unless iter
|
229
|
+
|
230
|
+
playsink = nil
|
231
|
+
while (value = iter.next)[0] == :ok
|
232
|
+
playsink = value[1].value
|
233
|
+
sink_name = playsink.name # unused
|
234
|
+
end
|
235
|
+
|
236
|
+
goomsource = Gst::ElementFactory.make("goom", "source")
|
237
|
+
raise "Unable to create goom visualiser!" unless goomsource
|
238
|
+
|
239
|
+
# TODO: warnings occurred
|
240
|
+
#playsink_flags = playsink.flags.value
|
241
|
+
#playsink_flags |= GST_PLAY_FLAG_VIS
|
242
|
+
playsink.vis_plugin = goomsource
|
243
|
+
#playsink.flags = playsink_flags
|
244
|
+
|
245
|
+
# Create the control UI
|
246
|
+
app.control = Clutter::Actor.new
|
247
|
+
|
248
|
+
app.control_bg = Clutter::Texture.new
|
249
|
+
app.control_bg.from_file = File.expand_path("vid-panel.png", File.dirname(__FILE__))
|
250
|
+
app.control_play = Clutter::Texture.new
|
251
|
+
app.control_play.from_file = File.expand_path("media-actions-start.png", File.dirname(__FILE__))
|
252
|
+
app.control_pause = Clutter::Texture.new
|
253
|
+
app.control_pause.from_file = File.expand_path("media-actions-pause.png", File.dirname(__FILE__))
|
254
|
+
|
255
|
+
app.control_seek1 = new_rectangle_with_color(control_color1)
|
256
|
+
app.control_seek2 = new_rectangle_with_color(control_color2)
|
257
|
+
app.control_seekbar = new_rectangle_with_color(control_color1)
|
258
|
+
app.control_seekbar.opacity = 0x99
|
259
|
+
|
260
|
+
app.control_label = Clutter::Text.new
|
261
|
+
app.control_label.font_name = "Sans Bold 14"
|
262
|
+
# TODO: segfault
|
263
|
+
#app.control_label.text = File.basename(ARGV[0])
|
264
|
+
stage.title = File.basename(ARGV[0]) # substitutes for label text
|
265
|
+
app.control_label.color = control_color1
|
266
|
+
|
267
|
+
app.control_play.hide
|
268
|
+
|
269
|
+
app.control.add_child(app.control_bg)
|
270
|
+
app.control.add_child(app.control_play)
|
271
|
+
app.control.add_child(app.control_pause)
|
272
|
+
app.control.add_child(app.control_seek1)
|
273
|
+
app.control.add_child(app.control_seek2)
|
274
|
+
app.control.add_child(app.control_seekbar)
|
275
|
+
app.control.add_child(app.control_label)
|
276
|
+
|
277
|
+
app.control.opacity = 0xee
|
278
|
+
|
279
|
+
app.control_play.set_position(22, 31)
|
280
|
+
app.control_pause.set_position(18, 31)
|
281
|
+
|
282
|
+
app.control_seek1.set_size(SEEK_W + 4, SEEK_H + 4)
|
283
|
+
app.control_seek1.set_position(80, 57)
|
284
|
+
app.control_seek2.set_size(SEEK_W, SEEK_H)
|
285
|
+
app.control_seek2.set_position(82, 59)
|
286
|
+
app.control_seekbar.set_size(0, SEEK_H)
|
287
|
+
app.control_seekbar.set_position(82, 59)
|
288
|
+
|
289
|
+
app.control_label.set_position(82, 29)
|
290
|
+
|
291
|
+
# Add control UI to stage
|
292
|
+
stage.add_child(app.vtexture)
|
293
|
+
stage.add_child(app.control)
|
294
|
+
|
295
|
+
position_controls(app, app.control)
|
296
|
+
|
297
|
+
stage.hide_cursor
|
298
|
+
actor_animate(app.control, :ease_out_quint, 1000, "opacity", 0)
|
299
|
+
|
300
|
+
# Hook up other events
|
301
|
+
stage.signal_connect("event") do |stage, event|
|
302
|
+
handled = false
|
303
|
+
|
304
|
+
case event.type
|
305
|
+
when Clutter::EventType::MOTION
|
306
|
+
show_controls(app, true)
|
307
|
+
handled = true
|
308
|
+
when Clutter::EventType::BUTTON_PRESS
|
309
|
+
if app.controls_showing
|
310
|
+
actor = stage.get_actor_at_pos(:all, event.x, event.y)
|
311
|
+
if actor == app.control_pause || actor == app.control_play
|
312
|
+
toggle_pause_state(app)
|
313
|
+
elsif actor == app.control_seek1 ||
|
314
|
+
actor == app.control_seek2 ||
|
315
|
+
actor == app.control_seekbar
|
316
|
+
x, y = app.control_seekbar.transformed_position
|
317
|
+
dist = event.x - x
|
318
|
+
def clamp(x, low, high)
|
319
|
+
if x > high
|
320
|
+
high
|
321
|
+
elsif x < low
|
322
|
+
low
|
323
|
+
else
|
324
|
+
x
|
325
|
+
end
|
326
|
+
end
|
327
|
+
dist = clamp(dist, 0, SEEK_W)
|
328
|
+
progress = 1.0 * dist / SEEK_W
|
329
|
+
app.vtexture.progress == progress
|
330
|
+
end
|
331
|
+
end
|
332
|
+
handled = true
|
333
|
+
when Clutter::EventType::KEY_PRESS
|
334
|
+
animation = nil
|
335
|
+
case event.key_symbol
|
336
|
+
when Clutter::Keys::KEY_d
|
337
|
+
if app.vtexture
|
338
|
+
app.stage.remove_child(app.vtexture)
|
339
|
+
app.vtexture = nil
|
340
|
+
end
|
341
|
+
if app.control
|
342
|
+
app.stage.remove_child(app.control)
|
343
|
+
app.control = nil
|
344
|
+
end
|
345
|
+
when Clutter::Keys::KEY_q, Clutter::Keys::KEY_Escape
|
346
|
+
app.stage.destroy
|
347
|
+
when Clutter::Keys::KEY_e
|
348
|
+
if app.vtexture
|
349
|
+
app.vtexture .set_pivot_point(0.5, 0)
|
350
|
+
animation = actor_animate(app.vtexture,
|
351
|
+
:linear, 500,
|
352
|
+
"rotation-angle-y", 360.0)
|
353
|
+
animation.signal_connect_after("transitions-completed") do
|
354
|
+
if app.vtexture
|
355
|
+
app.vtexture.set_rotation_angle(:y_axis, 0.0)
|
356
|
+
end
|
357
|
+
end
|
358
|
+
handled = true
|
359
|
+
end
|
360
|
+
else
|
361
|
+
toggle_pause_state(app)
|
362
|
+
handled = true
|
363
|
+
end
|
364
|
+
when Clutter::EventType::ENTER
|
365
|
+
app.mouse_in_window = true
|
366
|
+
app.stage.cursor_visible = app.controls_showing
|
367
|
+
when Clutter::EventType::LEAVE
|
368
|
+
app.mouse_in_window = false
|
369
|
+
app.stage.show_cursor
|
370
|
+
end
|
371
|
+
handled
|
372
|
+
end
|
373
|
+
|
374
|
+
app.vtexture.signal_connect("notify::progress") do |video_texture, pspec|
|
375
|
+
progress = video_texture.progress
|
376
|
+
app.control_seekbar.set_size(progress * SEEK_W, SEEK_H)
|
377
|
+
end
|
378
|
+
|
379
|
+
app.vtexture.playing = true
|
380
|
+
|
381
|
+
stage.show
|
382
|
+
|
383
|
+
Clutter.main
|
@@ -0,0 +1,99 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This sample code is a port of clutter-gst/examples/video-sink-navigation.c.
|
4
|
+
# It is licensed under the terms of the GNU Lesser General Public
|
5
|
+
# License, version 2.1 or (at your option) later.
|
6
|
+
#
|
7
|
+
# The original header:
|
8
|
+
# video-sink.c - A small example around the videotestsrc ! capsfilter !
|
9
|
+
# navigationtest ! videoconvert ! cluttersink pipeline.
|
10
|
+
#
|
11
|
+
# Copyright (C) 2007,2008 OpenedHand
|
12
|
+
#
|
13
|
+
# Copyright (C) 2013 Ruby-GNOME2 Project Team
|
14
|
+
#
|
15
|
+
# This library is free software; you can redistribute it and/or
|
16
|
+
# modify it under the terms of the GNU Lesser General Public
|
17
|
+
# License as published by the Free Software Foundation; either
|
18
|
+
# version 2.1 of the License, or (at your option) any later version.
|
19
|
+
#
|
20
|
+
# This library is distributed in the hope that it will be useful,
|
21
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
22
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
23
|
+
# Lesser General Public License for more details.
|
24
|
+
#
|
25
|
+
# You should have received a copy of the GNU Lesser General Public
|
26
|
+
# License along with this library; if not, write to the Free Software
|
27
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
28
|
+
|
29
|
+
# NOTE: This sample code is for libclutter-gst (a library by C) 2.0.2.
|
30
|
+
require "clutter-gst"
|
31
|
+
|
32
|
+
stage = Clutter::Stage.new
|
33
|
+
stage.user_resizable = true
|
34
|
+
stage.signal_connect("destroy") do
|
35
|
+
Clutter.main_quit
|
36
|
+
end
|
37
|
+
|
38
|
+
# Make a timeline
|
39
|
+
timeline = Clutter::Timeline.new(1000)
|
40
|
+
timeline.loop = true
|
41
|
+
|
42
|
+
# We need to set certain props on the target texture currently for
|
43
|
+
# efficient/correct playback onto the texture (which sucks a bit)
|
44
|
+
texture = Clutter::Texture.new
|
45
|
+
# NOTE: Because warning is given, I comment out.
|
46
|
+
#texture.set_property("disable-slicing", true)
|
47
|
+
|
48
|
+
texture.signal_connect("size-change") do |texture, width, height|
|
49
|
+
stage = texture.stage
|
50
|
+
next if stage.nil? # go out of the block if stage is nil
|
51
|
+
stage_width, stage_height = stage.size
|
52
|
+
new_height = (height * stage_width) / width
|
53
|
+
if new_height <= stage_height
|
54
|
+
new_width = stage_width
|
55
|
+
new_x = 0
|
56
|
+
new_y = (stage_height - new_height) / 2
|
57
|
+
else
|
58
|
+
new_width = (width * stage_height) / height
|
59
|
+
new_height = stage_height
|
60
|
+
new_x = (stage_width - new_width) / 2
|
61
|
+
new_y = 0
|
62
|
+
end
|
63
|
+
texture.set_position(new_x, new_y)
|
64
|
+
texture.set_size(new_width, new_height)
|
65
|
+
end
|
66
|
+
|
67
|
+
# Set up pipeline
|
68
|
+
pipeline = Gst::Pipeline.new("pipeline")
|
69
|
+
|
70
|
+
src = Gst::ElementFactory.make("videotestsrc")
|
71
|
+
filter = Gst.parse_launch("capsfilter caps=video/x-raw,pixel-aspect-ratio=1/4")
|
72
|
+
|
73
|
+
test = Gst::ElementFactory.make("navigationtest")
|
74
|
+
colorspace = Gst::ElementFactory.make("videoconvert")
|
75
|
+
sink = ClutterGst::VideoSink.new(texture)
|
76
|
+
|
77
|
+
# We can try other patterns
|
78
|
+
# src.pattern = 10
|
79
|
+
|
80
|
+
pipeline << src << filter << test << colorspace << sink
|
81
|
+
src >> filter >> test >> colorspace >> sink
|
82
|
+
pipeline.play
|
83
|
+
|
84
|
+
# Resize with the window
|
85
|
+
constraint = Clutter::BindConstraint.new(stage, :size, 0.0)
|
86
|
+
texture.constraints = constraint
|
87
|
+
|
88
|
+
# Rotate a bit
|
89
|
+
texture.set_pivot_point(0.5, 0.5)
|
90
|
+
texture.set_rotation_angle(:z_axis, 45.0)
|
91
|
+
|
92
|
+
# start the timeline
|
93
|
+
timeline.start
|
94
|
+
|
95
|
+
stage.add_child(texture)
|
96
|
+
# texture.opacity = 0x11
|
97
|
+
stage.show
|
98
|
+
|
99
|
+
Clutter.main
|
@@ -0,0 +1,88 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# This sample code is a port of clutter-gst/examples/video-sink.c.
|
4
|
+
# It is licensed under the terms of the GNU Lesser General Public
|
5
|
+
# License, version 2.1 or (at your option) later.
|
6
|
+
#
|
7
|
+
# The original header:
|
8
|
+
# video-sink.c - A small example around the videotestsrc ! warptv !
|
9
|
+
# videoconvert ! cluttersink pipeline.
|
10
|
+
#
|
11
|
+
# Copyright (C) 2007,2008 OpenedHand
|
12
|
+
#
|
13
|
+
# Copyright (C) 2013 Ruby-GNOME2 Project Team
|
14
|
+
#
|
15
|
+
# This library is free software; you can redistribute it and/or
|
16
|
+
# modify it under the terms of the GNU Lesser General Public
|
17
|
+
# License as published by the Free Software Foundation; either
|
18
|
+
# version 2.1 of the License, or (at your option) any later version.
|
19
|
+
#
|
20
|
+
# This library is distributed in the hope that it will be useful,
|
21
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
22
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
23
|
+
# Lesser General Public License for more details.
|
24
|
+
#
|
25
|
+
# You should have received a copy of the GNU Lesser General Public
|
26
|
+
# License along with this library; if not, write to the Free Software
|
27
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
28
|
+
|
29
|
+
# NOTE: This sample code is for libclutter-gst (a library by C) 2.0.2.
|
30
|
+
require "clutter-gst"
|
31
|
+
|
32
|
+
stage = Clutter::Stage.new
|
33
|
+
stage.signal_connect("destroy") do
|
34
|
+
Clutter.main_quit
|
35
|
+
end
|
36
|
+
|
37
|
+
# Make a timeline
|
38
|
+
timeline = Clutter::Timeline.new(1000)
|
39
|
+
timeline.loop = true
|
40
|
+
|
41
|
+
# We need to set certain props on the target texture currently for
|
42
|
+
# efficient/correct playback onto the texture (which sucks a bit)
|
43
|
+
texture = Clutter::Texture.new
|
44
|
+
# NOTE: Because warning is given, I comment out.
|
45
|
+
#texture.set_property("disable-slicing", true)
|
46
|
+
|
47
|
+
texture.signal_connect("size-change") do |widget, width, height|
|
48
|
+
stage = widget.stage
|
49
|
+
next if stage.nil? # go out of the block if stage is nil
|
50
|
+
stage_width, stage_height = stage.size
|
51
|
+
new_height = (height * stage_width) / width
|
52
|
+
if new_height <= stage_height
|
53
|
+
new_width = stage_width
|
54
|
+
new_x = 0
|
55
|
+
new_y = (stage_height - new_height) / 2
|
56
|
+
else
|
57
|
+
new_width = (width * stage_height) / height
|
58
|
+
new_height = stage_height
|
59
|
+
new_x = (stage_width - new_width) / 2
|
60
|
+
new_y = 0
|
61
|
+
end
|
62
|
+
widget.set_position(new_x, new_y)
|
63
|
+
widget.set_size(new_width, new_height)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Set up pipeline
|
67
|
+
pipeline = Gst::Pipeline.new("pipeline")
|
68
|
+
|
69
|
+
src = Gst::ElementFactory.make("videotestsrc")
|
70
|
+
warp = Gst::ElementFactory.make("warptv")
|
71
|
+
colorspace = Gst::ElementFactory.make("videoconvert")
|
72
|
+
sink = ClutterGst::VideoSink.new(texture)
|
73
|
+
|
74
|
+
# We can try other patterns
|
75
|
+
# src.pattern = 10
|
76
|
+
|
77
|
+
pipeline << src << warp << colorspace << sink
|
78
|
+
src >> warp >> colorspace >> sink
|
79
|
+
pipeline.play
|
80
|
+
|
81
|
+
# start the timeline
|
82
|
+
timeline.start
|
83
|
+
|
84
|
+
stage.add_child(texture)
|
85
|
+
# texture.opacity = 0x11
|
86
|
+
stage.show
|
87
|
+
|
88
|
+
Clutter.main
|
data/test/run-test.rb
CHANGED
@@ -16,22 +16,28 @@
|
|
16
16
|
# License along with this library; if not, write to the Free Software
|
17
17
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
18
18
|
|
19
|
+
have_make = system("which make > /dev/null")
|
20
|
+
|
19
21
|
ruby_gnome2_base = File.join(File.dirname(__FILE__), "..", "..")
|
20
22
|
ruby_gnome2_base = File.expand_path(ruby_gnome2_base)
|
21
23
|
|
22
24
|
glib_base = File.join(ruby_gnome2_base, "glib2")
|
25
|
+
cairo_gobject_base = File.join(ruby_gnome2_base, "cairo-gobject")
|
23
26
|
gobject_introspection_base = File.join(ruby_gnome2_base, "gobject-introspection")
|
24
27
|
clutter_base = File.join(ruby_gnome2_base, "clutter")
|
25
28
|
gstreamer_base = File.join(ruby_gnome2_base, "gstreamer")
|
29
|
+
clutter_gstreamer_base = File.join(ruby_gnome2_base, "clutter-gstreamer")
|
26
30
|
|
27
31
|
modules = [
|
28
32
|
[glib_base, "glib2"],
|
33
|
+
[cairo_gobject_base, "cairo-gobject"],
|
29
34
|
[gobject_introspection_base, "gobject-introspection"],
|
30
35
|
[clutter_base, "clutter"],
|
31
36
|
[gstreamer_base, "gstreamer"],
|
37
|
+
[clutter_gstreamer_base, "clutter-gst"],
|
32
38
|
]
|
33
39
|
modules.each do |target, module_name|
|
34
|
-
if
|
40
|
+
if File.exist?(File.join(target, "Makefile")) and have_make
|
35
41
|
`make -C #{target.dump} > /dev/null` or exit(false)
|
36
42
|
end
|
37
43
|
$LOAD_PATH.unshift(File.join(target, "ext", module_name))
|
@@ -41,12 +47,14 @@ end
|
|
41
47
|
$LOAD_PATH.unshift(File.join(glib_base, "test"))
|
42
48
|
require "glib-test-init"
|
43
49
|
|
50
|
+
$VERBOSE = false # TODO: remove me
|
51
|
+
|
44
52
|
$LOAD_PATH.unshift(File.join(gobject_introspection_base, "test"))
|
45
53
|
require "gobject-introspection-test-utils"
|
46
54
|
|
47
55
|
$LOAD_PATH.unshift(File.join(clutter_base, "test"))
|
48
56
|
require "clutter-test-utils"
|
49
57
|
|
50
|
-
require "clutter-
|
58
|
+
require "clutter-gst"
|
51
59
|
|
52
60
|
exit Test::Unit::AutoRunner.run(true)
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# Copyright (C) 2013 Ruby-GNOME2 Project Team
|
2
|
+
#
|
3
|
+
# This library is free software; you can redistribute it and/or
|
4
|
+
# modify it under the terms of the GNU Lesser General Public
|
5
|
+
# License as published by the Free Software Foundation; either
|
6
|
+
# version 2.1 of the License, or (at your option) any later version.
|
7
|
+
#
|
8
|
+
# This library is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
11
|
+
# Lesser General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU Lesser General Public
|
14
|
+
# License along with this library; if not, write to the Free Software
|
15
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
16
|
+
|
17
|
+
class ClutterGstTest < Test::Unit::TestCase
|
18
|
+
def test_init
|
19
|
+
assert_nothing_raised do
|
20
|
+
ClutterGst.init
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
metadata
CHANGED
@@ -1,62 +1,55 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: clutter-gstreamer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
5
|
-
prerelease:
|
4
|
+
version: 2.0.3
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- The Ruby-GNOME2 Project Team
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2013-
|
11
|
+
date: 2013-12-28 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: clutter
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
17
|
- - '='
|
20
18
|
- !ruby/object:Gem::Version
|
21
|
-
version: 2.0.
|
19
|
+
version: 2.0.3
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
24
|
- - '='
|
28
25
|
- !ruby/object:Gem::Version
|
29
|
-
version: 2.0.
|
26
|
+
version: 2.0.3
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: gstreamer
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
31
|
- - '='
|
36
32
|
- !ruby/object:Gem::Version
|
37
|
-
version: 2.0.
|
33
|
+
version: 2.0.3
|
38
34
|
type: :runtime
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
38
|
- - '='
|
44
39
|
- !ruby/object:Gem::Version
|
45
|
-
version: 2.0.
|
40
|
+
version: 2.0.3
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: test-unit-notify
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
|
-
- -
|
45
|
+
- - '>='
|
52
46
|
- !ruby/object:Gem::Version
|
53
47
|
version: '0'
|
54
48
|
type: :development
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
|
-
- -
|
52
|
+
- - '>='
|
60
53
|
- !ruby/object:Gem::Version
|
61
54
|
version: '0'
|
62
55
|
description: Ruby/ClutterGStreamer is a Ruby binding of Clutter-GStreamer.
|
@@ -67,30 +60,36 @@ extra_rdoc_files: []
|
|
67
60
|
files:
|
68
61
|
- Rakefile
|
69
62
|
- lib/clutter-gst.rb
|
63
|
+
- sample/media-actions-pause.png
|
64
|
+
- sample/media-actions-start.png
|
65
|
+
- sample/vid-panel.png
|
66
|
+
- sample/video-player.rb
|
67
|
+
- sample/video-sink-navigation.rb
|
68
|
+
- sample/video-sink.rb
|
70
69
|
- test/clutter-gstreamer-test-utils.rb
|
71
70
|
- test/run-test.rb
|
71
|
+
- test/test-clutter-gst.rb
|
72
72
|
homepage: http://ruby-gnome2.sourceforge.jp/
|
73
73
|
licenses: []
|
74
|
+
metadata: {}
|
74
75
|
post_install_message:
|
75
76
|
rdoc_options: []
|
76
77
|
require_paths:
|
77
78
|
- lib
|
78
79
|
required_ruby_version: !ruby/object:Gem::Requirement
|
79
|
-
none: false
|
80
80
|
requirements:
|
81
|
-
- -
|
81
|
+
- - '>='
|
82
82
|
- !ruby/object:Gem::Version
|
83
|
-
version: 1.
|
83
|
+
version: 1.9.3
|
84
84
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
85
|
-
none: false
|
86
85
|
requirements:
|
87
|
-
- -
|
86
|
+
- - '>='
|
88
87
|
- !ruby/object:Gem::Version
|
89
88
|
version: '0'
|
90
89
|
requirements: []
|
91
90
|
rubyforge_project:
|
92
|
-
rubygems_version:
|
91
|
+
rubygems_version: 2.0.14
|
93
92
|
signing_key:
|
94
|
-
specification_version:
|
93
|
+
specification_version: 4
|
95
94
|
summary: Ruby/ClutterGStreamer is a Ruby binding of Clutter-GStreamer.
|
96
95
|
test_files: []
|