giffy 0.0.1
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/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +37 -0
- data/Rakefile +12 -0
- data/bin/giffy +48 -0
- data/giffy.gemspec +28 -0
- data/lib/giffy.rb +6 -0
- data/lib/giffy/pipeline.rb +15 -0
- data/lib/giffy/processors/gif_generation_processor.rb +55 -0
- data/lib/giffy/processors/image_sequence_processor.rb +20 -0
- data/lib/giffy/processors/video_extraction_processor.rb +54 -0
- data/lib/giffy/version.rb +3 -0
- data/test/fixtures/test_video.mov +0 -0
- data/test/fixtures/test_video_images/001.png +0 -0
- data/test/fixtures/test_video_images/002.png +0 -0
- data/test/fixtures/test_video_images/003.png +0 -0
- data/test/fixtures/test_video_images/004.png +0 -0
- data/test/fixtures/test_video_images/005.png +0 -0
- data/test/fixtures/test_video_images/006.png +0 -0
- data/test/fixtures/test_video_images/007.png +0 -0
- data/test/fixtures/test_video_images/008.png +0 -0
- data/test/fixtures/test_video_images/009.png +0 -0
- data/test/giffy/pipeline_test.rb +32 -0
- data/test/giffy/processors/gif_generation_processor_test.rb +42 -0
- data/test/giffy/processors/image_sequence_processor_test.rb +29 -0
- data/test/giffy/processors/video_extraction_processor_test.rb +54 -0
- data/test/test_helper.rb +36 -0
- metadata +173 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d116a571dafe011946543c344742a7aa766d0350
|
4
|
+
data.tar.gz: f4943485eebb74d6b122b7f10052682d3cf761d5
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b8ca4cf95c4c9c94b65b35fafa7a1bf68ac95cc225a6d3c55a702132a21b688e6ec771ea035dcb9272a052e72d909c82ff8574222ebb31938b110da2be7a563f
|
7
|
+
data.tar.gz: 4e8a7d05c42e6cac06a9227e4fca58c0bd66473b42d5eb31baea4e74d6b5b8aede63e8c7c15e4f2bc0cad8fecdf5bd463f4ad9750506ac0a178ade035f31e143
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Shopify
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# Giffy
|
2
|
+
|
3
|
+
Giffy is a very simple tool to use. The goal was to make it simple to take a screencast/demo
|
4
|
+
and convert it into a gif without needing to remember all the incantations required for ffmpeg
|
5
|
+
and ImageMagick
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
If you want to use the command line tool simply:
|
10
|
+
|
11
|
+
$ gem install giffy
|
12
|
+
|
13
|
+
If you want to use custom extensions or use giffy in
|
14
|
+
a project add the following to your applications Gemfile:
|
15
|
+
|
16
|
+
gem 'giffy'
|
17
|
+
|
18
|
+
And then execute:
|
19
|
+
|
20
|
+
$ bundle
|
21
|
+
|
22
|
+
## Usage
|
23
|
+
|
24
|
+
From your terminal simply type the following:
|
25
|
+
|
26
|
+
$ giffy path_to_your_video path_to_where_gif_should_go
|
27
|
+
|
28
|
+
## Contributing
|
29
|
+
|
30
|
+
Don't forget to include tests. Contributions without tests may not be
|
31
|
+
accepted as quickly.
|
32
|
+
|
33
|
+
1. Fork it
|
34
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
35
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
36
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
37
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require 'rake/testtask'
|
3
|
+
|
4
|
+
task default: [:test]
|
5
|
+
|
6
|
+
Rake::TestTask.new 'test' do |t|
|
7
|
+
ENV['test'] = '1'
|
8
|
+
t.libs = ['lib', 'test']
|
9
|
+
t.ruby_opts << '-rubygems'
|
10
|
+
t.verbose = true
|
11
|
+
t.test_files = FileList['test/**/*_test.rb']
|
12
|
+
end
|
data/bin/giffy
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# This allows shopify_them to run easily from a git checkout without install.
|
4
|
+
# Hat tip to chriseppstein of Compass fame for the code for this
|
5
|
+
def fallback_load_path(path)
|
6
|
+
retried = false
|
7
|
+
begin
|
8
|
+
yield
|
9
|
+
rescue LoadError
|
10
|
+
unless retried
|
11
|
+
$: << path
|
12
|
+
retried = true
|
13
|
+
retry
|
14
|
+
end
|
15
|
+
raise
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
fallback_load_path(File.join(File.dirname(__FILE__), '..', 'lib')) do
|
20
|
+
require 'thor'
|
21
|
+
require 'pry'
|
22
|
+
require 'pry-debugger'
|
23
|
+
require 'giffy'
|
24
|
+
end
|
25
|
+
|
26
|
+
module Giffy
|
27
|
+
class CLI < Thor
|
28
|
+
PROCESSORS = [
|
29
|
+
Processors::VideoExtractionProcessor,
|
30
|
+
Processors::ImageSequenceProcessor,
|
31
|
+
Processors::GifGenerationProcessor
|
32
|
+
]
|
33
|
+
|
34
|
+
COMMANDS = %w(process)
|
35
|
+
|
36
|
+
desc 'process VIDEO_FILE OUTPUT_GIF', 'Convert provided video into a gif'
|
37
|
+
method_options size: :string, start: :string, length: :string
|
38
|
+
def process(video_file, output_gif)
|
39
|
+
pipeline = Pipeline.new(PROCESSORS)
|
40
|
+
result = pipeline.process(video_file, options.merge(filename: output_gif))
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
ARGV.unshift('process') unless Giffy::CLI::COMMANDS.include?(ARGV.first)
|
46
|
+
|
47
|
+
Giffy::CLI.start
|
48
|
+
|
data/giffy.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'giffy/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "giffy"
|
8
|
+
spec.version = Giffy::VERSION
|
9
|
+
spec.authors = ["Shopify", "Chris Saunders"]
|
10
|
+
spec.email = ["chris.saunders@shopify.com"]
|
11
|
+
spec.description = "A tool that makes it easy to convert videos into gifs"
|
12
|
+
spec.summary = "Using existing tools such as ffmpeg and ImageMagick easily create gifs"
|
13
|
+
spec.homepage = "https://github.com/Shopify/giffy"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "thor"
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
24
|
+
spec.add_development_dependency "rake"
|
25
|
+
spec.add_development_dependency "minitest", ">= 5.0.0"
|
26
|
+
spec.add_development_dependency "pry"
|
27
|
+
spec.add_development_dependency "pry-debugger"
|
28
|
+
end
|
data/lib/giffy.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
module Giffy
|
2
|
+
class Pipeline
|
3
|
+
attr_reader :processors
|
4
|
+
def initialize(processors)
|
5
|
+
@processors = processors
|
6
|
+
end
|
7
|
+
|
8
|
+
def process(input, options)
|
9
|
+
processors.reduce(input) do |input, processor|
|
10
|
+
instance = processor.new(options)
|
11
|
+
instance.process(input)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Giffy
|
2
|
+
module Processors
|
3
|
+
class GifGenerationProcessor
|
4
|
+
COMMANDS = {
|
5
|
+
"delay" => '-delay',
|
6
|
+
"other" => '-coalesce -layers OptimizeTransparency'
|
7
|
+
}
|
8
|
+
OPTIMIZE = '-fuzz 1%'
|
9
|
+
DEFAULTS = {
|
10
|
+
"filename" => 'animation.gif',
|
11
|
+
"delay" => '1x10'
|
12
|
+
}
|
13
|
+
|
14
|
+
def initialize(options={})
|
15
|
+
@optimize = options.delete("optimize")
|
16
|
+
@opts = DEFAULTS.merge(options)
|
17
|
+
end
|
18
|
+
|
19
|
+
def command(filenames)
|
20
|
+
result = %w(convert)
|
21
|
+
result << OPTIMIZE if optimize?
|
22
|
+
result << build_options(opts.merge("sequence" => filenames))
|
23
|
+
result << opts["filename"]
|
24
|
+
result.flatten.join(' ')
|
25
|
+
end
|
26
|
+
|
27
|
+
def process(filenames)
|
28
|
+
Open3.popen3(command(filenames)) do |stdin, stdout, stderr, wait_thread|
|
29
|
+
while line = stderr.gets
|
30
|
+
puts line
|
31
|
+
end
|
32
|
+
end
|
33
|
+
"Created #{opts["filename"]}"
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
attr_reader :opts
|
38
|
+
def build_options(options)
|
39
|
+
COMMANDS.sort.map do |key, command|
|
40
|
+
value = options[key]
|
41
|
+
value = send(key, value, options) if respond_to?(key, true)
|
42
|
+
value ? [command, value] : [command]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def optimize?
|
47
|
+
@optimize
|
48
|
+
end
|
49
|
+
|
50
|
+
def delay(amount, options)
|
51
|
+
"#{amount} #{options["sequence"]}"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Giffy
|
2
|
+
module Processors
|
3
|
+
class ImageSequenceProcessor
|
4
|
+
DEFAULT_INCREMENT = 5
|
5
|
+
attr_reader :increment
|
6
|
+
def initialize(options={})
|
7
|
+
@increment = options["increment"] || DEFAULT_INCREMENT
|
8
|
+
end
|
9
|
+
|
10
|
+
def process(dir)
|
11
|
+
accumulator = []
|
12
|
+
entries = Dir.entries(dir).reject { |entry| (entry =~ /\.png\z/) == nil }
|
13
|
+
entries.each_with_index do |entry, index|
|
14
|
+
accumulator << "#{dir}/#{entry}" if index % increment == 0
|
15
|
+
end
|
16
|
+
accumulator.join(' ')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'open3'
|
2
|
+
|
3
|
+
module Giffy
|
4
|
+
module Processors
|
5
|
+
class VideoExtractionProcessor
|
6
|
+
COMMANDS = {
|
7
|
+
"format" => '-f',
|
8
|
+
"input" => '-i',
|
9
|
+
"length" => '-t',
|
10
|
+
"size" => '-s',
|
11
|
+
"start" => '-ss'
|
12
|
+
}
|
13
|
+
|
14
|
+
DEFAULTS = {
|
15
|
+
"size" => '1024x768'
|
16
|
+
}
|
17
|
+
|
18
|
+
attr_reader :dir
|
19
|
+
def initialize(options={})
|
20
|
+
@dir = options.fetch("dir") { |key| Dir.mktmpdir }
|
21
|
+
@opts = DEFAULTS.merge(options)
|
22
|
+
end
|
23
|
+
|
24
|
+
def command(input)
|
25
|
+
result = %w(ffmpeg) + build_options(opts.merge("input" => input))
|
26
|
+
result.flatten.join(' ')
|
27
|
+
end
|
28
|
+
|
29
|
+
def process(input)
|
30
|
+
Open3.popen3(command(input)) do |stdin, stdout, stderr, wait_thread|
|
31
|
+
while line = stderr.gets
|
32
|
+
puts line
|
33
|
+
end
|
34
|
+
end
|
35
|
+
dir
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
attr_reader :opts
|
40
|
+
def build_options(options)
|
41
|
+
COMMANDS.sort.map do |key, command|
|
42
|
+
value = options[key]
|
43
|
+
value = send(key, value) if respond_to?(key, true)
|
44
|
+
value ? [command, value] : []
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def format(value=nil)
|
49
|
+
"image2 #{dir}/%03d.png"
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'giffy/pipeline'
|
3
|
+
|
4
|
+
module Giffy
|
5
|
+
class PipelineTest < Minitest::Test
|
6
|
+
class Processor
|
7
|
+
def initialize(*args)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class Yeller < Processor
|
12
|
+
def process(input)
|
13
|
+
input.upcase
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class Reverser < Processor
|
18
|
+
def process(input)
|
19
|
+
input.reverse
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
attr_reader :pipeline
|
24
|
+
def setup
|
25
|
+
@pipeline = Pipeline.new([Yeller, Reverser])
|
26
|
+
end
|
27
|
+
|
28
|
+
test "running something through the pipeline" do
|
29
|
+
assert_equal "DLROW OLLEH", pipeline.process("hello world", {})
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'giffy/processors/gif_generation_processor'
|
3
|
+
|
4
|
+
module Giffy
|
5
|
+
module Processors
|
6
|
+
class GifGenerationProcessorTest < Minitest::Test
|
7
|
+
include Giffy::Fixtures
|
8
|
+
attr_reader :sequence, :dir
|
9
|
+
|
10
|
+
def setup
|
11
|
+
@sequence = images_sequence
|
12
|
+
@dir = Dir.mktmpdir
|
13
|
+
@stdout = $stdout
|
14
|
+
end
|
15
|
+
|
16
|
+
def teardown
|
17
|
+
FileUtils.remove_entry_secure(dir)
|
18
|
+
$stdout = @stdout
|
19
|
+
end
|
20
|
+
|
21
|
+
test "it should be able to generate the correct command" do
|
22
|
+
processor = GifGenerationProcessor.new("filename" => 'result.gif')
|
23
|
+
expected_command = "convert -delay 1x10 #{sequence} -coalesce -layers OptimizeTransparency result.gif"
|
24
|
+
assert_equal expected_command, processor.command(sequence)
|
25
|
+
end
|
26
|
+
|
27
|
+
test "when the optimized option is passed in for the command generation" do
|
28
|
+
processor = GifGenerationProcessor.new("optimize" => true, "delay" => '1x8')
|
29
|
+
expected_command = "convert -fuzz 1% -delay 1x8 #{sequence} -coalesce -layers OptimizeTransparency animation.gif"
|
30
|
+
assert_equal expected_command, processor.command(sequence)
|
31
|
+
end
|
32
|
+
|
33
|
+
test "it should be able to create a gif" do
|
34
|
+
slow_test('convert', __method__)
|
35
|
+
filename = "#{dir}/example.gif"
|
36
|
+
processor = GifGenerationProcessor.new("filename" => filename)
|
37
|
+
processor.process(sequence)
|
38
|
+
assert File.exist?(filename), "#{filename} does not exist after the image processing"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'giffy/processors/image_sequence_processor'
|
3
|
+
|
4
|
+
module Giffy
|
5
|
+
module Processors
|
6
|
+
class ImageSequenceProcessorTest < Minitest::Test
|
7
|
+
include Giffy::Fixtures
|
8
|
+
|
9
|
+
attr_reader :dir
|
10
|
+
def setup
|
11
|
+
@dir = images_directory_path
|
12
|
+
end
|
13
|
+
|
14
|
+
test "it collects the sequence based on the provided increment" do
|
15
|
+
processor = ImageSequenceProcessor.new("increment" => 3)
|
16
|
+
results = processor.process(dir)
|
17
|
+
expected = %w(001.png 004.png 007.png).map { |e| "#{dir}/#{e}" }
|
18
|
+
assert_equal expected.join(' '), results
|
19
|
+
end
|
20
|
+
|
21
|
+
test "it collects the sequence based on the default increment" do
|
22
|
+
processor = ImageSequenceProcessor.new
|
23
|
+
results = processor.process(dir)
|
24
|
+
expected = %w(001.png 006.png).map { |e| "#{dir}/#{e}" }
|
25
|
+
assert_equal expected.join(' '), results
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'giffy'
|
3
|
+
require 'giffy/processors/video_extraction_processor'
|
4
|
+
|
5
|
+
module Giffy
|
6
|
+
module Processors
|
7
|
+
class VideoExtractionProcessorTest < Minitest::Test
|
8
|
+
include Giffy::Fixtures
|
9
|
+
|
10
|
+
attr_reader :dir, :processor
|
11
|
+
attr_accessor :args
|
12
|
+
def setup
|
13
|
+
@dir = Dir.mktmpdir
|
14
|
+
@args = {"size" => '320x240', "dir" => dir}
|
15
|
+
@processor = VideoExtractionProcessor.new(args)
|
16
|
+
@stdout = $stdout
|
17
|
+
end
|
18
|
+
|
19
|
+
def teardown
|
20
|
+
FileUtils.remove_entry_secure(dir)
|
21
|
+
$stdout = @stdout
|
22
|
+
end
|
23
|
+
|
24
|
+
test "it takes in a provided video path and generates the correct ffmpeg command" do
|
25
|
+
expected_command = "ffmpeg -f image2 #{dir}/%03d.png -i #{video_path} -s #{args["size"]}"
|
26
|
+
assert_equal expected_command, processor.command(video_path)
|
27
|
+
end
|
28
|
+
|
29
|
+
test "it can have additional options passed in for start location and video length to generate the ffmpeg command" do
|
30
|
+
self.args = args.merge("start" => '0:0:0.4', "length" => '0:0:0.5')
|
31
|
+
processor = VideoExtractionProcessor.new(args)
|
32
|
+
expected_command = "ffmpeg -f image2 #{dir}/%03d.png -i #{video_path} -t #{args["length"]} -s #{args["size"]} -ss #{args["start"]}"
|
33
|
+
assert_equal expected_command, processor.command(video_path)
|
34
|
+
end
|
35
|
+
|
36
|
+
test "it can be queried for the directory it will be writing processed files to" do
|
37
|
+
assert_equal dir, processor.dir
|
38
|
+
end
|
39
|
+
|
40
|
+
test "running the processor generates png files in the directory" do
|
41
|
+
slow_test('ffmpeg', __method__)
|
42
|
+
stdout = StringIO.new
|
43
|
+
$stdout = stdout
|
44
|
+
dir = processor.process(video_path)
|
45
|
+
files = Dir.entries(dir).reject {|file| file =~ /\A\./}
|
46
|
+
assert stdout.length > 0, "The mocked stdout should've been written to"
|
47
|
+
assert_equal 31, files.length
|
48
|
+
files.each do |file|
|
49
|
+
assert file =~ /\.png\z/, "#{file} is not a PNG"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'pry'
|
3
|
+
require 'pry-debugger'
|
4
|
+
|
5
|
+
class Minitest::Test
|
6
|
+
def self.test(name, &blk)
|
7
|
+
define_method("test_#{name.gsub(/\s+/, '_')}", blk)
|
8
|
+
end
|
9
|
+
|
10
|
+
def slow_test(program_name, test_name)
|
11
|
+
unless ENV['FULL_SUITE']
|
12
|
+
puts "Processing via #{program_name} is slow, set FULL_SUITE to include #{test_name} in the test run" unless ENV['NO_WARN']
|
13
|
+
skip ''
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
module Giffy
|
19
|
+
module Fixtures
|
20
|
+
def fixture_path(name)
|
21
|
+
File.expand_path(File.join(File.dirname(__FILE__), "fixtures/#{name}"))
|
22
|
+
end
|
23
|
+
|
24
|
+
def video_path
|
25
|
+
fixture_path('test_video.mov')
|
26
|
+
end
|
27
|
+
|
28
|
+
def images_directory_path
|
29
|
+
fixture_path('test_video_images/')
|
30
|
+
end
|
31
|
+
|
32
|
+
def images_sequence
|
33
|
+
Dir.entries(images_directory_path).reject{|e| (e =~ /\.png\z/) == nil}.map{|e| "#{images_directory_path}/#{e}"}.join(' ')
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
metadata
ADDED
@@ -0,0 +1,173 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: giffy
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Shopify
|
8
|
+
- Chris Saunders
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-12-16 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: thor
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - '>='
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '0'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - '>='
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '0'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: bundler
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ~>
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '1.3'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ~>
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '1.3'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: rake
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - '>='
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - '>='
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: minitest
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - '>='
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 5.0.0
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 5.0.0
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: pry
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - '>='
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: pry-debugger
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - '>='
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
type: :development
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - '>='
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
description: A tool that makes it easy to convert videos into gifs
|
99
|
+
email:
|
100
|
+
- chris.saunders@shopify.com
|
101
|
+
executables:
|
102
|
+
- giffy
|
103
|
+
extensions: []
|
104
|
+
extra_rdoc_files: []
|
105
|
+
files:
|
106
|
+
- .gitignore
|
107
|
+
- Gemfile
|
108
|
+
- LICENSE.txt
|
109
|
+
- README.md
|
110
|
+
- Rakefile
|
111
|
+
- bin/giffy
|
112
|
+
- giffy.gemspec
|
113
|
+
- lib/giffy.rb
|
114
|
+
- lib/giffy/pipeline.rb
|
115
|
+
- lib/giffy/processors/gif_generation_processor.rb
|
116
|
+
- lib/giffy/processors/image_sequence_processor.rb
|
117
|
+
- lib/giffy/processors/video_extraction_processor.rb
|
118
|
+
- lib/giffy/version.rb
|
119
|
+
- test/fixtures/test_video.mov
|
120
|
+
- test/fixtures/test_video_images/001.png
|
121
|
+
- test/fixtures/test_video_images/002.png
|
122
|
+
- test/fixtures/test_video_images/003.png
|
123
|
+
- test/fixtures/test_video_images/004.png
|
124
|
+
- test/fixtures/test_video_images/005.png
|
125
|
+
- test/fixtures/test_video_images/006.png
|
126
|
+
- test/fixtures/test_video_images/007.png
|
127
|
+
- test/fixtures/test_video_images/008.png
|
128
|
+
- test/fixtures/test_video_images/009.png
|
129
|
+
- test/giffy/pipeline_test.rb
|
130
|
+
- test/giffy/processors/gif_generation_processor_test.rb
|
131
|
+
- test/giffy/processors/image_sequence_processor_test.rb
|
132
|
+
- test/giffy/processors/video_extraction_processor_test.rb
|
133
|
+
- test/test_helper.rb
|
134
|
+
homepage: https://github.com/Shopify/giffy
|
135
|
+
licenses:
|
136
|
+
- MIT
|
137
|
+
metadata: {}
|
138
|
+
post_install_message:
|
139
|
+
rdoc_options: []
|
140
|
+
require_paths:
|
141
|
+
- lib
|
142
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
143
|
+
requirements:
|
144
|
+
- - '>='
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '0'
|
147
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
148
|
+
requirements:
|
149
|
+
- - '>='
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: '0'
|
152
|
+
requirements: []
|
153
|
+
rubyforge_project:
|
154
|
+
rubygems_version: 2.0.3
|
155
|
+
signing_key:
|
156
|
+
specification_version: 4
|
157
|
+
summary: Using existing tools such as ffmpeg and ImageMagick easily create gifs
|
158
|
+
test_files:
|
159
|
+
- test/fixtures/test_video.mov
|
160
|
+
- test/fixtures/test_video_images/001.png
|
161
|
+
- test/fixtures/test_video_images/002.png
|
162
|
+
- test/fixtures/test_video_images/003.png
|
163
|
+
- test/fixtures/test_video_images/004.png
|
164
|
+
- test/fixtures/test_video_images/005.png
|
165
|
+
- test/fixtures/test_video_images/006.png
|
166
|
+
- test/fixtures/test_video_images/007.png
|
167
|
+
- test/fixtures/test_video_images/008.png
|
168
|
+
- test/fixtures/test_video_images/009.png
|
169
|
+
- test/giffy/pipeline_test.rb
|
170
|
+
- test/giffy/processors/gif_generation_processor_test.rb
|
171
|
+
- test/giffy/processors/image_sequence_processor_test.rb
|
172
|
+
- test/giffy/processors/video_extraction_processor_test.rb
|
173
|
+
- test/test_helper.rb
|