dclext-anim 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +4 -0
- data/LICENSE.txt +34 -0
- data/README.rdoc +56 -0
- data/Rakefile +1 -0
- data/dclext-anim.gemspec +28 -0
- data/lib/numru/dclext/anim.rb +8 -0
- data/lib/numru/dclext/anim/anim.rb +13 -0
- data/lib/numru/dclext/anim/anim_dcl.rb +70 -0
- data/lib/numru/dclext/anim/source.rb +39 -0
- data/lib/numru/dclext/anim/stream.rb +131 -0
- data/lib/numru/dclext/anim/version.rb +7 -0
- data/sample/sample1.rb +19 -0
- metadata +106 -0
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
RubyDCLExt-Anim is copyrighted free software by Seiya Nishizawa and GFD
|
2
|
+
Dennou Club (http://www.gfd-dennou.org/).
|
3
|
+
|
4
|
+
Copyright 2001 (C) Seiya Nishizawa and GFD Dennou Club
|
5
|
+
(http://www.gfd-dennou.org/) All rights reserved.
|
6
|
+
|
7
|
+
Redistribution and use in source and binary forms, with or without
|
8
|
+
modification, are permitted provided that the following conditions are
|
9
|
+
met:
|
10
|
+
|
11
|
+
1. Redistributions of source code must retain the above copyright
|
12
|
+
notice, this list of conditions and the following disclaimer.
|
13
|
+
|
14
|
+
2. Redistributions in binary form must reproduce the above copyright
|
15
|
+
notice, this list of conditions and the following disclaimer in
|
16
|
+
the documentation and/or other materials provided with the
|
17
|
+
distribution.
|
18
|
+
|
19
|
+
THIS SOFTWARE IS PROVIDED BY GFD DENNOU CLUB AND CONTRIBUTORS ``AS IS''
|
20
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
21
|
+
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
22
|
+
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GFD DENNOU CLUB OR
|
23
|
+
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
24
|
+
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
25
|
+
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
26
|
+
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
27
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
28
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
29
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
30
|
+
|
31
|
+
The views and conclusions contained in the software and documentation
|
32
|
+
are those of the authors and should not be interpreted as representing
|
33
|
+
official policies, either expressed or implied, of Seiya Nishizawa
|
34
|
+
and GFD Dennou Club.
|
data/README.rdoc
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
= What's RubyDCLExt-Anim
|
2
|
+
|
3
|
+
RubyDCLExt-Anim is an extension for RubyDCL
|
4
|
+
to output animation (movie) file.
|
5
|
+
Currently, output file is MP4 file formated and h264 encoded .
|
6
|
+
|
7
|
+
|
8
|
+
= RubyDCLExt-Anim home-page
|
9
|
+
|
10
|
+
The URL of the RubyDCLExt-Anim home-page is:
|
11
|
+
http://ruby.gfd-dennou.org/products/ruby-dclext-anim/
|
12
|
+
|
13
|
+
|
14
|
+
= Requires
|
15
|
+
|
16
|
+
* Ruby (http://www.ruby-lang.org/)
|
17
|
+
* RubyDCL (http://ruby.gfd-dennou.org/products/ruby-dcl/)
|
18
|
+
* Ruby-Gtk2 and Ruby-GStreamer (http://ruby-gnome2.sourceforge.jp/)
|
19
|
+
* gst-plugins-ugly (http://gstreamer.freedesktop.org/modules/gst-plugins-ugly.html)
|
20
|
+
* use x264enc element.
|
21
|
+
|
22
|
+
|
23
|
+
= Install
|
24
|
+
|
25
|
+
# gem install dclext-anim
|
26
|
+
|
27
|
+
|
28
|
+
= Copying
|
29
|
+
|
30
|
+
See the file LICENSE.txt.
|
31
|
+
|
32
|
+
|
33
|
+
= Usage
|
34
|
+
|
35
|
+
To output animation file, require "numru/dclext/anim"
|
36
|
+
% ruby -r numru/dclext/anim your_dcl_script.rb
|
37
|
+
|
38
|
+
== Options
|
39
|
+
|
40
|
+
You can change some parameters with environmental variable or runtime option.
|
41
|
+
|
42
|
+
* framerate: frame rate for the output movie (frame/sec)
|
43
|
+
* environmental variable: DCLEXT_ANIM_FRAMERATE=(int)
|
44
|
+
* runtime option: --dclext-anim-framerate=(int)
|
45
|
+
|
46
|
+
* filename: name of the output file
|
47
|
+
* environmental variable: DCLEXT_ANIM_FILENAME=(string)
|
48
|
+
* runtime option: --dclext-anim-filename=(string)
|
49
|
+
|
50
|
+
|
51
|
+
= The Author
|
52
|
+
|
53
|
+
Feel free to send comments and bug reports to the author.
|
54
|
+
The author's e-mail addess is
|
55
|
+
|
56
|
+
seiya@gfd-dennou.org
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/dclext-anim.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.unshift File.expand_path("../lib", __FILE__)
|
3
|
+
require "numru/dclext/anim/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "dclext-anim"
|
7
|
+
s.version = NumRu::DCLExt::Anim::VERSION
|
8
|
+
s.authors = ["Seiya Nishizawa"]
|
9
|
+
s.email = ["seiya@gfd-dennou.org"]
|
10
|
+
s.homepage = "http://ruby.gfd-dennou.org/products/ruby-dclext-anim/"
|
11
|
+
s.summary = %q{Anim extension for RubyDCL}
|
12
|
+
s.description = %q{RubyDCLExt-Anim is an extension for RubyDCL to output animation (movie) file.
|
13
|
+
Currently, output file is MP4 file formated and h264 encoded .}
|
14
|
+
|
15
|
+
s.rubyforge_project = "dclext-anim"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
#s.extensions << "ext/extconf.rb"
|
22
|
+
|
23
|
+
# specify any dependencies here; for example:
|
24
|
+
#s.add_development_dependency "rspec"
|
25
|
+
#s.add_runtime_dependency "numru/dcl"
|
26
|
+
s.add_runtime_dependency "gtk2"
|
27
|
+
s.add_runtime_dependency "gst"
|
28
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module NumRu
|
2
|
+
module DCLExt
|
3
|
+
module Anim
|
4
|
+
PADDING = 4
|
5
|
+
|
6
|
+
module_function
|
7
|
+
def width; @width ||= NumRu::DCL.swiget("iwidth") - PADDING; end
|
8
|
+
def height; @height ||= NumRu::DCL.swiget("iheight") - PADDING; end
|
9
|
+
|
10
|
+
end # module Anim
|
11
|
+
end # module DCLExt
|
12
|
+
|
13
|
+
end # module NumRu
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require "numru/dcl"
|
2
|
+
|
3
|
+
|
4
|
+
module NumRu
|
5
|
+
module DCL
|
6
|
+
|
7
|
+
alias :__gropn :gropn
|
8
|
+
def gropn(wsn)
|
9
|
+
|
10
|
+
pr, pw = IO.pipe
|
11
|
+
|
12
|
+
width = NumRu::DCLExt::Anim.width
|
13
|
+
height = NumRu::DCLExt::Anim.height
|
14
|
+
|
15
|
+
fork do
|
16
|
+
|
17
|
+
require "numru/dclext/anim/stream"
|
18
|
+
|
19
|
+
pw.close
|
20
|
+
|
21
|
+
stream = NumRu::DCLExt::Anim::Stream.new(pr)
|
22
|
+
stream.start
|
23
|
+
|
24
|
+
end # fork
|
25
|
+
|
26
|
+
require "gtk2"
|
27
|
+
require "numru/dclext/gtk"
|
28
|
+
require "numru/dclext/anim/source"
|
29
|
+
|
30
|
+
pr.close
|
31
|
+
|
32
|
+
Gtk.init
|
33
|
+
|
34
|
+
drw = Gtk::DrawingArea.new
|
35
|
+
drw.set_width_request NumRu::DCLExt::Anim.width
|
36
|
+
drw.set_height_request NumRu::DCLExt::Anim.height
|
37
|
+
drw.show
|
38
|
+
|
39
|
+
wnd = Gtk::Window.new
|
40
|
+
wnd.add drw
|
41
|
+
drw.realize
|
42
|
+
|
43
|
+
pixmap = Gdk::Pixmap.new(drw.window, width, height, -1)
|
44
|
+
|
45
|
+
NumRu::DCLExt.zgsdrw(drw)
|
46
|
+
NumRu::DCLExt.zgspmp(pixmap)
|
47
|
+
|
48
|
+
@source = NumRu::DCLExt::Anim::Source.new(pixmap, pw)
|
49
|
+
|
50
|
+
__gropn(4)
|
51
|
+
end # gropn
|
52
|
+
module_function :__gropn, :gropn
|
53
|
+
|
54
|
+
alias :__grfrm :grfrm
|
55
|
+
def grfrm
|
56
|
+
@source.new_frame
|
57
|
+
__grfrm
|
58
|
+
end
|
59
|
+
module_function :__grfrm, :grfrm
|
60
|
+
|
61
|
+
alias :__grcls :grcls
|
62
|
+
def grcls
|
63
|
+
@source.close
|
64
|
+
__grcls
|
65
|
+
end
|
66
|
+
module_function :__grcls, :grcls
|
67
|
+
|
68
|
+
end # module DCL
|
69
|
+
|
70
|
+
end # module NumRu
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module NumRu
|
2
|
+
module DCLExt
|
3
|
+
module Anim
|
4
|
+
|
5
|
+
class Source
|
6
|
+
|
7
|
+
include Anim
|
8
|
+
|
9
|
+
def initialize(pixmap, pipe)
|
10
|
+
@pixmap = pixmap
|
11
|
+
@pipe = pipe
|
12
|
+
@first_frame = true
|
13
|
+
end
|
14
|
+
|
15
|
+
def new_frame
|
16
|
+
if @first_frame
|
17
|
+
@first_frame = false
|
18
|
+
else
|
19
|
+
put_data
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def close
|
24
|
+
put_data unless @first_frame
|
25
|
+
@pipe.close
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
private
|
30
|
+
def put_data
|
31
|
+
pixbuf = Gdk::Pixbuf.from_drawable(nil, @pixmap, 0, 0, width, height)
|
32
|
+
@pipe.write pixbuf.pixels
|
33
|
+
end
|
34
|
+
|
35
|
+
end # class DCL
|
36
|
+
|
37
|
+
end # module Anim
|
38
|
+
end # module DCLExt
|
39
|
+
end # module NumRu
|
@@ -0,0 +1,131 @@
|
|
1
|
+
module NumRu
|
2
|
+
module DCLExt
|
3
|
+
module Anim
|
4
|
+
|
5
|
+
class Stream
|
6
|
+
|
7
|
+
include Anim
|
8
|
+
|
9
|
+
DEPTH = 24
|
10
|
+
BPP = 24
|
11
|
+
|
12
|
+
DEFAULT_FRAMERATE = 4
|
13
|
+
DEFAULT_FILENAME = "dcl.mp4"
|
14
|
+
|
15
|
+
|
16
|
+
|
17
|
+
attr_accessor :filename, :framerate
|
18
|
+
attr_reader :pipe
|
19
|
+
attr_reader :buffersize
|
20
|
+
|
21
|
+
def initialize(pipe)
|
22
|
+
@pipe = pipe
|
23
|
+
@buffersize = width * height * DEPTH
|
24
|
+
@num_frames = 0
|
25
|
+
@source_id = nil
|
26
|
+
ARGV.each do |arg|
|
27
|
+
case arg
|
28
|
+
when /\A--dclext-anim-framerate=/
|
29
|
+
@framerate = $'.to_i
|
30
|
+
when /\A--dclext-anim-filename=/
|
31
|
+
@filename = $'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
@framerate ||= ((c=ENV["DCLEXT_ANIM_FRAMERATE"]) && c.to_i) || DEFAULT_FRAMERATE
|
35
|
+
@filename ||= ENV["DCLEXT_ANIM_FILENAME"] || DEFAULT_FILENAME
|
36
|
+
end
|
37
|
+
|
38
|
+
def start
|
39
|
+
require "gst"
|
40
|
+
|
41
|
+
Gst.init
|
42
|
+
|
43
|
+
loop = GLib::MainLoop.new(nil, false)
|
44
|
+
|
45
|
+
x264opts = "path=qual quantizer=18 qp-min=10 qp-max=25 me=umh subme=6 ref=3 threads=0 cabac=true dct8x8=false"
|
46
|
+
# x264opts = "bitrate=10000"
|
47
|
+
cmd = "appsrc min-latency=100000000 block=true name=dclsource caps=\"#{caps_str}\" ! queue ! ffmpegcolorspace ! video/x-raw-yuv,format=(fourcc)I420,width=#{width},height=#{height} ! videorate ! video/x-raw-yuv,framerate=#{@framerate}/1 ! queue ! x264enc #{x264opts} ! queue ! mp4mux ! filesink location=#{@filename}"
|
48
|
+
|
49
|
+
bin = Gst::Parse.launch(cmd)
|
50
|
+
|
51
|
+
appsrc = bin.get_child("dclsource")
|
52
|
+
appsrc.format = Gst::Format::TIME
|
53
|
+
appsrc.max_bytes = height*width*DEPTH*5
|
54
|
+
|
55
|
+
bus = bin.bus
|
56
|
+
bus.add_watch do |bus, message|
|
57
|
+
case message.type
|
58
|
+
when Gst::Message::EOS
|
59
|
+
loop.quit
|
60
|
+
when Gst::Message::ERROR
|
61
|
+
p message.parse
|
62
|
+
loop.quit
|
63
|
+
end
|
64
|
+
true
|
65
|
+
end
|
66
|
+
|
67
|
+
appsrc.signal_connect('need-data') do |elm, length|
|
68
|
+
start_feed(elm)
|
69
|
+
end
|
70
|
+
appsrc.signal_connect('enough-data') do |elm|
|
71
|
+
stop_feed
|
72
|
+
end
|
73
|
+
|
74
|
+
bin.play
|
75
|
+
begin
|
76
|
+
loop.run
|
77
|
+
rescue Interrupt
|
78
|
+
ensure
|
79
|
+
@pipe.close
|
80
|
+
bin.stop
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def caps_str
|
85
|
+
"video/x-raw-rgb,width=(int)#{width},height=(int)#{height},depth=(int)#{DEPTH},bpp=(int)#{BPP},framerate=#{@framerate}/1,endianness=4321,red_mask=16711680,green_mask=65280,blue_mask=255"
|
86
|
+
end
|
87
|
+
|
88
|
+
def get_data
|
89
|
+
sleep(0.1)
|
90
|
+
@pipe.read(@buffersize/8)
|
91
|
+
end
|
92
|
+
|
93
|
+
def start_feed(appsrc)
|
94
|
+
unless @source_id
|
95
|
+
@source_id = GLib::Idle.add do
|
96
|
+
if data = get_data
|
97
|
+
buffer = Gst::Buffer.new(data.size*8)
|
98
|
+
buffer.caps = Gst::Caps.parse(caps_str)
|
99
|
+
buffer.duration = 10**9/@framerate
|
100
|
+
buffer.timestamp = buffer.duration * @num_frames
|
101
|
+
buffer.set_data(data)
|
102
|
+
# ret = appsrc.signal_emit("push-buffer", buffer)
|
103
|
+
ret = appsrc.push_buffer(buffer)
|
104
|
+
if ret.name == "GST_FLOW_OK"
|
105
|
+
@num_frames += 1
|
106
|
+
true
|
107
|
+
else
|
108
|
+
p ret.name
|
109
|
+
appsrc.end_of_stream
|
110
|
+
false
|
111
|
+
end
|
112
|
+
else
|
113
|
+
appsrc.end_of_stream
|
114
|
+
false
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
def stop_feed
|
120
|
+
if @source_id
|
121
|
+
GLib::Source.remove(@source_id)
|
122
|
+
@source_id = nil
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
end # class Stream
|
127
|
+
|
128
|
+
end # module Anim
|
129
|
+
end # module DCLExt
|
130
|
+
|
131
|
+
end # module NumRu
|
data/sample/sample1.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require "numru/dclext/anim"
|
3
|
+
include NumRu
|
4
|
+
|
5
|
+
N = 100
|
6
|
+
x = NArray.sfloat(N).indgen*Math::PI*2/N
|
7
|
+
|
8
|
+
width = 724
|
9
|
+
height = 484
|
10
|
+
|
11
|
+
DCL.gropn(4)
|
12
|
+
|
13
|
+
100.times do |i|
|
14
|
+
DCL.grfrm
|
15
|
+
DCL.usgrph(x, NMath.sin(x + i*Math::PI/10))
|
16
|
+
DCL.uxsttl("t", "t=#{i}", 0)
|
17
|
+
end
|
18
|
+
|
19
|
+
DCL.grcls
|
metadata
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dclext-anim
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 23
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 2
|
9
|
+
- 0
|
10
|
+
version: 0.2.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Seiya Nishizawa
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2012-02-17 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: gtk2
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 3
|
29
|
+
segments:
|
30
|
+
- 0
|
31
|
+
version: "0"
|
32
|
+
type: :runtime
|
33
|
+
version_requirements: *id001
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: gst
|
36
|
+
prerelease: false
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
+
none: false
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
hash: 3
|
43
|
+
segments:
|
44
|
+
- 0
|
45
|
+
version: "0"
|
46
|
+
type: :runtime
|
47
|
+
version_requirements: *id002
|
48
|
+
description: |-
|
49
|
+
RubyDCLExt-Anim is an extension for RubyDCL to output animation (movie) file.
|
50
|
+
Currently, output file is MP4 file formated and h264 encoded .
|
51
|
+
email:
|
52
|
+
- seiya@gfd-dennou.org
|
53
|
+
executables: []
|
54
|
+
|
55
|
+
extensions: []
|
56
|
+
|
57
|
+
extra_rdoc_files: []
|
58
|
+
|
59
|
+
files:
|
60
|
+
- Gemfile
|
61
|
+
- LICENSE.txt
|
62
|
+
- README.rdoc
|
63
|
+
- Rakefile
|
64
|
+
- dclext-anim.gemspec
|
65
|
+
- lib/numru/dclext/anim.rb
|
66
|
+
- lib/numru/dclext/anim/anim.rb
|
67
|
+
- lib/numru/dclext/anim/anim_dcl.rb
|
68
|
+
- lib/numru/dclext/anim/source.rb
|
69
|
+
- lib/numru/dclext/anim/stream.rb
|
70
|
+
- lib/numru/dclext/anim/version.rb
|
71
|
+
- sample/sample1.rb
|
72
|
+
homepage: http://ruby.gfd-dennou.org/products/ruby-dclext-anim/
|
73
|
+
licenses: []
|
74
|
+
|
75
|
+
post_install_message:
|
76
|
+
rdoc_options: []
|
77
|
+
|
78
|
+
require_paths:
|
79
|
+
- lib
|
80
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
hash: 3
|
86
|
+
segments:
|
87
|
+
- 0
|
88
|
+
version: "0"
|
89
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
90
|
+
none: false
|
91
|
+
requirements:
|
92
|
+
- - ">="
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
hash: 3
|
95
|
+
segments:
|
96
|
+
- 0
|
97
|
+
version: "0"
|
98
|
+
requirements: []
|
99
|
+
|
100
|
+
rubyforge_project: dclext-anim
|
101
|
+
rubygems_version: 1.8.11
|
102
|
+
signing_key:
|
103
|
+
specification_version: 3
|
104
|
+
summary: Anim extension for RubyDCL
|
105
|
+
test_files: []
|
106
|
+
|