screengif 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,10 @@
1
+ .bundle/
2
+ vendor/
3
+ Gemfile.lock
4
+
5
+ output
6
+ build
7
+ *.gem
8
+
9
+ *.swp
10
+ *.swo
@@ -0,0 +1,54 @@
1
+ screengif dev notes
2
+ ===================
3
+
4
+ ## Building the gem
5
+
6
+ See [vagrant-vbox-manage/DEVNOTES.md](https://github.com/dergachev/vagrant-vbox-snapshot/blob/master/DEVNOTES.md)
7
+
8
+ ```
9
+ gem build screengif.gemspec
10
+ gem install screengif-0.0.1.gem
11
+ screengif -i=demo.mov -o demo5.gif
12
+ ```
13
+
14
+ ### Related solutions
15
+
16
+ * http://freezeframe.chrisantonellis.com/ (js library to freeze/play gifs)
17
+ * http://askubuntu.com/questions/107726/how-to-create-animated-gif-images-of-a-screencast
18
+
19
+ ### RMagick
20
+
21
+ * http://railscasts.com/episodes/374-image-manipulation?view=asciicast
22
+ * http://ruby.bastardsbook.com/chapters/image-manipulation/
23
+ * https://github.com/markandrus/imgswiss/blob/master/pipeline.rb (ffmpeg -> imagemagick via rmagick -> gif)
24
+
25
+ * http://www.imagemagick.org/RMagick/doc/info.html#format
26
+ * http://www.imagemagick.org/RMagick/doc/draw.html#rectangle
27
+ * http://www.imagemagick.org/RMagick/doc/constants.html#GravityType
28
+ * http://www.simplesystems.org/RMagick/doc/optequiv.html
29
+ * http://www.imagemagick.org/RMagick/doc/ilist.html
30
+ * http://www.imagemagick.org/RMagick/doc/clip_path.rb.html (define_clip_path example)
31
+
32
+ ### Imagemagick
33
+
34
+ * http://www.imagemagick.org/Usage/draw/
35
+ * http://www.imagemagick.org/Usage/anim_opt/
36
+ * http://www.imagemagick.org/Usage/transform/#fx
37
+ * http://www.imagemagick.org/Usage/layers/
38
+ * http://www.imagemagick.org/script/command-line-options.php#delete
39
+ * http://www.imagemagick.org/script/fx.php
40
+ * http://www.imagemagick.org/script/escape.php
41
+ * http://www.imagemagick.org/Usage/annotating/#watermarking
42
+ * http://www.imagemagick.org/Usage/anim_mods/#frame_mod
43
+ * http://www.ioncannon.net/linux/81/5-imagemagick-command-line-examples-part-1/
44
+
45
+ ## Bash guides
46
+
47
+ * http://andreinc.net/2011/09/04/bash-scripting-best-practice/
48
+ * http://stackoverflow.com/questions/242538/unix-shell-script-find-out-which-directory-the-script-file-resides
49
+
50
+ ## Ruby guides
51
+
52
+ * TODO: implement tests; see https://github.com/pgericson/progress_bar/blob/master/test/arguments_test.rb
53
+ * TODO: look at mixlib-{shellout,cli,logger}; https://github.com/opscode/mixlib-shellout
54
+ * TODO: look at https://github.com/bitboxer/simple_progressbar/blob/master/lib/simple_progressbar.rb
@@ -0,0 +1,28 @@
1
+ FROM ubuntu:14.04
2
+
3
+ # If host is running squid-deb-proxy on port 8000, populate /etc/apt/apt.conf.d/30proxy
4
+ # By default, squid-deb-proxy 403s unknown sources, so apt shouldn't proxy ppa.launchpad.net
5
+ RUN route -n | awk '/^0.0.0.0/ {print $2}' > /tmp/host_ip.txt
6
+ RUN echo "HEAD /" | nc `cat /tmp/host_ip.txt` 8000 | grep squid-deb-proxy \
7
+ && (echo "Acquire::http::Proxy \"http://$(cat /tmp/host_ip.txt):8000\";" > /etc/apt/apt.conf.d/30proxy) \
8
+ && (echo "Acquire::http::Proxy::ppa.launchpad.net DIRECT;" >> /etc/apt/apt.conf.d/30proxy) \
9
+ || echo "No squid-deb-proxy detected on docker host"
10
+
11
+ RUN apt-get update
12
+
13
+ RUN apt-get install -y imagemagick
14
+ RUN apt-get install -y libmagickwand-dev
15
+ RUN apt-get install -y gifsicle
16
+ RUN apt-get -y install ruby1.9.1 ruby1.9.1-dev
17
+ RUN apt-get install -y build-essential curl git vim
18
+
19
+ RUN apt-get install -y python-software-properties software-properties-common
20
+ RUN add-apt-repository ppa:mc3man/trusty-media
21
+ RUN apt-get update
22
+ RUN apt-get -y install ffmpeg
23
+
24
+ RUN gem install bundler --no-rdoc --no-ri
25
+ ADD Gemfile /tmp/Gemfile
26
+ RUN cd /tmp; bundle install
27
+
28
+ WORKDIR /srv/screengif
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'rmagick'
@@ -0,0 +1,20 @@
1
+ build:
2
+ docker build -t dergachev/screengif .
3
+
4
+ cmd=/bin/bash
5
+ docker-run:
6
+ docker run -t -i \
7
+ -v `pwd`:/srv/screengif \
8
+ dergachev/screengif \
9
+ /bin/bash -c "umask 002; $(cmd) $(args)"
10
+
11
+ docker-bash:
12
+ $(MAKE) docker-run cmd="/bin/bash"
13
+
14
+ docker-convert:
15
+ $(MAKE) docker-run cmd="bin/screengif" args="$(args)"
16
+
17
+ docker-shell:
18
+ $(MAKE) docker-run cmd="/bin/bash"
19
+
20
+ .PHONY: build docker-run docker-convert docker-shell
@@ -0,0 +1,111 @@
1
+ # Screengif
2
+
3
+ A commandline tool to convert SCREENCAST.mov into ANIMATED.gif
4
+
5
+ Here's what happens when you apply it to [demo.mov](https://raw.github.com/dergachev/screengif/master/demo.mov)
6
+
7
+ <img src="https://raw.github.com/dergachev/screengif/master/demo.gif" width="400" />
8
+
9
+ ## Usage
10
+
11
+ ```
12
+ screengif.rb - Convert your screencast into a gif.
13
+ Usage:
14
+ screengif.rb [options] [--input FILENAME.mov] [--output OUTPUTFILE.gif]
15
+ Examples:
16
+ ./screengif.rb --input demo.mov --output out.gif
17
+ cat somefile.gif | ./screengif.rb --progressbar --framerate 10 --delay 50 --delay-last 5 > out.gif
18
+
19
+ Specific options:
20
+ -i, --input FILENAME.mov Use ffmpeg to convert FILENAME.mov into PPM image stream and process results.
21
+ If missing, will process PPM or GIF image stream from STDIN.
22
+ -o, --output FILENAME.gif Output resulting GIF data to FILENAME.gif. (defaults to STDOUT).
23
+ -p, --progressbar Overlay progress bar on the animation.
24
+ -d, --delay MS Animation frame delay, in tens of ms. (default: 10)
25
+ --delay-last MS Animation frame delay of last frame, in tens of ms. (default: 50)
26
+ -r, --framerate FPS Specify amount of frames per second to keep. (default: 5)
27
+ -w, --max-width PIXELS Output image max width, in pixels.
28
+ --max-height PIXELS Output image max height, in pixels.
29
+ --no-contrast Skip increasing contrast using imagemagick.
30
+ -f, --fuzz PERCENT Imagemagick fuzz factor for color reduction. (default: 5%)
31
+ --no-coalesce Skip Magick::ImageList#coalesce() if input doesn't need it.
32
+ --no-gifsicle Prevent filter the output through gifsicle. Greatly increases output file size.
33
+ -h, --help Show this message
34
+ -v, --verbose Verbose output
35
+ --version Show version
36
+ ```
37
+
38
+ ## Installation
39
+
40
+ ### Under Docker
41
+
42
+ If you have docker running, this is the quickest way to get
43
+ started with screengif:
44
+
45
+ ```
46
+ git clone git@github.com:dergachev/screengif.git
47
+ cd screengif
48
+
49
+ make build # or alternatively, 'docker pull dergachev/screengif'
50
+
51
+ make docker-convert args="-i demo.mov -o demo-docker.gif"
52
+
53
+ # input files must be relative to cloned screengif repo
54
+ cp /path/to/myMovie.mov .
55
+
56
+ make docker-convert args="-i myMovie.mov -o myMovie.gif"
57
+ ```
58
+
59
+ See Dockerfile and Makefile for how it works.
60
+
61
+ ### With Vagrant
62
+
63
+ If you have Vagrant and Virtualbox already installed, this is both faster and cleaner than downloading and compiling all the dependencies in OS X. To install, simply do the following:
64
+
65
+ ```
66
+ vagrant up
67
+ ```
68
+
69
+ The easiest way to use it is to copy your image to screengif project directory (shared in the VM under /vagrant), and run the following:
70
+
71
+ ```
72
+ cp ~/screencast.mov ./screencast.mov
73
+ vagrant ssh -- '/vagrant/screengif.rb --input /vagrant/screencast.mov --output /vagrant/output/screencast.gif'
74
+ ls ./output/screencast.gif # should exist!
75
+
76
+ # when finished, destroy the VM
77
+ vagrant destroy -f
78
+ ```
79
+
80
+ ### On OSX, with homebrew
81
+
82
+ The following works with OS X and homebrew, assuming you have ruby 1.9.2+:
83
+
84
+ You may need to install brew-cask: https://github.com/phinze/homebrew-cask
85
+
86
+ ```bash
87
+ git clone https://github.com/dergachev/screengif.git
88
+ cd screengif
89
+
90
+ # x-quartz is a dependency for gifsicle, no longer installed starting on 10.8
91
+ brew cask install xquartz
92
+ open /opt/homebrew-cask/Caskroom/xquartz/2.7.7/XQuartz.pkg # runs the XQuartz installer
93
+
94
+ brew install ffmpeg imagemagick gifsicle
95
+ gem install rmagick
96
+ ```
97
+
98
+ ## Tips
99
+
100
+ See https://gist.github.com/dergachev/4627207#os-x-screencast-to-animated-gif
101
+ for a guide on how to use Quicktime Player to record a screencast on OS X.
102
+ Keep in mind that other tools (like Screenflow) produce better video quality.
103
+
104
+ If you install [dropbox-screenshots](https://github.com/dergachev/dropbox-screenshots),
105
+ the following will automatically upload your new gif to Dropbox:
106
+
107
+ cp out.gif ~/Dropbox/Public/screenshots
108
+
109
+ ## Resources
110
+
111
+ See [DEVNOTES](https://github.com/dergachev/screengif/blob/master/DEVNOTES.md)
@@ -0,0 +1,27 @@
1
+ # -*- mode: ruby -*-
2
+ # vi: set ft=ruby :
3
+
4
+ Vagrant.configure("2") do |config|
5
+ config.vm.box = "precise64"
6
+
7
+ # config.vm.provision :shell, :inline => "apt-get install -y vim curl git"
8
+
9
+ config.vm.provision :shell, :inline => <<-EOH
10
+ apt-get update
11
+ apt-get install -y ffmpeg gifsicle imagemagick libmagickwand-dev
12
+ apt-get -y install ruby1.9.1 ruby1.9.1-dev
13
+ gem install bundler --no-rdoc --no-ri
14
+ cd /vagrant
15
+ bundle install
16
+ EOH
17
+
18
+ # test that everything is installed correctly by generating ./output/demo.gif
19
+ config.vm.provision :shell, :inline => <<-EOH
20
+ cd /vagrant
21
+ test -f ./output/demo.gif && exit 0 # ensures this script runs just once
22
+ echo "Testing deployment by converting ./demo.mov to ./output/demo.gif"
23
+ mkdir -p ./output
24
+ # vagrant colors stderr red (undesirable), so redirect it to stdout
25
+ ./screengif.rb --input demo.mov --output ./output/demo.gif 2>&1
26
+ EOH
27
+ end
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # when run as gem, $0 is /usr/local/bin/screengif not this file
4
+ if $0 == __FILE__
5
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
6
+ end
7
+
8
+ require 'screengif'
9
+
10
+ Screengif::start
Binary file
Binary file
@@ -0,0 +1,126 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'RMagick'
4
+ include Magick
5
+
6
+ require 'screengif/draw_progressbar.rb'
7
+ require 'screengif/options.rb'
8
+ require 'screengif/util.rb'
9
+
10
+ module Screengif
11
+ def self.call_ffmpeg(input_file, options, verbose)
12
+ ffmpeg_loglevel = verbose ? 'verbose' : 'warning'
13
+ if options.framerate
14
+ ffmpeg_framerate = "-r #{options.framerate}"
15
+ end
16
+
17
+ if options.max_width || options.max_height
18
+ options.max_width ||= "-1"
19
+ options.max_height ||= "-1"
20
+ ffmpeg_resize = "-vf scale=#{options.max_width}:#{options.max_height} -sws_flags lanczos"
21
+ end
22
+ # TODO: error handling
23
+ return `ffmpeg -i '#{input_file}' -loglevel #{ffmpeg_loglevel} #{ffmpeg_framerate} #{ffmpeg_resize} -f image2pipe -vcodec ppm - `
24
+ end
25
+
26
+ def self.call_gifsicle(data)
27
+ $stderr.puts "Filtering output through gifsicle" if $verbose
28
+ # TODO: error handling
29
+ result = ''
30
+ # popen is for system calls that require setting STDIN
31
+ IO.popen('gifsicle --loop --optimize=3 --multifile -', 'r+') do |f|
32
+ f.write(data)
33
+ f.close_write
34
+ result = f.read
35
+ end
36
+ return result
37
+ end
38
+
39
+ def self.handle_input(input_file, options, optionparser)
40
+ if (input_file)
41
+ $stderr.puts "Running ffmpeg with #{input_file}" if $verbose
42
+ input = Screengif::call_ffmpeg(input_file, options, $verbose)
43
+ elsif !$stdin.tty? # we are being piped to
44
+ $stderr.puts "Reading input from STDIN." if $verbose
45
+ input = STDIN.read
46
+ else
47
+ $stderr.puts "No input file available."
48
+ puts optionparser
49
+ exit 1
50
+ end
51
+ return input
52
+ end
53
+
54
+ def self.handle_output(output_file, output, optionparser)
55
+ if (output_file)
56
+ File.open(output_file, 'w') do |f|
57
+ f.puts output
58
+ end
59
+ elsif !STDOUT.tty?
60
+ $stderr.puts "Sending output to STDOUT" if $verbose
61
+ puts output
62
+ else
63
+ $stderr.puts "Error: No output destination available."
64
+ puts optionparser
65
+ exit 1
66
+ end
67
+ end
68
+
69
+ def self.start
70
+ options,optionparser = Screengif::Options.parse(ARGV)
71
+ $startTime = Time.now
72
+
73
+ input = handle_input(options.input_file, options, optionparser)
74
+ canvas = ImageList.new.from_blob(input)
75
+
76
+ if (!options.no_coalesce)
77
+ $stderr.puts "Beginning imagemagick coalescing..." if $verbose
78
+ canvas = canvas.coalesce()
79
+ $stderr.puts "Coalescing completed" if $verbose
80
+ end
81
+
82
+ statusPrinter = Screengif::StatusPrinter.new($stderr)
83
+ canvas.each_with_index do |img,index|
84
+ statusPrinter.printText("Processing image: #{index+1}/#{canvas.length}")
85
+ img.delay = (index + 1 == canvas.length) ? options.delay_last : options.delay
86
+ img.format = 'GIF'
87
+
88
+ if options.fuzz.to_i > 0
89
+ # when run as a gem, setting img.fuzz="5%" throws a wierd error; so we do this instead
90
+ # img.fuzz = "#{img.fuzz}%"
91
+ img.fuzz = QuantumRange * options.fuzz.to_i / 100.0
92
+ end
93
+ unless options.nocontrast
94
+ img = img.contrast(true)
95
+ img = img.white_threshold(QuantumRange * 0.99)
96
+ # img = img.level(QuantumRange * 0.05, QuantumRange * 0.95)
97
+ end
98
+ Screengif::DrawProgressbar.draw(img, (index.to_f+1)/canvas.length) if (options.progressbar)
99
+ canvas[index] = img
100
+ end
101
+ statusPrinter.done
102
+
103
+ # see http://stackoverflow.com/questions/958681/how-to-deal-with-memory-leaks-in-rmagick-in-ruby
104
+ GC.start
105
+
106
+ # Reduce down to 256 colors (as required by GIF), disable dithering (equivalent to +dither)
107
+ $stderr.puts "Beginning quantization... (takes a while)" if $verbose
108
+ canvas = canvas.quantize(256, RGBColorspace, NoDitherMethod)
109
+ $stderr.puts "Quantization completed." if $verbose
110
+
111
+ $stderr.puts "Beginning rmagick OptimizePlusLayer..." if $verbose
112
+ canvas = canvas.optimize_layers(OptimizePlusLayer)
113
+ $stderr.puts "Beginning rmagick OptimizeTransLayer..." if $verbose
114
+ canvas = canvas.optimize_layers(OptimizeTransLayer)
115
+
116
+ $stderr.puts "Rmagick processing completed. Outputting results..." if $verbose
117
+ output = canvas.to_blob
118
+
119
+ GC.start
120
+
121
+ output = Screengif::call_gifsicle(output) unless (options.no_gifsicle)
122
+
123
+ handle_output(options.output_file, output, optionparser)
124
+ Screengif::ConversionStats.print(options.input_file, options.output_file, input, output)
125
+ end
126
+ end
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ module Screengif
4
+ class DrawProgressbar
5
+ def self.draw(img,ratio)
6
+ wid = img.columns() - 3
7
+ ht = img.rows() - 3
8
+ rectWid = 60
9
+ rectHt = 20
10
+
11
+ progressbar = Draw.new
12
+
13
+ progressbar
14
+ .fill('white')
15
+ .stroke('black')
16
+ .draw(img)
17
+ .rectangle(wid-rectWid,ht-rectHt,wid,ht)
18
+ progressbar
19
+ .fill('black')
20
+ .pointsize(12)
21
+ .stroke('transparent')
22
+ .font_weight(BoldWeight)
23
+ .gravity(NorthWestGravity)
24
+ .text(wid-rectWid+4,ht-rectHt+5,"screengif")
25
+ progressbar
26
+ .fill('black')
27
+ .stroke('transparent')
28
+ .rectangle(wid-rectWid,ht-rectHt,wid-rectWid*(1-ratio),ht)
29
+ progressbar.draw(img)
30
+
31
+ maskedDraw = Draw.new
32
+ maskedDraw.define_clip_path('clip') {
33
+ maskedDraw
34
+ .rectangle(wid-rectWid,ht-rectHt,wid-rectWid*(1-ratio),ht)
35
+ }
36
+ maskedDraw.push
37
+ maskedDraw.clip_path('clip')
38
+ maskedDraw
39
+ .fill('white')
40
+ .pointsize(12)
41
+ .stroke('transparent')
42
+ .font_weight(BoldWeight)
43
+ .gravity(NorthWestGravity)
44
+ .text(wid-rectWid+4,ht-rectHt+5,"screengif")
45
+ maskedDraw.pop
46
+ maskedDraw.draw(img)
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,113 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+ require 'ostruct'
5
+ require 'pp'
6
+
7
+ $verbose = false
8
+
9
+ module Screengif
10
+ class Options
11
+ def self.parse(args)
12
+ options = OpenStruct.new
13
+
14
+ options.framerate = 5
15
+ options.delay = 10
16
+ options.delay_last = 50
17
+ options.no_coalesce = false
18
+ options.progressbar = false
19
+ options.input_file = nil
20
+ options.output_file = nil
21
+ options.no_gifsicle = false
22
+ options.fuzz = 5
23
+
24
+ # options.ffmpeg_inputfile = nil
25
+
26
+ optionparser = OptionParser.new do |opts|
27
+ opts.banner = "screengif.rb - Convert your screencast into a gif.\n" +
28
+ "Usage:\n" +
29
+ "\tscreengif.rb [options] [--input FILENAME.mov] [--output OUTPUTFILE.gif]\n" +
30
+ "Examples:\n" +
31
+ "\t./screengif.rb --input demo.mov --output out.gif\n" +
32
+ "\tcat somefile.gif | ./screengif.rb --progressbar --framerate 10 --delay 50 --delay-last 5 > out.gif\n"
33
+
34
+ opts.separator ""
35
+ opts.separator "Specific options:"
36
+
37
+ opts.on("-i", "--input FILENAME.mov", "Use ffmpeg to convert FILENAME.mov into PPM image stream and process results.",
38
+ "If missing, will process PPM or GIF image stream from STDIN.") do |filename|
39
+ if (File.exists?(filename))
40
+ options.input_file = filename
41
+ options.no_coalesce = true # ffmpeg's ppm output is already coalesced
42
+ else
43
+ $stderr.puts "Unable to open filename: #{filename}"
44
+ puts opts
45
+ exit 1
46
+ end
47
+ end
48
+ opts.on("-o", "--output FILENAME.gif", "Output resulting GIF data to FILENAME.gif. (defaults to STDOUT).") do |filename|
49
+ options.output_file = filename
50
+ end
51
+
52
+ opts.on("-d", "--delay MS", Integer, "Animation frame delay, in tens of ms. (default: 10)") do |tens_of_ms|
53
+ options.delay = tens_of_ms.to_i
54
+ end
55
+
56
+ opts.on("-p", "--progressbar", "Overlay progress bar on the animation.") do
57
+ options.progressbar = true
58
+ end
59
+
60
+ opts.on("-d", "--delay MS", Integer, "Animation frame delay, in tens of ms. (default: 10)") do |tens_of_ms|
61
+ options.delay = tens_of_ms.to_i
62
+ end
63
+
64
+ opts.on("--delay-last MS", Integer, "Animation frame delay of last frame, in tens of ms. (default: 50)") do |tens_of_ms|
65
+ options.delay_last = tens_of_ms.to_i
66
+ end
67
+
68
+ opts.on("-r", "--framerate FPS", Integer, "Specify amount of frames per second to keep. (default: 5)") do |fps|
69
+ options.framerate = fps.to_i
70
+ end
71
+
72
+ opts.on("-w", "--max-width PIXELS", Integer, "Output image max width, in pixels.") do |pixels|
73
+ options.max_width = pixels.to_i
74
+ end
75
+
76
+ opts.on("--max-height PIXELS", Integer, "Output image max height, in pixels.") do |pixels|
77
+ options.max_height = pixels.to_i
78
+ end
79
+
80
+ opts.on("--no-contrast", "Skip increasing contrast using imagemagick.") do
81
+ options.nocontrast = true
82
+ end
83
+
84
+ opts.on("-f", "--fuzz PERCENT", Integer, "Imagemagick fuzz factor for color reduction. (default: 5%)") do |fuzz|
85
+ options.fuzz = fuzz.to_i
86
+ end
87
+
88
+ opts.on("--no-coalesce", "Skip Magick::ImageList#coalesce() if input doesn't need it.") do
89
+ options.no_coalesce = true
90
+ end
91
+
92
+ opts.on("--no-gifsicle", "Prevent filter the output through gifsicle. Greatly increases output file size.") do
93
+ options.no_gifsicle = true
94
+ end
95
+
96
+ # Boilerplate
97
+ opts.on_tail("-h", "--help", "Show this message") do
98
+ puts opts
99
+ exit
100
+ end
101
+ opts.on_tail("-v", "--verbose", "Verbose output") do
102
+ $verbose = true
103
+ end
104
+ opts.on_tail("--version", "Show version") do
105
+ puts "0.1"
106
+ exit
107
+ end
108
+ end
109
+ optionparser.parse!(args)
110
+ return options, optionparser
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env ruby
2
+
3
+
4
+ module Screengif
5
+ class StatusPrinter
6
+ # inspired by http://stackoverflow.com/a/6679572/9621
7
+ def initialize(stream)
8
+ @previous_size = 0
9
+ @stream = stream || $stdout
10
+ end
11
+
12
+ def printText(text)
13
+ if @previous_size > 0
14
+ @stream.print "\033[#{@previous_size}D"
15
+ @stream.print(" " * @previous_size)
16
+ @stream.print "\033[#{@previous_size}D"
17
+ end
18
+ @stream.print text
19
+ @stream.flush
20
+ @previous_size = text.gsub(/\e\[\d+m/,"").size
21
+ end
22
+
23
+ def done()
24
+ @previous_size = 0
25
+ @stream.print "\n"
26
+ end
27
+ end
28
+
29
+ class ConversionStats
30
+ def self.print(input_file, output_file, input, output)
31
+ $stderr.puts "Conversion completed in #{Time.now - $startTime} seconds."
32
+ if input_file # ffmpeg
33
+ # Duration: 00:00:04.28, start: 0.010333, bitrate: 11225 kb/s
34
+ duration = (`ffmpeg -i '#{input_file}' 2>&1 | grep Duration`).gsub(/^.*Duration:\s*([^,]+),.*$/, '\1').gsub("\n",'')
35
+
36
+ input_filesize = `ls -lh '#{input_file}' | awk '{print $5}'`.gsub("\n",'')
37
+ $stderr.puts "Input: #{input_file} (#{duration}, #{input_filesize})"
38
+ else # piped input
39
+ input_contentsize = (input.bytesize.to_f / 2**10).to_i().to_s + "K"
40
+ $stderr.puts "Input: STDIN (#{input_contentsize})"
41
+ end
42
+ if output_file
43
+ output_filesize = `ls -lh '#{output_file}' | awk '{print $5}'`.gsub("\n",'')
44
+ $stderr.puts "Output: '#{output_file}' (#{output_filesize})"
45
+ else # piped output
46
+ output_contentsize = (output.bytesize.to_f / 2**10).to_i().to_s + "K"
47
+ $stderr.puts "Output: STDOUT (#{output_contentsize})"
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,21 @@
1
+ $:.unshift File.expand_path('../lib', __FILE__)
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "screengif"
5
+ spec.version = "0.0.1"
6
+ spec.authors = "Alex Dergachev"
7
+ spec.email = "alex@evolvingweb.ca"
8
+ spec.summary = 'Script to convert mov files to animated gifs.'
9
+ spec.description = 'Wrapper on ffmpeg and imagemagick to convert .mov to .gif'
10
+ spec.homepage = 'https://github.com/dergachev/screengif'
11
+ spec.license = "MIT"
12
+
13
+ spec.files = `git ls-files`.split($/)
14
+ spec.bindir = 'bin'
15
+ spec.executables = 'screengif'
16
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
17
+ spec.require_path = 'lib'
18
+
19
+ spec.add_development_dependency "bundler"
20
+ spec.add_development_dependency "rake"
21
+ end
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: screengif
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Alex Dergachev
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2015-04-30 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: Wrapper on ffmpeg and imagemagick to convert .mov to .gif
47
+ email: alex@evolvingweb.ca
48
+ executables:
49
+ - screengif
50
+ extensions: []
51
+ extra_rdoc_files: []
52
+ files:
53
+ - .gitignore
54
+ - DEVNOTES.md
55
+ - Dockerfile
56
+ - Gemfile
57
+ - Makefile
58
+ - README.md
59
+ - Vagrantfile
60
+ - bin/screengif
61
+ - demo.gif
62
+ - demo.mov
63
+ - lib/screengif.rb
64
+ - lib/screengif/draw_progressbar.rb
65
+ - lib/screengif/options.rb
66
+ - lib/screengif/util.rb
67
+ - screengif.gemspec
68
+ homepage: https://github.com/dergachev/screengif
69
+ licenses:
70
+ - MIT
71
+ post_install_message:
72
+ rdoc_options: []
73
+ require_paths:
74
+ - lib
75
+ required_ruby_version: !ruby/object:Gem::Requirement
76
+ none: false
77
+ requirements:
78
+ - - ! '>='
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ required_rubygems_version: !ruby/object:Gem::Requirement
82
+ none: false
83
+ requirements:
84
+ - - ! '>='
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ requirements: []
88
+ rubyforge_project:
89
+ rubygems_version: 1.8.23
90
+ signing_key:
91
+ specification_version: 3
92
+ summary: Script to convert mov files to animated gifs.
93
+ test_files: []