MIAConverter 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 71ab68fda7214edabf7743fe63b25c4cdb14299e
4
+ data.tar.gz: f573041fab7f2a9eba31d10b04a2948d39d690ee
5
+ SHA512:
6
+ metadata.gz: fda40d8ea927a402af01bd95371eb56387b0c6572d4f478023a75bfb85be75f6cf5056c401cd60b53b95f73c6eb59a1469d39e26366ed4c30819aec8003c1c0c
7
+ data.tar.gz: 8c66d551a93b5e07c289f4fe002b1797355b62074333d512df5c1b07fdd02f2a98f55e374f2d3ad1ad62319d6e3f523cab2777b8fb740208a7bd4f2a90c20dd3
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+
3
+ rvm:
4
+ - '2.0.0'
5
+
6
+ before_script:
7
+ - sudo apt-get install -y ffmpeg
data/Gemfile ADDED
@@ -0,0 +1,19 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ ruby '2.0.0'
7
+ gem 'streamio-ffmpeg', '~> 1.0.0'
8
+ gem 'rmagick', '~> 2.13.2'
9
+
10
+ gem 'rake'
11
+
12
+ # Add dependencies to develop your gem here.
13
+ # Include everything needed to run rake, tests, features, etc.
14
+ group :development do
15
+ gem "rspec", "~> 2.14.0"
16
+ gem "rdoc", "~> 3.12"
17
+ gem "bundler", "~> 1.0"
18
+ gem "jeweler", "~> 1.8.7"
19
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,68 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ addressable (2.3.5)
5
+ builder (3.2.2)
6
+ diff-lcs (1.2.5)
7
+ faraday (0.8.8)
8
+ multipart-post (~> 1.2.0)
9
+ git (1.2.6)
10
+ github_api (0.10.1)
11
+ addressable
12
+ faraday (~> 0.8.1)
13
+ hashie (>= 1.2)
14
+ multi_json (~> 1.4)
15
+ nokogiri (~> 1.5.2)
16
+ oauth2
17
+ hashie (2.0.5)
18
+ highline (1.6.20)
19
+ httpauth (0.2.0)
20
+ jeweler (1.8.8)
21
+ builder
22
+ bundler (~> 1.0)
23
+ git (>= 1.2.5)
24
+ github_api (= 0.10.1)
25
+ highline (>= 1.6.15)
26
+ nokogiri (= 1.5.10)
27
+ rake
28
+ rdoc
29
+ json (1.8.1)
30
+ jwt (0.1.8)
31
+ multi_json (>= 1.5)
32
+ multi_json (1.8.2)
33
+ multi_xml (0.5.5)
34
+ multipart-post (1.2.0)
35
+ nokogiri (1.5.10)
36
+ oauth2 (0.9.2)
37
+ faraday (~> 0.8)
38
+ httpauth (~> 0.2)
39
+ jwt (~> 0.1.4)
40
+ multi_json (~> 1.0)
41
+ multi_xml (~> 0.5)
42
+ rack (~> 1.2)
43
+ rack (1.5.2)
44
+ rake (10.1.0)
45
+ rdoc (3.12.2)
46
+ json (~> 1.4)
47
+ rmagick (2.13.2)
48
+ rspec (2.14.1)
49
+ rspec-core (~> 2.14.0)
50
+ rspec-expectations (~> 2.14.0)
51
+ rspec-mocks (~> 2.14.0)
52
+ rspec-core (2.14.7)
53
+ rspec-expectations (2.14.4)
54
+ diff-lcs (>= 1.1.3, < 2.0)
55
+ rspec-mocks (2.14.4)
56
+ streamio-ffmpeg (1.0.0)
57
+
58
+ PLATFORMS
59
+ ruby
60
+
61
+ DEPENDENCIES
62
+ bundler (~> 1.0)
63
+ jeweler (~> 1.8.7)
64
+ rake
65
+ rdoc (~> 3.12)
66
+ rmagick (~> 2.13.2)
67
+ rspec (~> 2.14.0)
68
+ streamio-ffmpeg (~> 1.0.0)
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2013 Martin Nash
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,19 @@
1
+ = MIAConverter
2
+
3
+ ![Travis Status](https://api.travis-ci.org/MartinJNash/MIAConverter.png)
4
+
5
+ == Contributing to MIAConverter
6
+
7
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
8
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
9
+ * Fork the project.
10
+ * Start a feature/bugfix branch.
11
+ * Commit and push until you are happy with your contribution.
12
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
13
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2013 Martin Nash. See LICENSE.txt for
18
+ further details.
19
+
data/Rakefile ADDED
@@ -0,0 +1,71 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "MIAConverter"
18
+ gem.homepage = "http://github.com/MartinJNash/MIAConverter"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{Turns a video file into an animated gif.}
21
+ gem.description = %Q{Turns a video file into an animated gif.}
22
+ gem.email = "martin.j.nash@gmail.com"
23
+ gem.authors = ["Martin Nash"]
24
+ # dependencies defined in Gemfile
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
27
+
28
+
29
+
30
+
31
+
32
+
33
+ ####################
34
+ ##
35
+ ## TESTING
36
+ ##
37
+ ####################
38
+
39
+ require 'rake/testtask'
40
+ Rake::TestTask.new(:test) do |test|
41
+ test.libs << 'lib' << 'test'
42
+ test.pattern = 'test/**/test_*.rb'
43
+ test.verbose = true
44
+ end
45
+
46
+ require 'rspec/core'
47
+ require 'rspec/core/rake_task'
48
+ RSpec::Core::RakeTask.new(:spec) do |spec|
49
+ spec.pattern = FileList['spec/**/*_spec.rb']
50
+ end
51
+
52
+ task :default => :spec
53
+
54
+
55
+
56
+
57
+ ####################
58
+ ##
59
+ ## DOCUMENTATION
60
+ ##
61
+ ####################
62
+
63
+ require 'rdoc/task'
64
+ Rake::RDocTask.new do |rdoc|
65
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
66
+
67
+ rdoc.rdoc_dir = 'rdoc'
68
+ rdoc.title = "MIAConverter #{version}"
69
+ rdoc.rdoc_files.include('README*')
70
+ rdoc.rdoc_files.include('lib/**/*.rb')
71
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.0
@@ -0,0 +1,20 @@
1
+ require 'MIAConverter'
2
+ require 'FileUtils'
3
+
4
+
5
+
6
+ conv = MIAConverter::Converter.new('./typing.mp4')
7
+ conv.start_seconds = 0.0
8
+ # conv.length_seconds = 5
9
+ conv.shot_gap = 0.5
10
+ conv.transition_time = 40
11
+
12
+ final_path = conv.process
13
+
14
+ # TODO:
15
+ # Process should take a block and report finished
16
+ # if start seconds is more than video length, throw exception
17
+
18
+ # MOVE THOSE FILES SOMEWHERE
19
+ FileUtils.mv(final_path, "./#{Time.now.to_i}-tt#{conv.transition_time}-gap#{conv.shot_gap}animated.gif")
20
+ # FileUtils.mv(conv.chopped_video_path, "./#{Time.now.to_i}chopped.mp4")
Binary file
@@ -0,0 +1,151 @@
1
+ require 'RMagick'
2
+ require 'streamio-ffmpeg'
3
+
4
+ module MIAConverter
5
+
6
+ # LOG TO FILE, NOT CONSOLE
7
+ # Dir.mkdir("/tmp/MIAConverter/logs") unless Dir.exists?("/tmp/MIAConverter/logs")
8
+ # FFMPEG.logger = Logger.new('/tmp/MIAConverter/logs/ffmpeglog.txt');
9
+
10
+
11
+ class Converter
12
+
13
+ # INPUT FILE
14
+ attr_accessor :original_file
15
+
16
+ # VIDEO OPTiONS
17
+ attr_accessor :start_seconds
18
+ attr_accessor :length_seconds
19
+ attr_accessor :shot_gap # seconds apart to take shots
20
+
21
+ # IMAGE OPTIONS
22
+ attr_accessor :transition_time
23
+
24
+
25
+ def initialize(original_file, options={})
26
+
27
+ @original_dir = Dir.pwd
28
+
29
+ @original_file = File.expand_path original_file
30
+ @init_time = Time.now
31
+
32
+ # DEFAULTS
33
+ @shot_gap = 0.5
34
+ @start_seconds = 0
35
+ @transition_time = 20
36
+ @length_seconds = 20
37
+
38
+ # Set instance variables from options dictionary
39
+ options.each {|key,value| self.instance_variable_set("@#{key}", value) }
40
+ end
41
+
42
+
43
+ def original_file_valid?
44
+ File.exists? @original_file
45
+ end
46
+
47
+
48
+ def process
49
+ extract_relevant_parts_of_video
50
+ create_still_images
51
+ create_animated_image
52
+ end
53
+
54
+
55
+
56
+
57
+
58
+
59
+
60
+
61
+ #
62
+ # FOLDERS
63
+ #
64
+ def base_folder
65
+ temp_folder_path = "/tmp/MIAConverter"
66
+ Dir.mkdir(temp_folder_path) unless Dir.exists?(temp_folder_path)
67
+ temp_folder_path
68
+ end
69
+
70
+ def get_temp_folder
71
+ current_tmp_path = "#{base_folder}/#{time_second_string}"
72
+ Dir.mkdir(current_tmp_path) unless Dir.exists?(current_tmp_path)
73
+ current_tmp_path
74
+ end
75
+
76
+ def get_images_folder
77
+ images_folder_path = "#{get_temp_folder}/images"
78
+ Dir.mkdir(images_folder_path) unless Dir.exists?(images_folder_path)
79
+ images_folder_path
80
+ end
81
+
82
+ def time_second_string
83
+ @init_time.to_f.to_s.sub('.', '-')
84
+ end
85
+
86
+ def animated_gif_file_name
87
+ "animated.gif"
88
+ end
89
+
90
+ def chopped_video_path
91
+ chopped_path = "#{get_temp_folder}/chopped.mp4"
92
+ end
93
+
94
+ def animated_gif_path
95
+ "#{get_temp_folder}/#{animated_gif_file_name}"
96
+ end
97
+
98
+ def screenshots_folder_path
99
+ get_images_folder
100
+ end
101
+
102
+ def still_image_paths
103
+ Dir["#{get_images_folder}/*.jpg"]
104
+ end
105
+
106
+
107
+
108
+
109
+
110
+
111
+ #
112
+ # Make video shorter, so we have only relevant parts
113
+ #
114
+ def extract_relevant_parts_of_video
115
+ orig_movie = FFMPEG::Movie.new(@original_file)
116
+ throw "Start Seconds beyond end of video" if @start_seconds > orig_movie.duration
117
+ @chopped_movie = orig_movie.transcode(chopped_video_path, duration: @length_seconds + 1, seek_time: @start_seconds)
118
+
119
+ chopped_video_path
120
+ end
121
+
122
+
123
+ def create_still_images
124
+ img_folder = get_images_folder # call once
125
+
126
+ # BUILD UP THE LIST OF SEEK_TIMES
127
+ seek_times = (0.0...@length_seconds).step(@shot_gap).to_a.select do |time|
128
+ time <= @chopped_movie.duration || time <= @length_seconds
129
+ end
130
+
131
+ # SCREEN GRABS
132
+ seek_times.each.with_index do |time, idx|
133
+ padded_string = "%010i" % idx
134
+ file_name = "#{img_folder}/shot-#{padded_string}.jpg"
135
+ @chopped_movie.screenshot(file_name, seek_time: time)
136
+ end
137
+
138
+ still_image_paths
139
+ end
140
+
141
+
142
+ def create_animated_image
143
+ animation = Magick::ImageList.new(*still_image_paths)
144
+ animation.delay = @transition_time
145
+ animation.write(animated_gif_path)
146
+
147
+ animated_gif_path
148
+ end
149
+
150
+ end
151
+ end
@@ -0,0 +1,84 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+
4
+
5
+ sp_path = File.expand_path(File.dirname(__FILE__) + '/../example/typing.mp4')
6
+
7
+ # TO TEST RELATIVE PATH
8
+ # Dir.chdir File.dirname(__FILE__)
9
+ # sp_path = "sp17-08.mp4"
10
+
11
+
12
+
13
+ describe MIAConverter do
14
+
15
+ before(:all) do
16
+ @converter = MIAConverter::Converter.new(
17
+ sp_path,
18
+ start_seconds: 5,
19
+ length_seconds: 10,
20
+ transition_time: 15
21
+ )
22
+ end
23
+
24
+
25
+
26
+ context "new object setup" do
27
+
28
+ it "should make a new converter object" do
29
+ MIAConverter::Converter.new('').should_not be_nil
30
+ end
31
+
32
+ it "should take #segment_length option at creation time" do
33
+ @converter.length_seconds.should == 10
34
+ end
35
+
36
+ it "should take #transition_time option at creation time" do
37
+ @converter.transition_time.should == 15
38
+ end
39
+
40
+ it "should take #start_time option at creation time" do
41
+ @converter.start_seconds.should == 5
42
+ end
43
+
44
+ end
45
+
46
+
47
+
48
+
49
+ context "file creation" do
50
+
51
+ before :all do
52
+
53
+ @converter.length_seconds = 5
54
+ @converter.start_seconds = 5
55
+ @converter.transition_time = 25
56
+ @converter.shot_gap = 0.5
57
+
58
+ @short_path = @converter.extract_relevant_parts_of_video
59
+ @images = @converter.create_still_images
60
+ @animated_image_path = @converter.create_animated_image
61
+
62
+ end
63
+
64
+
65
+ it "should create a temporary fodler to use every time" do
66
+ Dir.exists?(@converter.get_temp_folder).should == true
67
+ end
68
+
69
+ it "should create shorter video to work on" do
70
+ File.exists?(@short_path).should == true
71
+ end
72
+
73
+ it "should create still images" do
74
+ @images.count.should > 0
75
+ end
76
+
77
+ it "should create an animated gif" do
78
+ File.exists?(@animated_image_path).should == true
79
+ end
80
+
81
+ end
82
+
83
+
84
+ end
@@ -0,0 +1,12 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+ require 'rspec'
4
+ require 'MIAConverter'
5
+
6
+ # Requires supporting files with custom matchers and macros, etc,
7
+ # in ./support/ and its subdirectories.
8
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
9
+
10
+ RSpec.configure do |config|
11
+
12
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,18 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'test/unit'
11
+ require 'shoulda'
12
+
13
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
14
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
15
+ require 'MIAConverter'
16
+
17
+ class Test::Unit::TestCase
18
+ end
@@ -0,0 +1,7 @@
1
+ require 'helper'
2
+
3
+ class TestMiaconverter < Test::Unit::TestCase
4
+ should "probably rename this file and start testing for real" do
5
+ flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,159 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: MIAConverter
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Martin Nash
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-12-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: streamio-ffmpeg
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: 1.0.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: 1.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: rmagick
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: 2.13.2
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: 2.13.2
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 2.14.0
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: 2.14.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: rdoc
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: '3.12'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: '3.12'
83
+ - !ruby/object:Gem::Dependency
84
+ name: bundler
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: '1.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ~>
95
+ - !ruby/object:Gem::Version
96
+ version: '1.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: jeweler
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ~>
102
+ - !ruby/object:Gem::Version
103
+ version: 1.8.7
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ~>
109
+ - !ruby/object:Gem::Version
110
+ version: 1.8.7
111
+ description: Turns a video file into an animated gif.
112
+ email: martin.j.nash@gmail.com
113
+ executables: []
114
+ extensions: []
115
+ extra_rdoc_files:
116
+ - LICENSE.txt
117
+ - README.md
118
+ files:
119
+ - .document
120
+ - .travis.yml
121
+ - Gemfile
122
+ - Gemfile.lock
123
+ - LICENSE.txt
124
+ - README.md
125
+ - Rakefile
126
+ - VERSION
127
+ - example/1386362824-tt40-gap0.5animated.gif
128
+ - example/gem_example.rb
129
+ - example/typing.mp4
130
+ - lib/MIAConverter.rb
131
+ - spec/MIAConverter_spec.rb
132
+ - spec/spec_helper.rb
133
+ - test/helper.rb
134
+ - test/test_MIAConverter.rb
135
+ homepage: http://github.com/MartinJNash/MIAConverter
136
+ licenses:
137
+ - MIT
138
+ metadata: {}
139
+ post_install_message:
140
+ rdoc_options: []
141
+ require_paths:
142
+ - lib
143
+ required_ruby_version: !ruby/object:Gem::Requirement
144
+ requirements:
145
+ - - '>='
146
+ - !ruby/object:Gem::Version
147
+ version: '0'
148
+ required_rubygems_version: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - '>='
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ requirements: []
154
+ rubyforge_project:
155
+ rubygems_version: 2.1.11
156
+ signing_key:
157
+ specification_version: 4
158
+ summary: Turns a video file into an animated gif.
159
+ test_files: []