rays-video 0.1.2
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 +7 -0
- data/.doc/ext/rays-video/native.cpp +17 -0
- data/.doc/ext/rays-video/video.cpp +257 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +12 -0
- data/.github/workflows/release-gem.yml +51 -0
- data/.github/workflows/tag.yml +35 -0
- data/.github/workflows/test.yml +37 -0
- data/.github/workflows/utils.rb +127 -0
- data/CONTRIBUTING.md +7 -0
- data/ChangeLog.md +19 -0
- data/Gemfile +5 -0
- data/LICENSE +21 -0
- data/README.md +147 -0
- data/Rakefile +25 -0
- data/VERSION +1 -0
- data/ext/rays-video/defs.h +17 -0
- data/ext/rays-video/extconf.rb +23 -0
- data/ext/rays-video/native.cpp +17 -0
- data/ext/rays-video/video.cpp +282 -0
- data/include/rays/video.h +102 -0
- data/include/rays-video/ruby/video.h +47 -0
- data/include/rays-video/ruby.h +10 -0
- data/include/rays-video.h +10 -0
- data/lib/rays/video.rb +45 -0
- data/lib/rays-video/ext.rb +1 -0
- data/lib/rays-video/extension.rb +41 -0
- data/lib/rays-video.rb +3 -0
- data/rays-video.gemspec +39 -0
- data/src/ios/video.mm +633 -0
- data/src/ios/video_audio_in.h +22 -0
- data/src/ios/video_audio_in.mm +252 -0
- data/src/osx/video.mm +633 -0
- data/src/osx/video_audio_in.h +22 -0
- data/src/osx/video_audio_in.mm +252 -0
- data/src/sdl/video.cpp +86 -0
- data/src/sdl/video_audio_in.cpp +63 -0
- data/src/video.cpp +278 -0
- data/src/video.h +50 -0
- data/src/video_audio_in.h +57 -0
- data/src/win32/video.cpp +86 -0
- data/src/win32/video_audio_in.cpp +63 -0
- data/test/helper.rb +15 -0
- data/test/test_video.rb +165 -0
- metadata +145 -0
data/README.md
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# Rays Video - Video support for Rays
|
|
2
|
+
|
|
3
|
+
[](https://deepwiki.com/xord/rays-video)
|
|
4
|
+

|
|
5
|
+

|
|
6
|
+

|
|
7
|
+
|
|
8
|
+
## ⚠️ Notice
|
|
9
|
+
|
|
10
|
+
This repository is a read-only mirror of our monorepo.
|
|
11
|
+
We do not accept pull requests or direct contributions here.
|
|
12
|
+
|
|
13
|
+
### 🔄 Where to Contribute?
|
|
14
|
+
|
|
15
|
+
All development happens in our [xord/all](https://github.com/xord/all) monorepo, which contains all our main libraries.
|
|
16
|
+
If you'd like to contribute, please submit your changes there.
|
|
17
|
+
|
|
18
|
+
For more details, check out our [Contribution Guidelines](./CONTRIBUTING.md).
|
|
19
|
+
|
|
20
|
+
Thanks for your support! 🙌
|
|
21
|
+
|
|
22
|
+
## 🚀 About
|
|
23
|
+
|
|
24
|
+
**Rays Video** is a small extension to [Rays](https://github.com/xord/rays) that adds video reading, writing, and frame-level manipulation. A `Rays::Video` is, conceptually, an ordered list of `Rays::Image` frames with a frame rate and a pixel density — you can build one from scratch, append / insert / remove frames, scrub a playback position, load a video from disk, save it back out, or grab any frame as a regular `Rays::Image` to draw with.
|
|
25
|
+
|
|
26
|
+
Audio support is built on [Beeps](https://github.com/xord/beeps) — video files keep their audio track and it can be fed into a Beeps processor chain.
|
|
27
|
+
|
|
28
|
+
Like the rest of the `xord/*` family, this gem is primarily developed for our own use, but it works as a standalone video gem.
|
|
29
|
+
|
|
30
|
+
> **Platform status:** macOS / iOS only at the moment. Windows and Linux backends are not yet implemented.
|
|
31
|
+
|
|
32
|
+
## 📋 Requirements
|
|
33
|
+
|
|
34
|
+
- Ruby **3.0.0** or later
|
|
35
|
+
- A C++ compiler with C++20 support
|
|
36
|
+
- [Xot](https://rubygems.org/gems/xot), [Rucy](https://rubygems.org/gems/rucy), [Beeps](https://rubygems.org/gems/beeps), and [Rays](https://rubygems.org/gems/rays) (declared as runtime dependencies)
|
|
37
|
+
- **macOS / iOS** — AVFoundation (bundled with the OS)
|
|
38
|
+
|
|
39
|
+
## 📦 Installation
|
|
40
|
+
|
|
41
|
+
Add this line to your Gemfile:
|
|
42
|
+
```ruby
|
|
43
|
+
gem 'rays-video'
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Then install:
|
|
47
|
+
```bash
|
|
48
|
+
$ bundle install
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Or install it directly:
|
|
52
|
+
```bash
|
|
53
|
+
$ gem install rays-video
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## 📚 What's Provided
|
|
57
|
+
|
|
58
|
+
### `Rays::Video`
|
|
59
|
+
|
|
60
|
+
A finite sequence of `Rays::Image` frames with a fixed `width`, `height`, `fps`, and `pixel_density`.
|
|
61
|
+
|
|
62
|
+
| Method | Purpose |
|
|
63
|
+
| ------------------------------------------ | ------------------------------------------------------------------ |
|
|
64
|
+
| `Video.new(width, height, fps:, pixel_density:)` | Create an empty video (`fps` defaults to 30) |
|
|
65
|
+
| `Video.load(path)` | Load a video file from disk |
|
|
66
|
+
| `Video.exts` | Supported video file extensions on the current platform |
|
|
67
|
+
| `video.append(*images)` | Append one or more frames |
|
|
68
|
+
| `video.insert(index, *images)` | Insert frames at the given index |
|
|
69
|
+
| `video.remove(index)` | Remove the frame at the given index |
|
|
70
|
+
| `video.each { \|image\| ... }` | Iterate frames (also includes `Enumerable`) |
|
|
71
|
+
| `video[i]` | Get the frame at index *i* as a `Rays::Image` |
|
|
72
|
+
| `video.pos` / `video.pos =` | Current playback position (index) |
|
|
73
|
+
| `video.play` / `video.pause` / `video.stop`| Playback controls |
|
|
74
|
+
| `video.time_scale` / `video.time_scale =` | Speed multiplier for playback |
|
|
75
|
+
| `video.size`, `video.empty?` | Frame count / emptiness |
|
|
76
|
+
| `video.width`, `video.height`, `video.fps`, `video.pixel_density` | Read-only metadata |
|
|
77
|
+
| `video.dup` | Deep-ish copy (shares image references) |
|
|
78
|
+
| `video.save(path)` | Encode the video to a file |
|
|
79
|
+
| `video.to_image` (`Image()` cast) | Get the frame at the current `pos` as a `Rays::Image` |
|
|
80
|
+
|
|
81
|
+
## 💡 Usage
|
|
82
|
+
|
|
83
|
+
### Build a video from frames and save it
|
|
84
|
+
|
|
85
|
+
```ruby
|
|
86
|
+
require 'rays'
|
|
87
|
+
require 'rays/video'
|
|
88
|
+
|
|
89
|
+
video = Rays::Video.new(320, 240, fps: 30)
|
|
90
|
+
|
|
91
|
+
60.times do |n|
|
|
92
|
+
frame = Rays::Image.new(320, 240)
|
|
93
|
+
frame.paint do |p|
|
|
94
|
+
p.background 0
|
|
95
|
+
p.fill 1, 0.5, 0.1
|
|
96
|
+
p.ellipse n * 5, 120, 60, 60
|
|
97
|
+
end
|
|
98
|
+
video.append frame
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
video.save 'out.mp4'
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Load a video and draw a frame
|
|
105
|
+
|
|
106
|
+
```ruby
|
|
107
|
+
require 'rays'
|
|
108
|
+
require 'rays/video'
|
|
109
|
+
|
|
110
|
+
video = Rays::Video.load 'clip.mp4'
|
|
111
|
+
puts "#{video.width}×#{video.height} @ #{video.fps}fps, #{video.size} frames"
|
|
112
|
+
|
|
113
|
+
# get the 30th frame as an Image and save it
|
|
114
|
+
video[30].save 'frame30.png'
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Scrub through a video
|
|
118
|
+
|
|
119
|
+
```ruby
|
|
120
|
+
video = Rays::Video.load 'clip.mp4'
|
|
121
|
+
|
|
122
|
+
video.pos = 0
|
|
123
|
+
target = Rays::Image.new video.width, video.height
|
|
124
|
+
target.paint do |p|
|
|
125
|
+
p.image video.to_image
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
video.pos = video.size / 2 # mid-point
|
|
129
|
+
mid = video.to_image
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## 🛠️ Development
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
$ rake lib # build the native C++ library (librays-video)
|
|
136
|
+
$ rake ext # build the Ruby C extension
|
|
137
|
+
$ rake test # run the test suite (macOS / iOS only)
|
|
138
|
+
$ rake doc # generate RDoc from C++ sources
|
|
139
|
+
$ rake # default: builds the extension
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
In the [`xord/all`](https://github.com/xord/all) monorepo you can scope by module, e.g. `rake rays-video test`.
|
|
143
|
+
|
|
144
|
+
## 📜 License
|
|
145
|
+
|
|
146
|
+
**Rays Video** is licensed under the MIT License.
|
|
147
|
+
See the [LICENSE](./LICENSE) file for details.
|
data/Rakefile
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# -*- mode: ruby -*-
|
|
2
|
+
|
|
3
|
+
%w[../xot ../rucy ../beeps ../rays .]
|
|
4
|
+
.map {|s| File.expand_path "#{s}/lib", __dir__}
|
|
5
|
+
.each {|s| $:.unshift s if !$:.include?(s) && File.directory?(s)}
|
|
6
|
+
|
|
7
|
+
require 'rucy/rake'
|
|
8
|
+
|
|
9
|
+
require 'xot/extension'
|
|
10
|
+
require 'rucy/extension'
|
|
11
|
+
require 'beeps/extension'
|
|
12
|
+
require 'rays/extension'
|
|
13
|
+
require 'rays-video/extension'
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
EXTENSIONS = [Xot, Rucy, Beeps, Rays, RaysVideo]
|
|
17
|
+
TESTS_ALONE = []
|
|
18
|
+
|
|
19
|
+
default_tasks :ext
|
|
20
|
+
use_bundler
|
|
21
|
+
build_native_library
|
|
22
|
+
build_ruby_extension
|
|
23
|
+
test_ruby_extension unless github_actions? && win32?
|
|
24
|
+
generate_documents
|
|
25
|
+
build_ruby_gem
|
data/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.1.2
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// -*- c++ -*-
|
|
2
|
+
#pragma once
|
|
3
|
+
#ifndef __RAYS_VIDEO_EXT_DEFS_H__
|
|
4
|
+
#define __RAYS_VIDEO_EXT_DEFS_H__
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
#include <rucy.h>
|
|
8
|
+
#include "rays/defs.h"
|
|
9
|
+
#include "rays/ruby/defs.h"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
using namespace Rucy;
|
|
13
|
+
|
|
14
|
+
using Rays::coord;
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
#endif//EOH
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
%w[../xot ../rucy ../beeps ../rays .]
|
|
2
|
+
.map {|s| File.expand_path "../../#{s}/lib", __dir__}
|
|
3
|
+
.each {|s| $:.unshift s if !$:.include?(s) && File.directory?(s)}
|
|
4
|
+
|
|
5
|
+
require 'mkmf'
|
|
6
|
+
require 'xot/extconf'
|
|
7
|
+
require 'xot/extension'
|
|
8
|
+
require 'rucy/extension'
|
|
9
|
+
require 'beeps/extension'
|
|
10
|
+
require 'rays/extension'
|
|
11
|
+
require 'rays-video/extension'
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
Xot::ExtConf.new Xot, Rucy, Beeps, Rays, RaysVideo do
|
|
15
|
+
setup do
|
|
16
|
+
headers << 'ruby.h'
|
|
17
|
+
libs.unshift 'gdi32', 'opengl32', 'glew32' if win32?
|
|
18
|
+
frameworks << 'AppKit' << 'AVFoundation' if osx?
|
|
19
|
+
$LDFLAGS << ' -Wl,--out-implib=librays-video.dll.a' if mingw? || cygwin?
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
create_makefile 'rays_video_ext'
|
|
23
|
+
end
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
#include "rays-video/ruby/video.h"
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
#include "rays/ruby/image.h"
|
|
5
|
+
#include "defs.h"
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
RUCY_DEFINE_VALUE_FROM_TO(RAYS_VIDEO_EXPORT, Rays::Video)
|
|
9
|
+
|
|
10
|
+
#define THIS to<Rays::Video*>(self)
|
|
11
|
+
|
|
12
|
+
#define CHECK RUCY_CHECK_OBJECT(Rays::Video, self)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
static
|
|
16
|
+
RUCY_DEF_ALLOC(alloc, klass)
|
|
17
|
+
{
|
|
18
|
+
return new_type<Rays::Video>(klass);
|
|
19
|
+
}
|
|
20
|
+
RUCY_END
|
|
21
|
+
|
|
22
|
+
static
|
|
23
|
+
RUCY_DEF4(initialize, width, height, fps, pixel_density)
|
|
24
|
+
{
|
|
25
|
+
RUCY_CHECK_OBJ(Rays::Video, self);
|
|
26
|
+
|
|
27
|
+
float fps_ = to<float>(fps);
|
|
28
|
+
*THIS = Rays::Video(
|
|
29
|
+
to<int>(width),
|
|
30
|
+
to<int>(height),
|
|
31
|
+
fps_ > 0 ? fps_ : (float) Rays::Video::DEFAULT_FPS,
|
|
32
|
+
to<float>(pixel_density));
|
|
33
|
+
}
|
|
34
|
+
RUCY_END
|
|
35
|
+
|
|
36
|
+
static
|
|
37
|
+
RUCY_DEF1(initialize_copy, obj)
|
|
38
|
+
{
|
|
39
|
+
RUCY_CHECK_OBJ(Rays::Video, self);
|
|
40
|
+
|
|
41
|
+
*THIS = to<Rays::Video&>(obj).dup();
|
|
42
|
+
}
|
|
43
|
+
RUCY_END
|
|
44
|
+
|
|
45
|
+
static
|
|
46
|
+
RUCY_DEF2(insert, index, image)
|
|
47
|
+
{
|
|
48
|
+
CHECK;
|
|
49
|
+
THIS->insert(to<size_t>(index), to<const Rays::Image&>(image));
|
|
50
|
+
return self;
|
|
51
|
+
}
|
|
52
|
+
RUCY_END
|
|
53
|
+
|
|
54
|
+
static
|
|
55
|
+
RUCY_DEF1(append, image)
|
|
56
|
+
{
|
|
57
|
+
CHECK;
|
|
58
|
+
THIS->append(to<const Rays::Image&>(image));
|
|
59
|
+
return self;
|
|
60
|
+
}
|
|
61
|
+
RUCY_END
|
|
62
|
+
|
|
63
|
+
static
|
|
64
|
+
RUCY_DEF1(remove, index)
|
|
65
|
+
{
|
|
66
|
+
CHECK;
|
|
67
|
+
THIS->remove(to<size_t>(index));
|
|
68
|
+
return self;
|
|
69
|
+
}
|
|
70
|
+
RUCY_END
|
|
71
|
+
|
|
72
|
+
static
|
|
73
|
+
RUCY_DEF1(save, path)
|
|
74
|
+
{
|
|
75
|
+
CHECK;
|
|
76
|
+
THIS->save(path.c_str());
|
|
77
|
+
return self;
|
|
78
|
+
}
|
|
79
|
+
RUCY_END
|
|
80
|
+
|
|
81
|
+
static
|
|
82
|
+
RUCY_DEF0(width)
|
|
83
|
+
{
|
|
84
|
+
CHECK;
|
|
85
|
+
return value(THIS->width());
|
|
86
|
+
}
|
|
87
|
+
RUCY_END
|
|
88
|
+
|
|
89
|
+
static
|
|
90
|
+
RUCY_DEF0(height)
|
|
91
|
+
{
|
|
92
|
+
CHECK;
|
|
93
|
+
return value(THIS->height());
|
|
94
|
+
}
|
|
95
|
+
RUCY_END
|
|
96
|
+
|
|
97
|
+
static
|
|
98
|
+
RUCY_DEF0(fps)
|
|
99
|
+
{
|
|
100
|
+
CHECK;
|
|
101
|
+
return value(THIS->fps());
|
|
102
|
+
}
|
|
103
|
+
RUCY_END
|
|
104
|
+
|
|
105
|
+
static
|
|
106
|
+
RUCY_DEF0(pixel_density)
|
|
107
|
+
{
|
|
108
|
+
CHECK;
|
|
109
|
+
return value(THIS->pixel_density());
|
|
110
|
+
}
|
|
111
|
+
RUCY_END
|
|
112
|
+
|
|
113
|
+
static
|
|
114
|
+
RUCY_DEF0(size)
|
|
115
|
+
{
|
|
116
|
+
CHECK;
|
|
117
|
+
return value(THIS->size());
|
|
118
|
+
}
|
|
119
|
+
RUCY_END
|
|
120
|
+
|
|
121
|
+
static
|
|
122
|
+
RUCY_DEF0(empty)
|
|
123
|
+
{
|
|
124
|
+
CHECK;
|
|
125
|
+
return value(THIS->empty());
|
|
126
|
+
}
|
|
127
|
+
RUCY_END
|
|
128
|
+
|
|
129
|
+
static
|
|
130
|
+
RUCY_DEF1(set_position, position)
|
|
131
|
+
{
|
|
132
|
+
CHECK;
|
|
133
|
+
THIS->set_position(to<size_t>(position));
|
|
134
|
+
return position;
|
|
135
|
+
}
|
|
136
|
+
RUCY_END
|
|
137
|
+
|
|
138
|
+
static
|
|
139
|
+
RUCY_DEF0(get_position)
|
|
140
|
+
{
|
|
141
|
+
CHECK;
|
|
142
|
+
return value(THIS->position());
|
|
143
|
+
}
|
|
144
|
+
RUCY_END
|
|
145
|
+
|
|
146
|
+
static
|
|
147
|
+
RUCY_DEF0(each)
|
|
148
|
+
{
|
|
149
|
+
CHECK;
|
|
150
|
+
Value ret;
|
|
151
|
+
for (auto it = THIS->begin(), end = THIS->end(); it != end; ++it)
|
|
152
|
+
ret = rb_yield(value(*it));
|
|
153
|
+
return ret;
|
|
154
|
+
}
|
|
155
|
+
RUCY_END
|
|
156
|
+
|
|
157
|
+
static
|
|
158
|
+
RUCY_DEF0(to_image)
|
|
159
|
+
{
|
|
160
|
+
CHECK;
|
|
161
|
+
return value((Rays::Image) *THIS);
|
|
162
|
+
}
|
|
163
|
+
RUCY_END
|
|
164
|
+
|
|
165
|
+
static
|
|
166
|
+
RUCY_DEF1(at, index)
|
|
167
|
+
{
|
|
168
|
+
CHECK;
|
|
169
|
+
return value((*THIS)[(size_t) to<int>(index)]);
|
|
170
|
+
}
|
|
171
|
+
RUCY_END
|
|
172
|
+
|
|
173
|
+
static
|
|
174
|
+
RUCY_DEF0(play)
|
|
175
|
+
{
|
|
176
|
+
CHECK;
|
|
177
|
+
THIS->play();
|
|
178
|
+
return self;
|
|
179
|
+
}
|
|
180
|
+
RUCY_END
|
|
181
|
+
|
|
182
|
+
static
|
|
183
|
+
RUCY_DEF0(pause)
|
|
184
|
+
{
|
|
185
|
+
CHECK;
|
|
186
|
+
THIS->pause();
|
|
187
|
+
return self;
|
|
188
|
+
}
|
|
189
|
+
RUCY_END
|
|
190
|
+
|
|
191
|
+
static
|
|
192
|
+
RUCY_DEF0(stop)
|
|
193
|
+
{
|
|
194
|
+
CHECK;
|
|
195
|
+
THIS->stop();
|
|
196
|
+
return self;
|
|
197
|
+
}
|
|
198
|
+
RUCY_END
|
|
199
|
+
|
|
200
|
+
static
|
|
201
|
+
RUCY_DEF1(set_time_scale, scale)
|
|
202
|
+
{
|
|
203
|
+
CHECK;
|
|
204
|
+
THIS->set_time_scale(to<float>(scale));
|
|
205
|
+
return scale;
|
|
206
|
+
}
|
|
207
|
+
RUCY_END
|
|
208
|
+
|
|
209
|
+
static
|
|
210
|
+
RUCY_DEF0(get_time_scale)
|
|
211
|
+
{
|
|
212
|
+
CHECK;
|
|
213
|
+
return value(THIS->time_scale());
|
|
214
|
+
}
|
|
215
|
+
RUCY_END
|
|
216
|
+
|
|
217
|
+
static
|
|
218
|
+
RUCY_DEF1(load, path)
|
|
219
|
+
{
|
|
220
|
+
return value(Rays::load_video(path.c_str()));
|
|
221
|
+
}
|
|
222
|
+
RUCY_END
|
|
223
|
+
|
|
224
|
+
static
|
|
225
|
+
RUCY_DEF0(exts)
|
|
226
|
+
{
|
|
227
|
+
std::vector<Value> list;
|
|
228
|
+
for (const auto& ext : Rays::get_video_exts())
|
|
229
|
+
list.emplace_back(ext.c_str());
|
|
230
|
+
return array(list.data(), list.size());
|
|
231
|
+
}
|
|
232
|
+
RUCY_END
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
static Class cVideo;
|
|
236
|
+
|
|
237
|
+
void
|
|
238
|
+
Init_rays_video ()
|
|
239
|
+
{
|
|
240
|
+
Module mRays = define_module("Rays");
|
|
241
|
+
|
|
242
|
+
cVideo = mRays.define_class("Video");
|
|
243
|
+
cVideo.define_alloc_func(alloc);
|
|
244
|
+
cVideo.define_private_method("initialize!", initialize);
|
|
245
|
+
cVideo.define_private_method("initialize_copy", initialize_copy);
|
|
246
|
+
cVideo.define_method("insert!", insert);
|
|
247
|
+
cVideo.define_method("append!", append);
|
|
248
|
+
cVideo.define_method("remove!", remove);
|
|
249
|
+
cVideo.define_method("save", save);
|
|
250
|
+
cVideo.define_method("width", width);
|
|
251
|
+
cVideo.define_method("height", height);
|
|
252
|
+
cVideo.define_method("fps", fps);
|
|
253
|
+
cVideo.define_method("pixel_density", pixel_density);
|
|
254
|
+
cVideo.define_method("size", size);
|
|
255
|
+
cVideo.define_method("empty?", empty);
|
|
256
|
+
cVideo.define_method("position=", set_position);
|
|
257
|
+
cVideo.define_method("position", get_position);
|
|
258
|
+
cVideo.define_method("play", play);
|
|
259
|
+
cVideo.define_method("pause", pause);
|
|
260
|
+
cVideo.define_method("stop", stop);
|
|
261
|
+
cVideo.define_method("time_scale=", set_time_scale);
|
|
262
|
+
cVideo.define_method("time_scale", get_time_scale);
|
|
263
|
+
cVideo.define_method("each!", each);
|
|
264
|
+
cVideo.define_method("to_image", to_image);
|
|
265
|
+
cVideo.define_method("[]", at);
|
|
266
|
+
cVideo.define_module_function("load", load);
|
|
267
|
+
cVideo.define_module_function("exts", exts);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
namespace Rays
|
|
272
|
+
{
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
Class
|
|
276
|
+
video_class ()
|
|
277
|
+
{
|
|
278
|
+
return cVideo;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
}// Rays
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
// -*- c++ -*-
|
|
2
|
+
#pragma once
|
|
3
|
+
#ifndef __RAYS_VIDEO_H__
|
|
4
|
+
#define __RAYS_VIDEO_H__
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
#include <vector>
|
|
8
|
+
#include <xot/pimpl.h>
|
|
9
|
+
#include <xot/string.h>
|
|
10
|
+
#include <rays/defs.h>
|
|
11
|
+
#include <rays/image.h>
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
namespace Rays
|
|
15
|
+
{
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class Video
|
|
19
|
+
{
|
|
20
|
+
|
|
21
|
+
typedef Video This;
|
|
22
|
+
|
|
23
|
+
public:
|
|
24
|
+
|
|
25
|
+
typedef std::vector<Image> ImageList;
|
|
26
|
+
|
|
27
|
+
typedef ImageList::const_iterator const_iterator;
|
|
28
|
+
|
|
29
|
+
enum {DEFAULT_FPS = 30};
|
|
30
|
+
|
|
31
|
+
Video ();
|
|
32
|
+
|
|
33
|
+
Video (
|
|
34
|
+
int width, int height,
|
|
35
|
+
float fps = DEFAULT_FPS, float pixel_density = 1);
|
|
36
|
+
|
|
37
|
+
~Video ();
|
|
38
|
+
|
|
39
|
+
This dup () const;
|
|
40
|
+
|
|
41
|
+
void insert (size_t index, const Image& image);
|
|
42
|
+
|
|
43
|
+
void append (const Image& image);
|
|
44
|
+
|
|
45
|
+
void remove (size_t index);
|
|
46
|
+
|
|
47
|
+
void play ();
|
|
48
|
+
|
|
49
|
+
void pause ();
|
|
50
|
+
|
|
51
|
+
void stop ();
|
|
52
|
+
|
|
53
|
+
void set_time_scale (float scale);
|
|
54
|
+
|
|
55
|
+
float time_scale () const;
|
|
56
|
+
|
|
57
|
+
void save (const char* path);
|
|
58
|
+
|
|
59
|
+
coord width () const;
|
|
60
|
+
|
|
61
|
+
coord height () const;
|
|
62
|
+
|
|
63
|
+
float fps () const;
|
|
64
|
+
|
|
65
|
+
float pixel_density () const;
|
|
66
|
+
|
|
67
|
+
size_t size () const;
|
|
68
|
+
|
|
69
|
+
bool empty () const;
|
|
70
|
+
|
|
71
|
+
void set_position (size_t index);
|
|
72
|
+
|
|
73
|
+
size_t position () const;
|
|
74
|
+
|
|
75
|
+
const_iterator begin () const;
|
|
76
|
+
|
|
77
|
+
const_iterator end () const;
|
|
78
|
+
|
|
79
|
+
Image operator [] (size_t index) const;
|
|
80
|
+
|
|
81
|
+
operator Image () const;
|
|
82
|
+
|
|
83
|
+
operator bool () const;
|
|
84
|
+
|
|
85
|
+
bool operator ! () const;
|
|
86
|
+
|
|
87
|
+
struct Data;
|
|
88
|
+
|
|
89
|
+
Xot::PSharedImpl<Data> self;
|
|
90
|
+
|
|
91
|
+
};// Video
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
Video load_video (const char* path);
|
|
95
|
+
|
|
96
|
+
const StringList& get_video_exts ();
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
}// Rays
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
#endif//EOH
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// -*- c++ -*-
|
|
2
|
+
#pragma once
|
|
3
|
+
#ifndef __RAYS_VIDEO_RUBY_VIDEO_H__
|
|
4
|
+
#define __RAYS_VIDEO_RUBY_VIDEO_H__
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
#include <rucy/class.h>
|
|
8
|
+
#include <rucy/extension.h>
|
|
9
|
+
#include <rays/video.h>
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
#if defined(WIN32) && defined(GCC) && defined(RAYS_VIDEO)
|
|
13
|
+
#define RAYS_VIDEO_EXPORT __declspec(dllexport)
|
|
14
|
+
#else
|
|
15
|
+
#define RAYS_VIDEO_EXPORT
|
|
16
|
+
#endif
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
RUCY_DECLARE_VALUE_FROM_TO(RAYS_VIDEO_EXPORT, Rays::Video)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
namespace Rays
|
|
23
|
+
{
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
RAYS_VIDEO_EXPORT Rucy::Class video_class ();
|
|
27
|
+
// class Rays::Video
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
}// Rays
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
namespace Rucy
|
|
34
|
+
{
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
template <> inline Class
|
|
38
|
+
get_ruby_class<Rays::Video> ()
|
|
39
|
+
{
|
|
40
|
+
return Rays::video_class();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
}// Rucy
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
#endif//EOH
|