Project

rays-video

0.0
The project is in a healthy, maintained state
Video encoding/decoding with audio support using Rays and Beeps.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Runtime

~> 0.3.14
~> 0.3.14
~> 0.3.13
~> 0.3.13
 Project Readme

Rays Video - Video support for Rays

Ask DeepWiki License Build Status Gem Version

⚠️ Notice

This repository is a read-only mirror of our monorepo. We do not accept pull requests or direct contributions here.

🔄 Where to Contribute?

All development happens in our xord/all monorepo, which contains all our main libraries. If you'd like to contribute, please submit your changes there.

For more details, check out our Contribution Guidelines.

Thanks for your support! 🙌

🚀 About

Rays Video is a small extension to 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.

Audio support is built on Beeps — video files keep their audio track and it can be fed into a Beeps processor chain.

Like the rest of the xord/* family, this gem is primarily developed for our own use, but it works as a standalone video gem.

Platform status: macOS / iOS only at the moment. Windows and Linux backends are not yet implemented.

📋 Requirements

  • Ruby 3.0.0 or later
  • A C++ compiler with C++20 support
  • Xot, Rucy, Beeps, and Rays (declared as runtime dependencies)
  • macOS / iOS — AVFoundation (bundled with the OS)

📦 Installation

Add this line to your Gemfile:

gem 'rays-video'

Then install:

$ bundle install

Or install it directly:

$ gem install rays-video

📚 What's Provided

Rays::Video

A finite sequence of Rays::Image frames with a fixed width, height, fps, and pixel_density.

Method Purpose
Video.new(width, height, fps:, pixel_density:) Create an empty video (fps defaults to 30)
Video.load(path) Load a video file from disk
Video.exts Supported video file extensions on the current platform
video.append(*images) Append one or more frames
video.insert(index, *images) Insert frames at the given index
video.remove(index) Remove the frame at the given index
video.each { |image| ... } Iterate frames (also includes Enumerable)
video[i] Get the frame at index i as a Rays::Image
video.pos / video.pos = Current playback position (index)
video.play / video.pause / video.stop Playback controls
video.time_scale / video.time_scale = Speed multiplier for playback
video.size, video.empty? Frame count / emptiness
video.width, video.height, video.fps, video.pixel_density Read-only metadata
video.dup Deep-ish copy (shares image references)
video.save(path) Encode the video to a file
video.to_image (Image() cast) Get the frame at the current pos as a Rays::Image

💡 Usage

Build a video from frames and save it

require 'rays'
require 'rays/video'

video = Rays::Video.new(320, 240, fps: 30)

60.times do |n|
  frame = Rays::Image.new(320, 240)
  frame.paint do |p|
    p.background 0
    p.fill 1, 0.5, 0.1
    p.ellipse n * 5, 120, 60, 60
  end
  video.append frame
end

video.save 'out.mp4'

Load a video and draw a frame

require 'rays'
require 'rays/video'

video = Rays::Video.load 'clip.mp4'
puts "#{video.width}×#{video.height} @ #{video.fps}fps, #{video.size} frames"

# get the 30th frame as an Image and save it
video[30].save 'frame30.png'

Scrub through a video

video = Rays::Video.load 'clip.mp4'

video.pos = 0
target = Rays::Image.new video.width, video.height
target.paint do |p|
  p.image video.to_image
end

video.pos = video.size / 2     # mid-point
mid = video.to_image

🛠️ Development

$ rake lib    # build the native C++ library (librays-video)
$ rake ext    # build the Ruby C extension
$ rake test   # run the test suite (macOS / iOS only)
$ rake doc    # generate RDoc from C++ sources
$ rake       # default: builds the extension

In the xord/all monorepo you can scope by module, e.g. rake rays-video test.

📜 License

Rays Video is licensed under the MIT License. See the LICENSE file for details.