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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 5cb509bb4eb254fc941b27cf407d366a6ff89bee5f2393056ef846f9771f6888
4
+ data.tar.gz: 7e666166ba3371544280889621ddcf24f4c5474317a7523393fc7eb29acf4315
5
+ SHA512:
6
+ metadata.gz: ae9ca108005e2729028cfa31f721ea729cc608dc6ad228c51b90b564379ecd4e821b15ae6dd8812088b2e288fd2e1187fa033b0fcdf43dae0ef228eaf3ab8d54
7
+ data.tar.gz: a5839a31f749ea2daa8f6af8e421149e2c3ab5f7fa1a6a1eacdbcf7a9a4dda523ead71e95ca291c2a49080d10a08709b3a47dfc821e9ee5e35e4a8ac6a727b70
@@ -0,0 +1,17 @@
1
+ #include "defs.h"
2
+
3
+
4
+ void Init_rays_video ();
5
+
6
+
7
+ extern "C" void
8
+ Init_rays_video_ext ()
9
+ {
10
+ RUCY_TRY
11
+
12
+ Rucy::init();
13
+
14
+ Init_rays_video();
15
+
16
+ RUCY_CATCH
17
+ }
@@ -0,0 +1,257 @@
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
+ VALUE alloc(VALUE klass)
17
+ {
18
+ return new_type<Rays::Video>(klass);
19
+ }
20
+
21
+ static
22
+ VALUE initialize(VALUE self, VALUE width, VALUE height, VALUE fps, VALUE pixel_density)
23
+ {
24
+ RUCY_CHECK_OBJ(Rays::Video, self);
25
+
26
+ float fps_ = to<float>(fps);
27
+ *THIS = Rays::Video(
28
+ to<int>(width),
29
+ to<int>(height),
30
+ fps_ > 0 ? fps_ : (float) Rays::Video::DEFAULT_FPS,
31
+ to<float>(pixel_density));
32
+ }
33
+
34
+ static
35
+ VALUE initialize_copy(VALUE self, VALUE obj)
36
+ {
37
+ RUCY_CHECK_OBJ(Rays::Video, self);
38
+
39
+ *THIS = to<Rays::Video&>(obj).dup();
40
+ }
41
+
42
+ static
43
+ VALUE insert(VALUE self, VALUE index, VALUE image)
44
+ {
45
+ CHECK;
46
+ THIS->insert(to<size_t>(index), to<const Rays::Image&>(image));
47
+ return self;
48
+ }
49
+
50
+ static
51
+ VALUE append(VALUE self, VALUE image)
52
+ {
53
+ CHECK;
54
+ THIS->append(to<const Rays::Image&>(image));
55
+ return self;
56
+ }
57
+
58
+ static
59
+ VALUE remove(VALUE self, VALUE index)
60
+ {
61
+ CHECK;
62
+ THIS->remove(to<size_t>(index));
63
+ return self;
64
+ }
65
+
66
+ static
67
+ VALUE save(VALUE self, VALUE path)
68
+ {
69
+ CHECK;
70
+ THIS->save(path.c_str());
71
+ return self;
72
+ }
73
+
74
+ static
75
+ VALUE width(VALUE self)
76
+ {
77
+ CHECK;
78
+ return value(THIS->width());
79
+ }
80
+
81
+ static
82
+ VALUE height(VALUE self)
83
+ {
84
+ CHECK;
85
+ return value(THIS->height());
86
+ }
87
+
88
+ static
89
+ VALUE fps(VALUE self)
90
+ {
91
+ CHECK;
92
+ return value(THIS->fps());
93
+ }
94
+
95
+ static
96
+ VALUE pixel_density(VALUE self)
97
+ {
98
+ CHECK;
99
+ return value(THIS->pixel_density());
100
+ }
101
+
102
+ static
103
+ VALUE size(VALUE self)
104
+ {
105
+ CHECK;
106
+ return value(THIS->size());
107
+ }
108
+
109
+ static
110
+ VALUE empty(VALUE self)
111
+ {
112
+ CHECK;
113
+ return value(THIS->empty());
114
+ }
115
+
116
+ static
117
+ VALUE set_position(VALUE self, VALUE position)
118
+ {
119
+ CHECK;
120
+ THIS->set_position(to<size_t>(position));
121
+ return position;
122
+ }
123
+
124
+ static
125
+ VALUE get_position(VALUE self)
126
+ {
127
+ CHECK;
128
+ return value(THIS->position());
129
+ }
130
+
131
+ static
132
+ VALUE each(VALUE self)
133
+ {
134
+ CHECK;
135
+ Value ret;
136
+ for (auto it = THIS->begin(), end = THIS->end(); it != end; ++it)
137
+ ret = rb_yield(value(*it));
138
+ return ret;
139
+ }
140
+
141
+ static
142
+ VALUE to_image(VALUE self)
143
+ {
144
+ CHECK;
145
+ return value((Rays::Image) *THIS);
146
+ }
147
+
148
+ static
149
+ VALUE at(VALUE self, VALUE index)
150
+ {
151
+ CHECK;
152
+ return value((*THIS)[(size_t) to<int>(index)]);
153
+ }
154
+
155
+ static
156
+ VALUE play(VALUE self)
157
+ {
158
+ CHECK;
159
+ THIS->play();
160
+ return self;
161
+ }
162
+
163
+ static
164
+ VALUE pause(VALUE self)
165
+ {
166
+ CHECK;
167
+ THIS->pause();
168
+ return self;
169
+ }
170
+
171
+ static
172
+ VALUE stop(VALUE self)
173
+ {
174
+ CHECK;
175
+ THIS->stop();
176
+ return self;
177
+ }
178
+
179
+ static
180
+ VALUE set_time_scale(VALUE self, VALUE scale)
181
+ {
182
+ CHECK;
183
+ THIS->set_time_scale(to<float>(scale));
184
+ return scale;
185
+ }
186
+
187
+ static
188
+ VALUE get_time_scale(VALUE self)
189
+ {
190
+ CHECK;
191
+ return value(THIS->time_scale());
192
+ }
193
+
194
+ static
195
+ VALUE load(VALUE self, VALUE path)
196
+ {
197
+ return value(Rays::load_video(path.c_str()));
198
+ }
199
+
200
+ static
201
+ VALUE exts(VALUE self)
202
+ {
203
+ std::vector<Value> list;
204
+ for (const auto& ext : Rays::get_video_exts())
205
+ list.emplace_back(ext.c_str());
206
+ return array(list.data(), list.size());
207
+ }
208
+
209
+
210
+ static Class cVideo;
211
+
212
+ void
213
+ Init_rays_video ()
214
+ {
215
+ Module mRays = rb_define_module("Rays");
216
+
217
+ cVideo = rb_define_class_under(mRays, "Video", rb_cObject);
218
+ rb_define_alloc_func(cVideo, alloc);
219
+ cVideo.define_private_method("initialize!", initialize);
220
+ rb_define_private_method(cVideo, "initialize_copy", RUBY_METHOD_FUNC(initialize_copy), 1);
221
+ cVideo.define_method("insert!", insert);
222
+ cVideo.define_method("append!", append);
223
+ cVideo.define_method("remove!", remove);
224
+ rb_define_method(cVideo, "save", RUBY_METHOD_FUNC(save), 1);
225
+ rb_define_method(cVideo, "width", RUBY_METHOD_FUNC(width), 0);
226
+ rb_define_method(cVideo, "height", RUBY_METHOD_FUNC(height), 0);
227
+ rb_define_method(cVideo, "fps", RUBY_METHOD_FUNC(fps), 0);
228
+ rb_define_method(cVideo, "pixel_density", RUBY_METHOD_FUNC(pixel_density), 0);
229
+ rb_define_method(cVideo, "size", RUBY_METHOD_FUNC(size), 0);
230
+ cVideo.define_method("empty?", empty);
231
+ rb_define_method(cVideo, "position=", RUBY_METHOD_FUNC(set_position), 1);
232
+ rb_define_method(cVideo, "position", RUBY_METHOD_FUNC(get_position), 0);
233
+ rb_define_method(cVideo, "play", RUBY_METHOD_FUNC(play), 0);
234
+ rb_define_method(cVideo, "pause", RUBY_METHOD_FUNC(pause), 0);
235
+ rb_define_method(cVideo, "stop", RUBY_METHOD_FUNC(stop), 0);
236
+ rb_define_method(cVideo, "time_scale=", RUBY_METHOD_FUNC(set_time_scale), 1);
237
+ rb_define_method(cVideo, "time_scale", RUBY_METHOD_FUNC(get_time_scale), 0);
238
+ cVideo.define_method("each!", each);
239
+ rb_define_method(cVideo, "to_image", RUBY_METHOD_FUNC(to_image), 0);
240
+ cVideo.define_method("[]", at);
241
+ rb_define_module_function(cVideo, "load", RUBY_METHOD_FUNC(load), 1);
242
+ rb_define_module_function(cVideo, "exts", RUBY_METHOD_FUNC(exts), 0);
243
+ }
244
+
245
+
246
+ namespace Rays
247
+ {
248
+
249
+
250
+ Class
251
+ video_class ()
252
+ {
253
+ return cVideo;
254
+ }
255
+
256
+
257
+ }// Rays
@@ -0,0 +1,12 @@
1
+ ## Pull Requests Not Accepted 🚫
2
+
3
+ Thank you for your interest in contributing!
4
+ However, this repository does not accept pull requests directly.
5
+
6
+ ### Where to Contribute?
7
+
8
+ Please submit your changes to the [xord/all](https://github.com/xord/all) monorepo, which serves as the primary repository for all our main libraries.
9
+
10
+ For more details, please refer to our [contribution guidelines](../CONTRIBUTING.md).
11
+
12
+ Thanks for your understanding! 🙌
@@ -0,0 +1,51 @@
1
+ name: Release Gem
2
+
3
+ on:
4
+ push:
5
+ tags: ['v[0-9]*']
6
+
7
+ permissions:
8
+ contents: write
9
+
10
+ jobs:
11
+ release:
12
+ runs-on: macos-latest
13
+
14
+ steps:
15
+ - name: ruby 3.2
16
+ uses: ruby/setup-ruby@v1
17
+ with:
18
+ ruby-version: 3.2
19
+
20
+ - name: checkout
21
+ uses: actions/checkout@v4
22
+
23
+ - name: setup gems
24
+ run: bundle install
25
+
26
+ - name: setup dependencies
27
+ run: "ruby -I.github/workflows -rutils -e 'setup_dependencies'"
28
+
29
+ - name: test
30
+ run: bundle exec rake packages test
31
+
32
+ - name: create gem
33
+ id: gem
34
+ run: |
35
+ bundle exec rake gem
36
+ echo path=$(ruby -e 'print Dir.glob("*.gem").first') >> $GITHUB_OUTPUT
37
+
38
+ - name: create github release
39
+ env:
40
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
41
+ run: ruby -I.github/workflows -rutils -e 'release(*ARGV)' ./${{ steps.gem.outputs.path }}
42
+
43
+ - name: upload to rubygems
44
+ env:
45
+ GEM_HOST_API_KEY: ${{ secrets.RUBYGEMS_AUTH_TOKEN }}
46
+ run: |
47
+ mkdir -p $HOME/.gem
48
+ touch $HOME/.gem/credentials
49
+ chmod 0600 $HOME/.gem/credentials
50
+ printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
51
+ bundle exec rake upload
@@ -0,0 +1,35 @@
1
+ name: Tag
2
+
3
+ on:
4
+ push:
5
+ branches: [master]
6
+
7
+ jobs:
8
+ tag:
9
+ runs-on: ubuntu-latest
10
+
11
+ steps:
12
+ - name: ruby 3.2
13
+ uses: ruby/setup-ruby@v1
14
+ with:
15
+ ruby-version: 3.2
16
+
17
+ - name: checkout
18
+ uses: actions/checkout@v4
19
+ with:
20
+ fetch-depth: 0
21
+ token: ${{ secrets.PAT }}
22
+
23
+ - name: setup dependencies
24
+ run: "ruby -I.github/workflows -rutils -e 'setup_dependencies only: :xot'"
25
+
26
+ - name: setup user name and email
27
+ run: |
28
+ git config --global user.email "xordog@gmail.com"
29
+ git config --global user.name "xord"
30
+
31
+ - name: tag versions
32
+ run: "ruby -I.github/workflows -rutils -e 'tag_versions'"
33
+
34
+ - name: push tags
35
+ run: git push origin --tags
@@ -0,0 +1,37 @@
1
+ name: Test
2
+
3
+ on:
4
+ push:
5
+ branches: [master]
6
+ pull_request:
7
+
8
+ jobs:
9
+ test:
10
+ runs-on: macos-latest
11
+
12
+ steps:
13
+ - name: ruby 3.2
14
+ uses: ruby/setup-ruby@v1
15
+ with:
16
+ ruby-version: 3.2
17
+
18
+ - name: checkout
19
+ uses: actions/checkout@v4
20
+
21
+ - name: setup gems
22
+ run: bundle install
23
+
24
+ - name: setup dependencies
25
+ run: "ruby -I.github/workflows -rutils -e 'setup_dependencies'"
26
+
27
+ - name: packages
28
+ run: bundle exec rake verbose packages
29
+
30
+ - name: lib
31
+ run: bundle exec rake verbose lib
32
+
33
+ - name: ext
34
+ run: bundle exec rake verbose ext
35
+
36
+ - name: test
37
+ run: bundle exec rake verbose test
@@ -0,0 +1,127 @@
1
+ require 'shellwords'
2
+
3
+ ALL_REPO = 'xord/all'
4
+ ALL_DIR = '../all'
5
+ ALL_FETCH_DEPTH = 100
6
+
7
+ RENAMES = {reflex: 'reflexion'}
8
+
9
+ def sh(cmd)
10
+ puts cmd
11
+ system cmd
12
+ end
13
+
14
+ def setup_dependencies(only: nil)
15
+ gemspec_path = `git ls-files`.lines(chomp: true).find {|l| l =~ /\.gemspec$/}
16
+ return unless gemspec_path
17
+
18
+ gemspec = File.read gemspec_path
19
+ name = File.basename gemspec_path, '.gemspec'
20
+
21
+ exts = File.readlines('Rakefile')
22
+ .map {|l| l[%r|^\s*require\W+([\w\-\_]+)/extension\W+$|, 1]}
23
+ .compact
24
+ .reject {|ext| ext == name}
25
+ exts = exts & [only].flatten.map(&:to_s) if only
26
+ return if exts.empty?
27
+
28
+ unless setup_dependencies_via_monorepo(exts)
29
+ setup_dependencies_via_each_repo_by_version(gemspec, exts)
30
+ end
31
+
32
+ exts.each {|ext| sh %( cd ../#{ext} && rake ext )}
33
+ end
34
+
35
+ def setup_dependencies_via_monorepo(exts)
36
+ return false unless checkout_monorepo
37
+ exts.each {|ext| sh %( ln -snf all/#{ext} ../#{ext} )}
38
+ true
39
+ end
40
+
41
+ def checkout_monorepo()
42
+ uuid = `git log -1 --format=%B`[/^\[\[([0-9a-fA-F-]+)\]\]$/, 1]
43
+ return false unless uuid
44
+
45
+ commit = setup_monorepo uuid
46
+ return false unless commit
47
+
48
+ Dir.chdir(ALL_DIR) {sh %( git checkout -q #{commit} )}
49
+ true
50
+ end
51
+
52
+ def setup_monorepo(uuid)
53
+ unless File.directory? ALL_DIR
54
+ url = "https://github.com/#{ALL_REPO}.git"
55
+ sh %( git clone --no-tags --depth #{ALL_FETCH_DEPTH} #{url} #{ALL_DIR} )
56
+ end
57
+ loop do
58
+ commit = find_monorepo_commit uuid
59
+ return commit if commit
60
+
61
+ deepened = Dir.chdir ALL_DIR do
62
+ before = `git rev-list --count HEAD`.to_i
63
+ sh %( git fetch --deepen #{ALL_FETCH_DEPTH} )
64
+ `git rev-list --count HEAD`.to_i > before
65
+ end
66
+ return nil unless deepened
67
+ end
68
+ end
69
+
70
+ def find_monorepo_commit(uuid)
71
+ Dir.chdir ALL_DIR do
72
+ out = `git log origin/HEAD -F --grep="[[#{uuid}]]" --format=%H -1`.strip
73
+ out.empty? ? nil : out
74
+ end
75
+ end
76
+
77
+ def setup_dependencies_via_each_repo_by_version(gemspec, exts)
78
+ exts.each do |ext|
79
+ gem = RENAMES[ext.to_sym].then {|s| s || ext}
80
+ ver = gemspec[/add_dependency.*['"]#{gem}['"].*['"]\s*~>\s*([\d\.]+)\s*['"]/, 1]
81
+ opts = '-c advice.detachedHead=false --depth 1'
82
+ clone = "git clone #{opts} https://github.com/xord/#{ext}.git ../#{ext}"
83
+
84
+ # 'rake subtree:push' pushes all subrepos, so cloning by new tag
85
+ # often fails before tagging each new tag
86
+ sh %( #{clone} --branch v#{ver} || #{clone} )
87
+ end
88
+ end
89
+
90
+ def tag_versions()
91
+ changes = changelogs
92
+ tags = `git tag`.lines chomp: true
93
+ vers = `git log --oneline ./VERSION`
94
+ .lines(chomp: true)
95
+ .map {|line| line.split.first[/^\w+$/]}
96
+ .map {|sha| [`git cat-file -p #{sha}:./VERSION 2>/dev/null`[/[\d\.]+/], sha]}
97
+ .select {|ver, sha| ver && sha}
98
+ .reverse
99
+ .to_h
100
+
101
+ vers.to_a.reverse.each do |ver, sha|
102
+ tag = "v#{ver}"
103
+ break if tags.include?(tag)
104
+ sh %( git tag -a -m \"#{changes[tag]&.gsub '"', '\\"'}\" #{tag} #{sha} )
105
+ end
106
+ end
107
+
108
+ def release(*paths)
109
+ tag = ENV['GITHUB_REF']&.sub(%r|^refs/tags/|, '') || raise('GITHUB_REF tag not set')
110
+ notes = (changelogs[tag] || '').shellescape
111
+ paths = paths.flatten.join ' '
112
+
113
+ sh(%( gh release create #{tag} #{paths} --notes #{notes} )) ||
114
+ sh(%( gh release upload #{tag} #{paths} --clobber )) ||
115
+ raise('failed to upload to releases')
116
+ end
117
+
118
+ def changelogs()
119
+ File.read('ChangeLog.md')
120
+ .split(/^\s*##\s*\[\s*(v[\d\.]+)\s*\].*$/)
121
+ .slice(1..)
122
+ .each_slice(2)
123
+ .to_h
124
+ .transform_values(&:strip!)
125
+ rescue Errno::ENOENT
126
+ raise 'failed to get changelogs'
127
+ end
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,7 @@
1
+ # Contribution Guide
2
+
3
+ Thank you for your interest in contributing!
4
+ However, this repository does not accept pull requests.
5
+ Instead, please submit your changes to the [xord/all](https://github.com/xord/all) monorepo, which serves as the primary repository for all our main libraries.
6
+
7
+ For any questions, feel free to open an issue.
data/ChangeLog.md ADDED
@@ -0,0 +1,19 @@
1
+ # rays-video ChangeLog
2
+
3
+
4
+ ## [v0.1.2] - 2026-05-17
5
+
6
+ - Rewrite README.md
7
+ - Add PR template
8
+ - CI: Migrate release-gem.yml from actions/create-release to gh release create
9
+
10
+
11
+ ## [v0.1.1] - 2026-05-10
12
+
13
+ - Add VideoAudioIn to support audio playback in Video class
14
+ - Remove deprecated has_rdoc= from gemspecs
15
+
16
+
17
+ ## [v0.1] - 2026-04-23
18
+
19
+ - Initial version
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'rake'
4
+ gem 'test-unit'
5
+ gem 'yard'
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 xordog
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.