video2gif 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a792d0bc3ded611a4295f7195ab17fbe5a71c65ae84bc527eb02c9f6c667088c
4
- data.tar.gz: f17cfefa5ef240925a2915ae089df6c7d9eacd7bf2d1ac449bce6f707a2a15c7
3
+ metadata.gz: 9033455c4d54099067dd61428f3190e75bc52783ab0ee110effa5cb9efedf688
4
+ data.tar.gz: fd1092a4ef5ffa4c280861fa084444ed2d3b260139062488824c71c3de0957ee
5
5
  SHA512:
6
- metadata.gz: ba5e69371e4edb486ff79a7ffa539cbf656c3edf1bc1794f58a02add3240fd81acadaaba8502b123990e09efa1d630560b4a20357d747f3349b3f9314864a9aa
7
- data.tar.gz: 243ddc56a97b5470d7771e90731dafbb9d0c69c2427e406a4f6f664305fe6d1bd40b27cf29b8a99221dabcce6d76a562ea5321767e161cdf72be165a2a2f94a3
6
+ metadata.gz: 19a4bfdfb4abd9f13c9c0b8f6a558ef9c1563c620c864e70b3ed96f59b2dd344e153c7900561b92298b18fdc3094ea8a8feb7f4fc2d1f67b2ba90adbc95f757a
7
+ data.tar.gz: f7c4f43908ca23a75651a73c3cff2cd30407024296ad3fab227f6dba331d0276228e54032458cf7d80739c0b6b4bd8f440508ef101ce5d6edd788e9f0d680084
data/README.md CHANGED
@@ -3,10 +3,10 @@ video2gif
3
3
 
4
4
  `video2gif` eases converting any video into a GIF.
5
5
 
6
- It uses [FFMpeg] and optionally [ImageMagick], so it understands any
7
- video that [FFMpeg] does. It has an array of options to allow you to
8
- select the part of the video you want, crop it automatically, overlay
9
- text, and manipulate the color and brightness.
6
+ It uses [FFMpeg], so it understands any video that [FFMpeg] does. It has
7
+ an array of options to allow you to select the part of the video you
8
+ want, crop it automatically, overlay text, and manipulate the color and
9
+ brightness.
10
10
 
11
11
 
12
12
  Installation
@@ -17,9 +17,6 @@ available in the system `$PATH`. If you can run `ffmpeg` from the
17
17
  command line, you're probably good. If not, use your favorite package
18
18
  manager to install it.
19
19
 
20
- If you install [ImageMagick], further optimization will automatically
21
- take place on the resulting GIF.
22
-
23
20
  Note that some features may not be available by default. For example,
24
21
  tonemapping (used for HDR videos) requires `libzimg` support, not
25
22
  included by default in the [FFMpeg] supplied by [Homebrew].
data/lib/video2gif.rb CHANGED
@@ -93,12 +93,6 @@ module Video2gif
93
93
  options[:cropdetect] = c || 24
94
94
  end
95
95
 
96
- parser.on('-o',
97
- '--[no-]optimize',
98
- 'Attempt to optimize GIF size with ImageMagick (default yes if available)') do |o|
99
- options[:optimize] = o
100
- end
101
-
102
96
  parser.on('--contrast CONTRAST',
103
97
  'Apply contrast adjustment, scaled from -2.0 to 2.0 (default 1)') do |c|
104
98
  options[:contrast] = c
@@ -239,19 +233,13 @@ module Video2gif
239
233
  exit
240
234
  end
241
235
 
242
- if !is_executable?('convert') && options[:optimize]
243
- logger.warn('ImageMagick isn\'t available! Optimization will be'\
244
- ' disabled!') unless options[:quiet]
245
- options[:optimize] = false
246
- end
247
-
248
236
  options
249
237
  end
250
238
 
251
239
  def self.build_filter_complex(options)
252
- fps = options[:fps] || 15
253
- palette_size = options[:palette] || 256
254
- width = options[:width] # default is not to scale at all
240
+ fps = options[:fps] || 15
241
+ max_colors = options[:palette] ? "max_colors=#{options[:palette]}:" : ''
242
+ width = options[:width] # default is not to scale at all
255
243
 
256
244
  # create filter elements
257
245
  fps_filter = "fps=#{fps}"
@@ -275,17 +263,17 @@ module Video2gif
275
263
  end
276
264
  eq_filter = if options[:eq]
277
265
  'eq=' + %W[
278
- contrast=#{options[:contrast] || 1}
279
- brightness=#{options[:brightness] || 0}
280
- saturation=#{options[:saturation] || 1}
281
- gamma=#{options[:gamma] || 1}
282
- gamma_r=#{options[:gamma_r] || 1}
283
- gamma_g=#{options[:gamma_g] || 1}
284
- gamma_b=#{options[:gamma_b] || 1}
266
+ contrast=#{ options[:contrast] || 1 }
267
+ brightness=#{ options[:brightness] || 0 }
268
+ saturation=#{ options[:saturation] || 1 }
269
+ gamma=#{ options[:gamma] || 1 }
270
+ gamma_r=#{ options[:gamma_r] || 1 }
271
+ gamma_g=#{ options[:gamma_g] || 1 }
272
+ gamma_b=#{ options[:gamma_b] || 1 }
285
273
  ].join(':')
286
274
  end
287
- palettegen_filter = "palettegen=max_colors=#{palette_size}:stats_mode=diff"
288
- paletteuse_filter = 'paletteuse=dither=sierra2_4a:diff_mode=rectangle'
275
+ palettegen_filter = "palettegen=#{max_colors}stats_mode=diff"
276
+ paletteuse_filter = 'paletteuse=dither=floyd_steinberg:diff_mode=rectangle'
289
277
  drawtext_filter = if options[:text]
290
278
  count_of_lines = options[:text].scan(/\\n/).count + 1
291
279
 
@@ -321,10 +309,10 @@ module Video2gif
321
309
  # before applying the palettegen so that we accurately predict the
322
310
  # final palette
323
311
  filter_complex << fps_filter
324
- filter_complex << crop_filter if crop_filter
325
- filter_complex << scale_filter if options[:width] unless options[:tonemap]
312
+ filter_complex << crop_filter if crop_filter
313
+ filter_complex << scale_filter if options[:width] unless options[:tonemap]
326
314
  filter_complex << tonemap_filters if options[:tonemap]
327
- filter_complex << eq_filter if options[:eq]
315
+ filter_complex << eq_filter if options[:eq]
328
316
  filter_complex << drawtext_filter if options[:text]
329
317
 
330
318
  # then generate the palette (and label this filter stream)
@@ -336,10 +324,10 @@ module Video2gif
336
324
  # affected by scaling)
337
325
  filter_complex << '[0:v][palette]' + paletteuse_filter
338
326
  filter_complex << fps_filter
339
- filter_complex << crop_filter if crop_filter
340
- filter_complex << scale_filter if options[:width] unless options[:tonemap]
327
+ filter_complex << crop_filter if crop_filter
328
+ filter_complex << scale_filter if options[:width] unless options[:tonemap]
341
329
  filter_complex << tonemap_filters if options[:tonemap]
342
- filter_complex << eq_filter if options[:eq]
330
+ filter_complex << eq_filter if options[:eq]
343
331
  filter_complex << drawtext_filter if options[:text]
344
332
 
345
333
  filter_complex.join(',')
@@ -349,51 +337,38 @@ module Video2gif
349
337
  if args[1]
350
338
  args[1].end_with?('.gif') ? args[1] : args[1] + '.gif'
351
339
  else
352
- File.join(File.dirname(args[0]),
353
- File.basename(args[0], '.*') + '.gif')
340
+ File.join(File.dirname(args[0]), File.basename(args[0], '.*') + '.gif')
354
341
  end
355
342
  end
356
343
 
357
- def self.build_ffmpeg_gif_command(args, options, logger)
358
- command = []
359
- command << 'ffmpeg'
360
- command << '-y' # always overwrite
344
+ def self.build_ffmpeg_cropdetect_command(args, options, logger)
345
+ command = ['ffmpeg']
361
346
  command << '-analyzeduration' << '2147483647' << '-probesize' << '2147483647'
362
347
  command << '-nostdin'
363
348
  command << '-ss' << options[:seek] if options[:seek]
364
349
  command << '-t' << options[:time] if options[:time]
365
350
  command << '-i' << args[0]
366
- command << '-filter_complex' << build_filter_complex(options)
367
- command << '-f' << 'gif'
368
-
369
- # if we're not optimizing, we won't send to stdout
370
- command << (options[:optimize] ? '-' : build_output_filename(args))
371
-
372
- logger.info(command.join(' ')) if options[:verbose] unless options[:quiet]
373
-
374
- command
375
- end
376
-
377
- def self.build_convert_optimize_command(args, options, logger)
378
- command = []
379
- command << 'convert' << '-' << '-layers' << 'Optimize' << build_output_filename(args)
351
+ command << '-filter_complex' << "cropdetect=limit=#{options[:cropdetect]}"
352
+ command << '-f' << 'null'
353
+ command << '-'
380
354
 
381
355
  logger.info(command.join(' ')) if options[:verbose] unless options[:quiet]
382
356
 
383
357
  command
384
358
  end
385
359
 
386
- def self.build_ffmpeg_cropdetect_command(args, options, logger)
387
- command = []
388
- command << 'ffmpeg'
360
+ def self.build_ffmpeg_gif_command(args, options, logger)
361
+ command = ['ffmpeg']
362
+ command << '-y' # always overwrite
389
363
  command << '-analyzeduration' << '2147483647' << '-probesize' << '2147483647'
390
364
  command << '-nostdin'
391
365
  command << '-ss' << options[:seek] if options[:seek]
392
366
  command << '-t' << options[:time] if options[:time]
393
367
  command << '-i' << args[0]
394
- command << '-filter_complex' << "cropdetect=limit=#{options[:cropdetect]}"
395
- command << '-f' << 'null'
396
- command << '-'
368
+ command << '-filter_complex' << build_filter_complex(options)
369
+ command << '-gifflags' << '+transdiff' # enabled by default
370
+ command << '-f' << 'gif'
371
+ command << build_output_filename(args)
397
372
 
398
373
  logger.info(command.join(' ')) if options[:verbose] unless options[:quiet]
399
374
 
@@ -405,7 +380,7 @@ module Video2gif
405
380
  options = parse_args(ARGV, logger)
406
381
 
407
382
  if options[:cropdetect]
408
- Open3.popen3(*build_ffmpeg_cropdetect_command(ARGV, options, logger)) do |stdin, stdout, stderr, wait_thr|
383
+ Open3.popen3(*build_ffmpeg_cropdetect_command(ARGV, options, logger)) do |stdin, stdout, stderr, thread|
409
384
  stdin.close
410
385
  stdout.close
411
386
  stderr.each(chomp: true) do |line|
@@ -414,26 +389,19 @@ module Video2gif
414
389
  end
415
390
  stderr.close
416
391
 
417
- raise "Process #{wait_thr.pid} failed! Try again with --verbose to see error." unless wait_thr.value.success?
392
+ raise "Process #{thread.pid} failed! Try again with --verbose to see error." unless thread.value.success?
418
393
  end
419
394
  end
420
395
 
421
- gif_pipeline_items = [build_ffmpeg_gif_command(ARGV, options, logger)]
422
- gif_pipeline_items << build_convert_optimize_command(ARGV, options, logger) if options[:optimize]
423
-
424
- read_io, write_io = IO.pipe
425
- Open3.pipeline_start(*gif_pipeline_items, out: write_io, err: write_io) do |threads|
426
- write_io.close
427
- if options[:verbose]
428
- read_io.each(chomp: true) { |line| logger.info(line) unless options[:quiet] }
429
- else
430
- read_io.read(1024) until read_io.eof?
396
+ Open3.popen3(*build_ffmpeg_gif_command(ARGV, options, logger)) do |stdin, stdout, stderr, thread|
397
+ stdin.close
398
+ stdout.close
399
+ stderr.each(chomp: true) do |line|
400
+ logger.info(line) if options[:verbose] unless options[:quiet]
431
401
  end
432
- read_io.close
402
+ stderr.close
433
403
 
434
- threads.each do |t|
435
- raise "Process #{t.pid} failed! Try again with --verbose to see error." unless t.value.success?
436
- end
404
+ raise "Process #{thread.pid} failed! Try again with --verbose to see error." unless thread.value.success?
437
405
  end
438
406
  end
439
407
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Video2gif
4
- VERSION = '0.0.1'
4
+ VERSION = '0.0.2'
5
5
  end
data/video2gif.gemspec CHANGED
@@ -17,7 +17,7 @@ Gem::Specification.new do |spec|
17
17
  # the 'allowed_push_host' to allow pushing to a single host or delete
18
18
  # this section to allow pushing to any host.
19
19
  if spec.respond_to?(:metadata)
20
- spec.metadata['allowed_push_host'] = 'https://rubygems.org/'
20
+ spec.metadata['allowed_push_host'] = 'https://rubygems.org'
21
21
  spec.metadata['homepage_uri'] = spec.homepage
22
22
  spec.metadata['source_code_uri'] = "https://github.com/emilyst/video2gif"
23
23
  # spec.metadata['changelog_uri'] = "https://github.com/emilyst/video2gif"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: video2gif
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Emily St.
@@ -93,7 +93,7 @@ homepage: https://github.com/emilyst/video2gif
93
93
  licenses:
94
94
  - CC0
95
95
  metadata:
96
- allowed_push_host: https://rubygems.org/
96
+ allowed_push_host: https://rubygems.org
97
97
  homepage_uri: https://github.com/emilyst/video2gif
98
98
  source_code_uri: https://github.com/emilyst/video2gif
99
99
  post_install_message: