Project

vcs_ruby

0.01
No commit activity in last 3 years
No release in over 3 years
Creates a contact sheet, a preview, of a video, usable as library or as a script. Based on VCS *NIX. Creating Thumbnails with libav, ffmpeg or mplayer and compose it with ImageMagick into nice looking sheets.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

>= 1.5.0, ~> 1.5
>= 5.0.0, ~> 5.10
>= 1.0.0, ~> 1.1
>= 11.0.0, ~> 11.0

Runtime

>= 4.0.0, ~> 4.0
 Project Readme

vcs_ruby

Video Contact Sheet for Ruby

Gem Version Build Status

I do like the results of the "Video Contact Sheet *NIX" but the Script is written as a Shell Script and naturally this makes it hard to understand and extend.

vcs.rb has several applications in mind

  1. It should be usable as a library in rails to make video captures easy.
  2. It should be usable as a simple script imitating the original vcs script.
  3. Capturing single frames from a video
  4. Gathering meta information from a video. (streamio replacement)

Example 1

Code Example

  require 'vcs.rb'

  video = VCSRuby::Video.new 'video.mkv'
  sheet = video.contact_sheet

  sheet.format = :jpg
  sheet.sheet.initialize_geometry(3,3,nil)
  sheet.signature = nil
  sheet.thumbnail_width = 320
  sheet.initialize_filename('out.jpg')
  sheet.build

  frame = video.frame VCSRuby::TimeIndex.new('1:22')
  frame.filename = "frame.jpg"
  frame.capture_and_evade # evade blank frames

Help

Installation

gem install vcs_ruby

Library

You will only need the CaptureSheet class from the VCSRuby Module. All other classes are only helper classes to create a Capture Sheet easily for you.

The library uses MiniMagick to use ImageMagick and we use directly libav, ffmpeg or mplayer whatever you have on your System.

Capturer

To extract the images from the videos you can select your preferred capturer. Currently there are the following 3 options:

  • LibAV
  • FFMPEG
  • MPlayer

Information

# encoding: utf-8

require "vcs"

video = VCSRuby::Video.new "video.avi"

if video.valid?
  # Fields on .info: duration, bit_rate, size, format, extension, raw (hash, depends on capturer)
  puts "Video duration: #{video.info.duration}"

  # Supports multiple streams
  puts "Video codec: #{video.video_streams.first.codec}"

  # Fields on a video stream: width, height, codec, color_space, bit_rate, frame_rate, aspect_ratio, raw (hash, depends on capturer)
  puts "Video frame rate: #{video.video.frame_rate}"

  # Supports multiple streams:
  puts "Audio codec: #{video.audio_streams.first.codec}"

  # Fields on a audio stream: codec, channels, channel_layout, sample_rate, bit_rate, raw (hash, depends on capturer)
  puts "Audio sample rate: #{video.video.sample_rate}"

end

Using with Paperclip, Carrierwave, Refile

It is pretty simple to include the Contact Sheet into CarrierWave, however the processing will be done after the upload which might take quite some time. It is recommendet to use something like carrierwave_backgrounder to make the processing not during the upload.

Here is a working example in Carrierwave:

# encoding: utf-8

require "vcs"

class VideoUploader < CarrierWave::Uploader::Base
  include CarrierWave::MiniMagick

  storage :file

  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end

  version :contact_sheet do
    process :contact_sheet_processor
  end

  def contact_sheet_format end
    :png
  end

  def cs_url
    "#{File.dirname(url)}/#{File.basename(url,'.*')}.#{contact_sheet_format}"
  end

  def contact_sheet_processor
    # input
    directory = File.dirname(current_path)
    tmpfile = File.join(directory, 'tmpfile')
    File.rename(current_path, tmpfile)

    # output
    new_name = File.basename(current_path, '.*') + '.' + contact_sheet_format.to_s
    current_extenstion = File.extname(current_path).gsub('.', '')
    encoded_file = File.join(directory, new_name)

    # create cs
    cs = VCSRuby::ContactSheet.new tmpfile

    cs.initialize_filename(encoded_file)
    cs.format = contact_sheet_format
    cs.title = model.name
    cs.signature = nil
    cs.thumbnail_width = 320
    cs.timestamp = false
    cs.softshadow = false

    cs.build

    # without this lines processed video files will remain in cache folder
    self.filename[-current_extenstion.size..-1] = contact_sheet_format.to_s
    self.file.file[-current_extenstion.size..-1] = contact_sheet_format.to_s

    File.delete(tmpfile)
  end
end

show.html.erb

The cs_url alternative gives you the right path. This is not very nice though. A solution to just correct the url would be appreciated.

  <%=  image_tag @video.video.contact_sheet.cs_url %>

Script

Command Line Options

Video Contact Sheet Ruby 1.1.9

    -i, --interval [INTERVAL]        Set the interval [INTERVAL]
    -c, --columns [COLUMNS]          Arrange the output in <COLUMNS> columns.
    -r, --rows [ROWS]                Arrange the output in <ROWS> rows.
    -H, --height [HEIGHT]            Set the output (individual thumbnail) height.
    -W, --width [WIDTH]              Set the output (individual thumbnail) width.
    -A, --aspect [ASPECT]            Aspect ratio. Accepts a floating point number or a fraction. (i.e. 16/19)
        --from [FROM]                Set starting time. No caps before this.
    -t, --to [TO]                    Set ending time. No caps beyond this.
    -f, --format [FORMAT]            Formats: png, jpg, jpeg, tiff
    -C, --capture [CAPTURER]         Capturer: ffmpeg, libav, mplayer, any
    -T, --title [TITLE]              Set Title
    -o, --output [FILE]              File name of output. When ommited will be derived from the input filename. Can be repeated for multiple files.
    -s, --signature [SIGNATURE]      Change the image signature to your preference.
        --no-signature               Remove footer with signature
    -l, --highlight [HIGHLIGHT]      Add the frame found at timestamp [HIGHLIGHT] as a highlight.
        --[no-]timestamp             Add timestamp to thumbnails. Default: true
        --[no-]shadow                Add shadow to thumbnails. Default: true
        --[no-]polaroid              Add  polaroid frame to thumbnail. Default: false
    -p, --profile [PROFILE]          Loads additional setting from profile.yml.
    -q, --quiet                      Don't print progress messages just errors.
        --continue                   Prints Error message and continues with next file (if any left)
    -V, --verbose                    More verbose Output.
    -v, --version                    Current Version
    -h, --help                       Prints help

Examples:
  Create a contact sheet with default values (4 x 4 matrix):
  $ vcs video.avi

  Create a sheet with vidcaps at intervals of 3 and a half minutes, save to
  "output.jpg":
  $ vcs -i 3m30 input.wmv -o output.jpg

  Create a sheet with vidcaps starting at 3 mins and ending at 18 mins in 2m intervals
  $ vcs --from 3m --to 18m -i 2m input.avi

Profiles

Each Profile is a yml file which copies all or parts of the defaults.yml file to overwrite some part of the settings.

There are a few profiles delivered with the gem. [black, white, oldstyle]

twobytwo.yml

This Profile Makes a two by two contact sheet with a large 10px padding and red text on yellow background for the header part. Place this file directly into the dir and call it with --profile twobytwo

main:
  rows: 2
  columns: 2
  interval: ~
  padding: 10
style:
  header:
    color: Red
    background: "#ffcc00"

All Profile Settings

Options Default Description
main:rows: 4 Number of Rows
main:columns: 4 Number of Columns
main:interval: ~ Number of columns, default is ~ (nil)
main:padding: 2 Padding in pixels
main:quality 95 quality level [1-100] for jpeg images
filter:timestamp true Add a timestamp to the thumbnail
filter:polaroid true Add a polaroid frame to the thumbnail
filter:softshadow true Add a shadow to the thumbanil
style:header:font DejaVuSans.ttf font (name or file) for the header
style:header:size 14 Size of the font for the header
style:header:color Black Color of the text for the header
style:header:background #afcd7a Background color for the header
style:title:font DejaVuSans.ttf font (name or file) for the title
style:title:size 33 Size of the font for the title
style:title:color Black Color of the text for the title
style:title:background White Background color for the title
style:highlight:background SlateGray Background color for the highlight
style:contact:background SlateGray Background color for the contact sheet
style:timestamp:font DejaVuSans.ttf font (name or file) for the timestamp
style:timestamp:size 14 Size of the font for the timestamp
style:timestamp:color White Color of the text for the timestamp
style:timestamp:background #000000aa Background color for the timestamp
style:signature:font DejaVuSans.ttf font (name or file) for the signature
style:signature:size 10 Size of the font for the signature
style:signature:color Black Color of the text for the signature
style:signature:background SlateGray Background color for the signature
lowlevel:blank_evasion true try to avoid blank frames
lowlevel:blank_threshold 0.08 median image brightness
lowlevel:blank_alternatives [ -5, 5, -10, 10, -30, 30, 0] Array of seconds around interval