screenshot_generator 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: dc45676b2096d9d1ac542d9e69c4a2491dae98ea
4
+ data.tar.gz: 90edf5253fffb6edaa668cc0824927dc68c29349
5
+ SHA512:
6
+ metadata.gz: 866854e0a4210f882315cdb4c6fa5f7fd92d73f771f7e5751b5d689dec888d4e01a0598dce3d0bb35edbcfdb3511fa185cc838e12369c10331ab9c527a040821
7
+ data.tar.gz: 59e420d241994def73a32944cda3dfc6178fe0c0ce534b2dfa99623480e826e9c05564bf64bf40bcd8ed2103e81b05516c79ef78a1a8365371b3f18ead7928f6
@@ -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,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,12 @@
1
+ DO WHAT THE FUCK YOU WANT TO + BEER/PIZZA PUBLIC LICENSE
2
+ Version 1, May 2011
3
+
4
+ Copyright (C) 2011 Tom Lea
5
+
6
+
7
+ DO WHAT THE FUCK YOU WANT TO + BEER/PIZZA PUBLIC LICENSE
8
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
9
+
10
+ 0. You just DO WHAT THE FUCK YOU WANT TO.
11
+ 1. If you make a substantial amount of money by exercising clause 0,
12
+ you should consider buying the author a beer or a pizza.
@@ -0,0 +1,32 @@
1
+ # ScreenshotGenerator
2
+
3
+ It makes pictures of your videos using ffmpg, and ruby.
4
+
5
+ ## Installation
6
+ ```bash
7
+ gem install screenshot_generator
8
+ ```
9
+
10
+ ## Usage
11
+ ```ruby
12
+ # Capture that lovely view from 3 hours into your 6 hour holiday video.
13
+ ScreenshotGenerator.extract_frame("holiday.mp4", 60*60*3, "the-car-park.jpg")
14
+
15
+ # Take 20 frames spread evenly around your holiday video, so you can sample the
16
+ # majesty of the same beach, from 20 different angles.
17
+ ScreenshotGenerator.extract_multi("holiday.mp4", "pictures-for-firends/", 20)
18
+
19
+ # Capture the three interesting bits of your holiday video.
20
+ vid = ScreenshotGenerator.new("holiday.mp4")
21
+ vid.extract_frame(60*60*2+8, "base-jumping.jpg")
22
+ vid.extract_frame(vid.length - 30, "end-credits.jpg")
23
+ ```
24
+
25
+ ## Additional usage
26
+ Although not thoroughly tested, it is theoretically possible that this library
27
+ could be used to take screen shots of videos that are neither holiday related,
28
+ nor dull.
29
+
30
+ ## Licence
31
+ WTFBPPL: http://tomlea.co.uk/WTFBPPL.txt
32
+
@@ -0,0 +1,5 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+ RSpec::Core::RakeTask.new(:spec)
4
+ task :default => :spec
5
+
@@ -0,0 +1,77 @@
1
+ require "screenshot_generator/version"
2
+
3
+ class ScreenshotGenerator
4
+ # Helper method for fetching a single frame
5
+ def self.extract_frame(video, *args)
6
+ new(video).extract_frame(*args)
7
+ end
8
+
9
+ def self.extract_multi(video, *args)
10
+ new(video).extract_multi(*args)
11
+ end
12
+
13
+ def initialize(video, size: '640x400')
14
+ @video = video
15
+ @size = size
16
+ raise ArgumentError, "Video does not exist" unless File.exist? @video
17
+ end
18
+
19
+ attr_reader :video, :size
20
+
21
+ def extract_frame(offset, path)
22
+ raise ArgumentError, "File already exists" if File.exist? path
23
+ offset = format_offset(offset)
24
+ ffmpeg(
25
+ "-loglevel", "error",
26
+ "-ss", offset,
27
+ "-i", video,
28
+ "-frames:v", 1,
29
+ "-s", size,
30
+ path
31
+ )
32
+ end
33
+
34
+
35
+ def extract_multi(dir, count)
36
+ dir = Pathname.new(dir)
37
+ 0.upto(count) do |index|
38
+ path = dir + "#{index}.jpg"
39
+ segment_size = length / (count + 2)
40
+ offset = (index + 1) * segment_size
41
+ extract_frame(offset, path)
42
+ end
43
+ end
44
+
45
+ def length
46
+ @length ||= get_length
47
+ end
48
+
49
+ protected
50
+
51
+ def ffmpeg(*args)
52
+ options = [self.class.ffmpeg, *args].map(&:to_s)
53
+ options.push(:err=>[:child, :out])
54
+ IO.popen(options) {|io| return io.read }
55
+ raise "ffmpeg comamnd #{options.inspect} failed" unless $?.success?
56
+ end
57
+
58
+ def self.ffmpeg
59
+ @ffmpeg ||= `which ffmpeg`.chomp
60
+ end
61
+
62
+ def get_length
63
+ output = ffmpeg("-i", video, "-frames", 1)
64
+ if output =~ /Duration:\s*([0-9:.]+)/
65
+ h,m,s = $1.split(":").map(&:to_i)
66
+ h*60^2 + m*60 + s
67
+ else
68
+ 60
69
+ end
70
+ end
71
+
72
+ def format_offset(v)
73
+ m, s = v.divmod(60)
74
+ h, m = m.divmod(60)
75
+ "%02i:%02i:%02i" % [h, m, s]
76
+ end
77
+ end
@@ -0,0 +1,3 @@
1
+ class ScreenshotGenerator
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'screenshot_generator/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "screenshot_generator"
8
+ spec.version = ScreenshotGenerator::VERSION
9
+ spec.authors = ["Tom Lea"]
10
+ spec.email = ["commit@tomlea.co.uk"]
11
+ spec.summary = %q{A simple wrapper around FFMpeg for extracing screen shots}
12
+ spec.homepage = ""
13
+ spec.license = "WTFBPPL"
14
+
15
+ spec.files = `git ls-files`.split($/)
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_development_dependency "bundler", "~> 1.5"
21
+ spec.add_development_dependency "rake"
22
+ spec.add_development_dependency "rspec"
23
+ spec.add_development_dependency "chunky_png"
24
+ end
@@ -0,0 +1,101 @@
1
+ require "rubygems"
2
+ require "bundler"
3
+ Bundler.setup
4
+
5
+ require "screenshot_generator"
6
+ require "rspec"
7
+
8
+ require "chunky_png"
9
+
10
+ describe ScreenshotGenerator do
11
+ let(:test_video){ "spec/fixtures/test-video.mov" }
12
+ let(:tmpfile){ "tmp/test_frame.png" }
13
+
14
+ describe ".extract_frame" do
15
+ it "extracts a frame from the video" do
16
+ expect(color_for_frame(0)).to be :red
17
+ expect(color_for_frame(1)).to be :green
18
+ expect(color_for_frame(2)).to be :blue
19
+ end
20
+
21
+ it "raises an ArgumentError if the video does not exist" do
22
+ expect{
23
+ ScreenshotGenerator.extract_frame("/tmp/does-not-exist.mp4", 0, "/dev/null")
24
+ }.to raise_error ArgumentError
25
+ end
26
+
27
+ it "errors is the output file already exists" do
28
+ expect{
29
+ ScreenshotGenerator.extract_frame(test_video, 0, __FILE__)
30
+ }.to raise_error ArgumentError
31
+ end
32
+ end
33
+
34
+ describe "#length" do
35
+ it "knows how long the video is" do
36
+ expect(ScreenshotGenerator.new(test_video).length).to eq 18
37
+ end
38
+ end
39
+
40
+ describe ".extract_multi" do
41
+ it "calls extract_frame for each needed frame" do
42
+ in_a_temp_dir do |dir|
43
+ ScreenshotGenerator.extract_multi(test_video, dir, 5)
44
+ 0.upto(5) do |i|
45
+ %x{convert #{dir + "#{i}.jpg"} #{dir + "#{i}.png"}}
46
+ end
47
+ expect(color_for_image(dir + "0.png")).to be :blue
48
+ expect(color_for_image(dir + "1.png")).to be :black
49
+ expect(color_for_image(dir + "2.png")).to be :green
50
+ expect(color_for_image(dir + "3.png")).to be :white
51
+ expect(color_for_image(dir + "4.png")).to be :red
52
+ expect(color_for_image(dir + "5.png")).to be :blue
53
+ end
54
+ end
55
+ end
56
+
57
+ def color_for_image(path)
58
+ rgb(ChunkyPNG::Image.from_file(path)[50,50]).classify
59
+ end
60
+
61
+ def color_for_frame(i)
62
+ ScreenshotGenerator.extract_frame(test_video, i, tmpfile)
63
+ color_for_image(tmpfile)
64
+ ensure
65
+ File.unlink tmpfile if File.exists?(tmpfile)
66
+ end
67
+
68
+ def in_a_temp_dir
69
+ dir = Pathname.new("tmp/working")
70
+ FileUtils.mkdir_p dir
71
+ yield dir
72
+ ensure
73
+ FileUtils.rm_r dir
74
+ end
75
+
76
+ Color = Struct.new(:r, :g, :b) do
77
+ def classify
78
+ if r > 250 and g > 250 and b > 250
79
+ :white
80
+ elsif r < 5 and g > 250 and b < 5
81
+ :green
82
+ elsif r > 250 and g < 5 and b < 5
83
+ :red
84
+ elsif r < 5 and g < 5 and b > 250
85
+ :blue
86
+ elsif r < 5 and g < 5 and b < 5
87
+ :black
88
+ else
89
+ raise "I don't know the color #{self.inspect}"
90
+ end
91
+ end
92
+ end
93
+
94
+ def rgb(color)
95
+ Color.new(
96
+ ChunkyPNG::Color.r(color),
97
+ ChunkyPNG::Color.g(color),
98
+ ChunkyPNG::Color.b(color)
99
+ )
100
+ end
101
+ end
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: screenshot_generator
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Tom Lea
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-02-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.5'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
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: chunky_png
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description:
70
+ email:
71
+ - commit@tomlea.co.uk
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - .gitignore
77
+ - Gemfile
78
+ - LICENSE.txt
79
+ - README.md
80
+ - Rakefile
81
+ - lib/screenshot_generator.rb
82
+ - lib/screenshot_generator/version.rb
83
+ - screenshot_generator.gemspec
84
+ - spec/features/image_generation_spec.rb
85
+ - spec/fixtures/test-video.mov
86
+ homepage: ''
87
+ licenses:
88
+ - WTFBPPL
89
+ metadata: {}
90
+ post_install_message:
91
+ rdoc_options: []
92
+ require_paths:
93
+ - lib
94
+ required_ruby_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ requirements: []
105
+ rubyforge_project:
106
+ rubygems_version: 2.0.14
107
+ signing_key:
108
+ specification_version: 4
109
+ summary: A simple wrapper around FFMpeg for extracing screen shots
110
+ test_files:
111
+ - spec/features/image_generation_spec.rb
112
+ - spec/fixtures/test-video.mov