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.
@@ -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
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in giffy.gemspec
4
+ gemspec
@@ -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.
@@ -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
@@ -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
@@ -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
+
@@ -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
@@ -0,0 +1,6 @@
1
+ require 'tmpdir'
2
+ require 'giffy/version'
3
+ require 'giffy/pipeline'
4
+ require 'giffy/processors/video_extraction_processor'
5
+ require 'giffy/processors/image_sequence_processor'
6
+ require 'giffy/processors/gif_generation_processor'
@@ -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
@@ -0,0 +1,3 @@
1
+ module Giffy
2
+ VERSION = "0.0.1"
3
+ end
@@ -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
@@ -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