evideo 0.2.4 → 0.2.9

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: 1e28f124268b83c747ed748296d09491c6955cb1b679952e76d0c78c3926de76
4
- data.tar.gz: e92e5ac092e29017ec65a4799de589109f4400723421360a46bbd35af8b6645e
3
+ metadata.gz: 23bae1bf4a02800c8338844da2b31fdef94a74c4c1375e6545c132b62ec43d87
4
+ data.tar.gz: ed983739260da1f0f38db33233250e59559934d5317f9b72a86405a1495abc03
5
5
  SHA512:
6
- metadata.gz: 7bb0acee95ef8a2307bdc1b525d82293fca925bc94cd8031dfa860affddeb40b6e52cca607f6315dacc343cf0b89ca79125112fe075d33a1cb7a1a36c1cfeb7b
7
- data.tar.gz: a7803cb72e5ff2105c3939deb56960babafba44fce72f26e9001e0191ca27b549110c8e87b1f556e725d10a3461f5792ade603f33646753d34a337c0c16307b0
6
+ metadata.gz: 405a6d20da0c168890ffb70f21dc7cd3a2cd8a73cc7fb52263c9aaebfd9ec656af07bfae5c07f63f2322131b3cf1789c0c9276b05e06ad65bf12aa89cae9d1c7
7
+ data.tar.gz: a5e507e1413047dcecb6118fdf06e09bfb0d663567ab6eb4e1af59eba75977fd9f77e292cdcfe3a4185b66b42e38a31d4ce7d2f3e08784c05101e07875ceb5e5
data/.rubocop.yml ADDED
@@ -0,0 +1,12 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.7
3
+ EnabledByDefault: true
4
+
5
+ Style/Copyright:
6
+ Enabled: false
7
+
8
+ Lint/ConstantResolution:
9
+ Enabled: false
10
+
11
+ Style/ConstantVisibility:
12
+ Enabled: false
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ ---
2
+ sudo: false
3
+ language: ruby
4
+ cache: bundler
5
+ rvm:
6
+ - 2.7.0
data/Gemfile.lock CHANGED
@@ -1,14 +1,72 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- evideo (0.2.4)
4
+ evideo (0.2.9)
5
5
  thor
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
- rake (13.0.1)
11
- thor (1.0.1)
10
+ ast (2.4.2)
11
+ backport (1.1.2)
12
+ benchmark (0.1.1)
13
+ e2mmap (0.1.0)
14
+ jaro_winkler (1.5.4)
15
+ kramdown (2.3.1)
16
+ rexml
17
+ kramdown-parser-gfm (1.1.0)
18
+ kramdown (~> 2.0)
19
+ kwalify (0.7.2)
20
+ mini_portile2 (2.5.3)
21
+ nokogiri (1.11.6)
22
+ mini_portile2 (~> 2.5.0)
23
+ racc (~> 1.4)
24
+ parallel (1.20.1)
25
+ parser (3.0.1.1)
26
+ ast (~> 2.4.1)
27
+ psych (3.3.2)
28
+ racc (1.5.2)
29
+ rainbow (3.0.0)
30
+ rake (13.0.3)
31
+ reek (6.0.4)
32
+ kwalify (~> 0.7.0)
33
+ parser (~> 3.0.0)
34
+ psych (~> 3.1)
35
+ rainbow (>= 2.0, < 4.0)
36
+ regexp_parser (2.1.1)
37
+ reverse_markdown (2.0.0)
38
+ nokogiri
39
+ rexml (3.2.5)
40
+ rubocop (1.16.0)
41
+ parallel (~> 1.10)
42
+ parser (>= 3.0.0.0)
43
+ rainbow (>= 2.2.2, < 4.0)
44
+ regexp_parser (>= 1.8, < 3.0)
45
+ rexml
46
+ rubocop-ast (>= 1.7.0, < 2.0)
47
+ ruby-progressbar (~> 1.7)
48
+ unicode-display_width (>= 1.4.0, < 3.0)
49
+ rubocop-ast (1.7.0)
50
+ parser (>= 3.0.1.1)
51
+ ruby-progressbar (1.11.0)
52
+ solargraph (0.41.1)
53
+ backport (~> 1.1)
54
+ benchmark
55
+ bundler (>= 1.17.2)
56
+ e2mmap
57
+ jaro_winkler (~> 1.5)
58
+ kramdown (~> 2.3)
59
+ kramdown-parser-gfm (~> 1.1)
60
+ parser (~> 3.0)
61
+ reverse_markdown (>= 1.0.5, < 3)
62
+ rubocop (>= 0.52)
63
+ thor (~> 1.0)
64
+ tilt (~> 2.0)
65
+ yard (~> 0.9, >= 0.9.24)
66
+ thor (1.1.0)
67
+ tilt (2.0.10)
68
+ unicode-display_width (2.0.0)
69
+ yard (0.9.26)
12
70
 
13
71
  PLATFORMS
14
72
  ruby
@@ -17,6 +75,10 @@ DEPENDENCIES
17
75
  bundler
18
76
  evideo!
19
77
  rake
78
+ reek
79
+ rubocop
80
+ solargraph
81
+ yard
20
82
 
21
83
  BUNDLED WITH
22
- 2.1.2
84
+ 2.1.4
data/README.md CHANGED
@@ -8,16 +8,16 @@ Processa ficheiros video. Pode alterar bitrate, framerate, height, aspect ratio
8
8
 
9
9
  ## Usage
10
10
 
11
- $ ev conv # converte videos
12
- $ ev test # testa videos
11
+ $ ev conv # converte videos
12
+ $ ev test # testa videos
13
13
 
14
- Options:
15
- [-d=DIR] # Onde procurar videos
16
- # Default: ["/home/eu/lust", "/media/eu/hrv2"]
17
- [-i=IN] # Pasta origem
18
- # Default: ftv
19
- [-o=OUT] # Pasta destino
20
- # Default: out
14
+ opcoes:
15
+ [-d=DIR] # Onde procurar videos defeito: ["/home/eu/lust", "/media/eu/hrv2", "/media/eu/hrv2/lust"]
16
+ [-i=IN] # Pasta inicial defeito: ftv
17
+ [-o=OUT] # Pasta final defeito: out
18
+ [-x], [--no-x] # executa/mostra comando converte videos
19
+ [-s=N] # Segundos cortados no inicio do video final defeito: 0=sem cortes
20
+ [-t=N] # Segundos duracao video final defeito: 0=sem cortes
21
21
 
22
22
  ## Development
23
23
 
@@ -27,7 +27,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
27
27
 
28
28
  ## Contributing
29
29
 
30
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/evideo.
30
+ Bug reports and pull requests are welcome on GitHub at https://github.com/hernanilr/evideo.
31
31
 
32
32
  ## License
33
33
 
data/Rakefile CHANGED
@@ -1,2 +1,5 @@
1
- require "bundler/gem_tasks"
2
- task :default => :spec
1
+ # frozen_string_literal: true
2
+
3
+ require('bundler/gem_tasks')
4
+
5
+ task default: :build
data/evideo.gemspec CHANGED
@@ -11,25 +11,30 @@ Gem::Specification.new do |spec|
11
11
  spec.email = ['hernanirvaz@gmail.com']
12
12
  spec.homepage = 'https://github.com/hernanilr/evideo'
13
13
  spec.license = 'MIT'
14
-
15
14
  spec.summary = 'Processa ficheiros video.'
16
- spec.description = spec.summary + ' Pode alterar bitrate, framerate, height, aspect ratio e elimina metadata.'
15
+ spec.description = "#{spec.summary} Pode alterar bitrate, framerate, height, aspect ratio e elimina metadata."
17
16
 
17
+ spec.required_ruby_version = Gem::Requirement.new('~> 2.7')
18
18
  spec.metadata['homepage_uri'] = spec.homepage
19
- spec.metadata['yard.run'] = 'yard'
19
+ spec.metadata['yard.run'] = 'yard'
20
20
 
21
21
  # Specify which files should be added to the gem when it is released.
22
22
  # The `git ls-files -z` loads the files in the RubyGem that have been
23
23
  # added into git.
24
- spec.files = Dir.chdir(File.expand_path(__dir__)) do
25
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
26
- end
24
+ spec.files =
25
+ Dir.chdir(File.expand_path(__dir__)) do
26
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
27
+ end
27
28
  spec.bindir = 'exe'
28
29
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
29
30
  spec.require_paths = ['lib']
30
31
 
31
- spec.add_development_dependency 'bundler'
32
- spec.add_development_dependency 'rake'
32
+ spec.add_development_dependency('bundler')
33
+ spec.add_development_dependency('rake')
34
+ spec.add_development_dependency('reek')
35
+ spec.add_development_dependency('rubocop')
36
+ spec.add_development_dependency('solargraph')
37
+ spec.add_development_dependency('yard')
33
38
 
34
- spec.add_dependency 'thor'
39
+ spec.add_dependency('thor')
35
40
  end
data/exe/ev CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'evideo'
4
+ require('evideo')
5
5
 
6
6
  Evideo::CLI.start(ARGV)
data/exe/evideo CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'evideo'
4
+ require('evideo')
5
5
 
6
6
  Evideo::CLI.start(ARGV)
data/lib/evideo.rb CHANGED
@@ -1,45 +1,52 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'thor'
4
+ require 'evideo/vars1'
5
+ require 'evideo/vars2'
6
+ require 'evideo/processa'
4
7
  require 'evideo/version'
5
- require 'evideo/hrvideo'
6
- require 'evideo/hrvprocessa'
7
8
 
9
+ # (see Evideo)
8
10
  module Evideo
9
- class Error < StandardError; end
10
- ID = `whoami`.chomp
11
+ who = `whoami`.chomp
12
+ ADI = ["/home/#{who}/lust", "/media/#{who}/hrv2", "/media/#{who}/hrv2/lust"].freeze
13
+
11
14
  # CLI para analisar/processar videos
12
15
  class CLI < Thor
13
- class_option :d, banner: 'DIR', type: :array, desc: 'Onde procurar videos',
14
- default: ["/home/#{ID}/lust", "/media/#{ID}/hrv2"]
15
- class_option :i, banner: 'IN', default: 'ftv', desc: 'Pasta origem'
16
- class_option :o, banner: 'OUT', default: 'out', desc: 'Pasta destino'
16
+ class_option :d, banner: 'DIR', type: :array, desc: 'Onde procurar videos', default: ADI
17
+ class_option :i, banner: 'IN', default: 'ftv', desc: 'Pasta inicial'
18
+ class_option :o, banner: 'OUT', default: 'out', desc: 'Pasta final'
19
+
20
+ # TODO convert jpg -> mp4
21
+ #ffmpeg -pattern_type glob -r 0.15 -i '*.jpg' -c:v libx264 -pix_fmt yuv420p -s 720x480 ../../lily95.mp4
17
22
 
18
23
  desc 'conv', 'converte videos'
19
- option :t, type: :boolean, default: false, desc: 'Processa somente segundos para teste'
24
+ option :x, type: :boolean, default: false, desc: 'executa/mostra comando converte videos'
25
+ option :s, type: :numeric, default: 0, desc: 'Segundos cortados no inicio do video final 0=sem cortes'
26
+ option :t, type: :numeric, default: 0, desc: 'Segundos duracao video final 0=sem cortes'
27
+ # converte videos
20
28
  def conv
21
- Dir.glob("#{fin}/*.???").sort.each do |f|
22
- HRVideo.new(f).processa(options, fout)
29
+ # cria pasta final para videos processados
30
+ system("mkdir -p #{ipasta}/#{options[:o]}")
31
+
32
+ Dir.glob("#{ipasta}/*.???").sort.each do |file|
33
+ Video.new(file, options).processa
23
34
  end
24
35
  end
25
36
 
26
37
  desc 'test', 'testa videos'
38
+ # testa videos
27
39
  def test
28
- Dir.glob("#{fin}/*.???").sort.each do |f|
29
- HRVideo.new(f).testa(options, fout)
40
+ Dir.glob("#{ipasta}/*.???").sort.each do |file|
41
+ puts(Video.new(file, options).inout)
30
42
  end
31
43
  end
32
44
 
33
45
  default_task :test
34
46
  no_commands do
35
- # @return [String] pasta absoluta origem dos videos
36
- def fin
37
- "#{options[:d].first}/#{options[:i]}"
38
- end
39
-
40
- # @return [String] pasta absoluta destino dos videos
41
- def fout
42
- "#{options[:d].first}/#{options[:o]}"
47
+ # @return [String] pasta absoluta inicial dos videos
48
+ def ipasta
49
+ "#{options[:d][0]}/#{options[:i]}"
43
50
  end
44
51
  end
45
52
  end
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ # (see Evideo)
4
+ module Evideo
5
+ # aspect ratios a converter para 16:9
6
+ ART = ['0:1', '4:3'].freeze
7
+
8
+ # classe permite analizar/processar videos para arquivo uniformizado
9
+ class Video
10
+ # processa video - somente se necessario
11
+ def processa
12
+ return if ivideo? || opastas?
13
+
14
+ work(cmd_mpeg("#{ops[:d][0]}/#{ops[:i]}/#{ops[:o]}/#{bas.downcase}"))
15
+ end
16
+
17
+ # executa/mostra comando mpeg
18
+ # @param [String] cmd comando mpeg
19
+ def work(cmd)
20
+ if ops[:x]
21
+ puts("processar #{inout}")
22
+ system(cmd)
23
+ else
24
+ puts(cmd)
25
+ end
26
+ end
27
+
28
+ # @return [String] params video inicial & comando mpeg
29
+ def inout
30
+ "#{bas}#{ishow} OUT: #{fparams}"
31
+ end
32
+
33
+ # @return [true, false] video inicial ok
34
+ def ivideo?
35
+ return false if ext != '.mp4' || iaudio.positive? || ibitrate >= 3000 || iheight <= 480
36
+
37
+ puts("mv #{inome} #{onome} #{ishow}")
38
+ true
39
+ end
40
+
41
+ # @return [true, false] video final ok
42
+ def ovideo?
43
+ oinit
44
+ return false if Video.to_t(otempo, 5) != Video.to_t(itempo, 5) || obitrate >= 3000 || oheight < 480
45
+
46
+ puts("rm #{inome} #{oshow}")
47
+ true
48
+ end
49
+
50
+ # @return [true, false] pastas com video final ok
51
+ def opastas?
52
+ ary = ops[:d]
53
+ if pos == ary.size then false
54
+ elsif ovideo? then true
55
+ else
56
+ # proxima pasta
57
+ @pos += 1
58
+ opastas?
59
+ end
60
+ end
61
+
62
+ # @return [String] parametros do comando processar video
63
+ def fparams
64
+ # frame rate & bitrate & dimensions & aspect ratio
65
+ "-r #{[ifps, 25.0].min} -b:v #{[ibitrate, 2000].min}k#{fdimensions}#{fratio}"
66
+ end
67
+
68
+ # @note final video dimensions hd480=852x480, hd720=1280x720, hd1080=1920x1080
69
+ # @return [String] dimensions do comando processar video
70
+ def fdimensions
71
+ if iheight < 480 then ' -s hd480'
72
+ elsif iheight <= 720 then ' -s hd720'
73
+ else ' -s hd1080'
74
+ end
75
+ end
76
+
77
+ # @return [String] aspect ratio do comando processar video
78
+ def fratio
79
+ ART.include?(iratio) ? " -aspect 16:9 -filter:v 'pad=max(iw\\,ih*16/9):ih:(ow-iw)/2:(oh-ih)/2'" : ''
80
+ end
81
+
82
+ # @return [String] cortes inicio video & duracao do video final processado
83
+ def fcuts
84
+ ict = Integer(ops[:s])
85
+ fct = Integer(ops[:t])
86
+ "#{ict.positive? ? " -ss #{ict}" : ''}#{fct.positive? ? " -t #{fct}" : ''}"
87
+ end
88
+
89
+ # @param [String] ficheiro video
90
+ # @return [String] comando probe
91
+ def cmd_prob(ficheiro)
92
+ "ffprobe -hide_banner -show_streams #{ficheiro} 2>&1|grep -v title"
93
+ end
94
+
95
+ # @param [String] base ficheiro video final
96
+ # @return [String] comando mpeg
97
+ def cmd_mpeg(base)
98
+ oout = "#{base}.out"
99
+ "ffmpeg -loglevel quiet -hide_banner -i #{inome} -y -an #{fparams}#{fcuts} "\
100
+ '-metadata title= -metadata artist= -metadata comment= -metadata major_brand= -metadata compatible_brands= '\
101
+ "#{base}.mp4 >#{oout} 2>&1;[ -s #{oout} ] || rm #{oout}"
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ # (see Evideo)
4
+ module Evideo
5
+ # parametros video :tempo, :bitrate - Duration: 01:01:08.50, start: 0.000000, bitrate: 2228 kb/s
6
+ RE1 = /duration:\s+(\d\d:\d\d:\d\d).*bitrate:\s+(\d+)\s+kb/i.freeze
7
+ # parametros video :height, :fps -
8
+ # Stream #0:0: Video: h264 (Main), yuv420p(tv, bt709, progressive), 1280x720
9
+ # [SAR 1:1 DAR 16:9], 23.98 fps, 23.98 tbr, 1k tbn, 180k tbc (default)
10
+ RE2 = /stream.*video:.*x\s*(\d+).*\s+(\d+\.*\d*)\s+fps/i.freeze
11
+ # parametros video :ratio - display_aspect_ratio=16:9
12
+ RE3 = /display_aspect_ratio\s*=\s*(\d+:\d+)$/i.freeze
13
+ # parametros video :audio - Stream #0:1(eng): Audio: aac (LC), 48000 Hz, stereo, fltp (default)
14
+ RE4 = /stream.*audio:.*\s+(\d+)\s+hz/i.freeze
15
+
16
+ # permite analizar string output do comando sonda video
17
+ class Video
18
+ # @return [String] base ficheiro video
19
+ attr_reader :bas
20
+ # @return [String] extensao ficheiro video
21
+ attr_reader :ext
22
+ # @return [Thor::CoreExt::HashWithIndifferentAccess] opcoes trabalho
23
+ attr_reader :ops
24
+
25
+ # @param [String] ficheiro video a processar
26
+ # @param [Thor::CoreExt::HashWithIndifferentAccess] opcoes trabalho
27
+ # @option opcoes [Array<String>] :d (/home/eu/lust,/media/eu/hrv2,/media/eu/hrv2/lust) pastas onde procurar videos
28
+ # @option opcoes [String] :i (ftv) pasta inicial dos videos
29
+ # @option opcoes [String] :o (out) pasta final dos videos
30
+ # @option opcoes [Boolean] :s (false) 10 segundos cortados no inicio do video final
31
+ # @option opcoes [Integer] :t (0) segundos duracao video final 0=sem cortes
32
+ # @return [Video] videos processados para arquivo uniformizado
33
+ def initialize(ficheiro, opcoes)
34
+ @ext = File.extname(ficheiro)
35
+ @bas = File.basename(ficheiro, ext)
36
+ @ops = opcoes
37
+ @iopcao = {}
38
+ end
39
+
40
+ # @return [String] texto probe do video inicial
41
+ def iprobe
42
+ @iprobe ||= `#{cmd_prob(inome)}`
43
+ end
44
+
45
+ # @return [Array<String>] parametros video inicial [:tempo, :bitrate]
46
+ def i1scan
47
+ @i1scan ||= iprobe.scan(RE1).flatten
48
+ end
49
+
50
+ # @return [Array<String>] parametros video inicial [:height, :fps]
51
+ def i2scan
52
+ @i2scan ||= iprobe.scan(RE2).flatten
53
+ end
54
+
55
+ # @return [String] parametro video inicial :tempo hh:mm:ss
56
+ def itempo
57
+ @iopcao[:tempo] ||= (i1scan[0] || '00:00:00')
58
+ end
59
+
60
+ # @return [Integer] parametro video inicial :bitrate kb/s
61
+ def ibitrate
62
+ @iopcao[:bitrate] ||= Integer(i1scan[1] || 0)
63
+ end
64
+
65
+ # @return [Integer] parametro video inicial :height
66
+ def iheight
67
+ @iopcao[:height] ||= Integer(i2scan[0] || 0)
68
+ end
69
+
70
+ # @return [Float] parametro video inicial :fps frame_rate
71
+ def ifps
72
+ @iopcao[:fps] ||= Float(i2scan[1] || 0)
73
+ end
74
+
75
+ # @return [String] parametro video inicial aspect :ratio 16:9
76
+ def iratio
77
+ @iopcao[:ratio] ||= (iprobe.scan(RE3).flatten[0] || '0:1')
78
+ end
79
+
80
+ # @return [Integer] parametro video inicial :audio Hz
81
+ def iaudio
82
+ @iopcao[:audio] ||= Integer(iprobe.scan(RE4).flatten[0] || 0)
83
+ end
84
+
85
+ # @return [String] ficheiro inicial absoluto
86
+ def inome
87
+ "#{ops[:d][0]}/#{ops[:i]}/#{bas}#{ext}"
88
+ end
89
+
90
+ # @return [String] mostra dados do ficheiro video inicial
91
+ def ishow
92
+ "# r:#{ibitrate} h:#{iheight} #{iratio}"
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'time'
4
+
5
+ # (see Evideo)
6
+ module Evideo
7
+ # permite analizar string output do comando sonda video
8
+ class Video
9
+ # @return [Time] tempo no ruby standard library com precisao
10
+ def self.to_t(tempo, pre = 8)
11
+ Time.parse(tempo[0, pre])
12
+ end
13
+
14
+ # inicia variaveis do video final
15
+ def oinit
16
+ @oopcao = {}
17
+ @oprobe = nil
18
+ @o1scan = nil
19
+ @o2scan = nil
20
+ end
21
+
22
+ # @return [String] texto probe do video final
23
+ def oprobe
24
+ return '' unless File.exist?(onome)
25
+
26
+ @oprobe ||= `#{cmd_prob(onome)}`
27
+ end
28
+
29
+ # @return [Array<String>] parametros video final [:tempo, :bitrate]
30
+ def o1scan
31
+ @o1scan ||= oprobe.scan(RE1).flatten
32
+ end
33
+
34
+ # @return [Array<String>] parametros video final [:height, :fps]
35
+ def o2scan
36
+ @o2scan ||= oprobe.scan(RE2).flatten
37
+ end
38
+
39
+ # @return [String] parametro video final :tempo hh:mm:ss
40
+ def otempo
41
+ @oopcao[:tempo] ||= (o1scan[0] || '00:00:00')
42
+ end
43
+
44
+ # @return [Integer] parametro video final :bitrate kb/s
45
+ def obitrate
46
+ @oopcao[:bitrate] ||= Integer(o1scan[1] || 0)
47
+ end
48
+
49
+ # @return [Integer] parametro video final :height
50
+ def oheight
51
+ @oopcao[:height] ||= Integer(o2scan[0] || 0)
52
+ end
53
+
54
+ # @return [Float] parametro video final :fps frame_rate
55
+ def ofps
56
+ @oopcao[:fps] ||= Float(o2scan[1] || 0)
57
+ end
58
+
59
+ # @return [String] parametro video final aspect :ratio 16:9
60
+ def oratio
61
+ @oopcao[:ratio] ||= (oprobe.scan(RE3).flatten[0] || '0:1')
62
+ end
63
+
64
+ # @return [Integer] posicao array pastas onde procurar videos finais
65
+ def pos
66
+ # -1 #{ops[:d][0]}/#{ops[:i]}/#{ops[:o]}"
67
+ # 0 #{ops[:d][pos]}/#{ops[:o]}"
68
+ # 1 #{ops[:d][pos]}/#{ops[:o]}"
69
+ @pos ||= -1
70
+ end
71
+
72
+ # @return [String] video final absoluto
73
+ def onome
74
+ dir = ops[:d]
75
+ (pos == -1 ? "#{dir[0]}/#{ops[:i]}" : dir[pos]) + "/#{ops[:o]}/#{bas.downcase}.mp4"
76
+ end
77
+
78
+ # @return [String] mostra dados do ficheiro video final
79
+ def oshow
80
+ "# r:#{obitrate} h:#{oheight} #{oratio} #{ops[:d][pos]}/#{ops[:o]}"
81
+ end
82
+ end
83
+ end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # analizar/processar videos para arquivo uniformizado
3
4
  module Evideo
4
- VERSION = '0.2.4'
5
+ VERSION = '0.2.9'
5
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: evideo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.2.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hernâni Rodrigues Vaz
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-08-02 00:00:00.000000000 Z
11
+ date: 2021-06-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -38,6 +38,62 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: reek
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: rubocop
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
+ - !ruby/object:Gem::Dependency
70
+ name: solargraph
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: yard
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
41
97
  - !ruby/object:Gem::Dependency
42
98
  name: thor
43
99
  requirement: !ruby/object:Gem::Requirement
@@ -63,6 +119,8 @@ extensions: []
63
119
  extra_rdoc_files: []
64
120
  files:
65
121
  - ".gitignore"
122
+ - ".rubocop.yml"
123
+ - ".travis.yml"
66
124
  - Gemfile
67
125
  - Gemfile.lock
68
126
  - LICENSE.txt
@@ -74,8 +132,9 @@ files:
74
132
  - exe/ev
75
133
  - exe/evideo
76
134
  - lib/evideo.rb
77
- - lib/evideo/hrvideo.rb
78
- - lib/evideo/hrvprocessa.rb
135
+ - lib/evideo/processa.rb
136
+ - lib/evideo/vars1.rb
137
+ - lib/evideo/vars2.rb
79
138
  - lib/evideo/version.rb
80
139
  homepage: https://github.com/hernanilr/evideo
81
140
  licenses:
@@ -89,16 +148,16 @@ require_paths:
89
148
  - lib
90
149
  required_ruby_version: !ruby/object:Gem::Requirement
91
150
  requirements:
92
- - - ">="
151
+ - - "~>"
93
152
  - !ruby/object:Gem::Version
94
- version: '0'
153
+ version: '2.7'
95
154
  required_rubygems_version: !ruby/object:Gem::Requirement
96
155
  requirements:
97
156
  - - ">="
98
157
  - !ruby/object:Gem::Version
99
158
  version: '0'
100
159
  requirements: []
101
- rubygems_version: 3.1.2
160
+ rubygems_version: 3.1.4
102
161
  signing_key:
103
162
  specification_version: 4
104
163
  summary: Processa ficheiros video.
@@ -1,93 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Evideo
4
- # permite analizar string output do comando sonda video
5
- class HRVideo
6
- # @return [String] nome do ficheiro video
7
- attr_reader :nome
8
- # @return [String] extensao do ficheiro video
9
- attr_reader :ext
10
- # @return [String] base do ficheiro video
11
- attr_reader :base
12
- # @return [String] duracao do ficheiro video
13
- attr_reader :tempo
14
- # @return [String] bitrate do ficheiro video
15
- attr_reader :bitrate
16
-
17
- # Duration: 01:01:08.50, start: 0.000000, bitrate: 2228 kb/s
18
- R1 = /duration:\s+(\d\d:\d\d:\d\d).*bitrate:\s+(\d+)\s+kb/i.freeze
19
- # Stream #0:0: Video: h264 (Main), yuv420p(tv, bt709, progressive), 1280x720
20
- # [SAR 1:1 DAR 16:9], 23.98 fps, 23.98 tbr, 1k tbn, 180k tbc (default)
21
- R2 = /stream.*video:.*x\s*(\d+).*\s+(\d+\.*\d*)\s+fps/i.freeze
22
- # display_aspect_ratio=16:9
23
- R3 = /display_aspect_ratio\s*=\s*(\d+:\d+)$/i.freeze
24
- # Stream #0:1(eng): Audio: aac (LC), 48000 Hz, stereo, fltp (default)
25
- # Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 127 kb/s (default)
26
- R4 = /stream.*audio:.*\s+(\d+)\s+hz/i.freeze
27
-
28
- def initialize(fil)
29
- @nome = fil
30
- @ext = File.extname(fil)
31
- @base = File.basename(fil, @ext).downcase
32
- @tempo = '00:00:00'
33
- @bitrate = 0
34
- @probe = `#{cmd_probe}` if File.exist?(fil)
35
- return unless @probe
36
-
37
- tr1 = @probe.scan(R1).flatten
38
- @tempo = tr1[0].to_s
39
- @bitrate = tr1[1].to_i
40
- end
41
-
42
- # Parametrizar height e frame rate
43
- def r2
44
- return unless @probe
45
-
46
- tr2 = @probe.scan(R2).flatten
47
- @height = tr2[0].to_i
48
- @fps = tr2[1].to_f
49
- end
50
-
51
- # Parametrizar aspect ratio
52
- def r3
53
- return unless @probe
54
-
55
- @ratio = @probe.scan(R3).flatten[0]
56
- end
57
-
58
- # Parametrizar audio
59
- def r4
60
- return unless @probe
61
-
62
- @audio = @probe.scan(R4).flatten[0].to_i
63
- end
64
-
65
- # @return [String] audio
66
- def audio
67
- r4 unless @audio
68
-
69
- @audio
70
- end
71
-
72
- # @return [String] height
73
- def height
74
- r2 unless @height
75
-
76
- @height
77
- end
78
-
79
- # @return [String] frame rate
80
- def fps
81
- r2 unless @fps
82
-
83
- @fps
84
- end
85
-
86
- # @return [String] aspect ratio
87
- def ratio
88
- r3 unless @ratio
89
-
90
- @ratio
91
- end
92
- end
93
- end
@@ -1,131 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'time'
4
-
5
- module Evideo
6
- # permite analizar/processar videos para arquivo
7
- class HRVideo
8
- # @return [String] tempo: rate:
9
- def show
10
- return nome unless @probe
11
-
12
- "tempo: #{tempo} rate: #{bitrate} ratio: #{ratio} height: #{height}"
13
- end
14
-
15
- # Testa validade video original
16
- #
17
- # @param [String] aot pasta destino dos videos absoluta
18
- # @return [true, false] sim ou nao video original esta ok
19
- def ofok?(aot)
20
- return false unless processa_of?
21
-
22
- puts "mv \"#{nome} #{aot}/#{base}.mp4\" # #{show}"
23
- true
24
- end
25
-
26
- # @return [true, false] video original precisa ser processado?
27
- def processa_of?
28
- # prossecar somente videos grandes (>1 min) ou extensao errada ou bitrate >= 3000
29
- ((bitrate < 3000 && ext == '.mp4') || Time.parse(tempo) < Time.parse('00:01:00')) &&
30
- # prossecar somente videos com ratio, height, audio errados
31
- ratio == '16:9' && height > 480 && audio.zero?
32
- end
33
-
34
- # Testa validade video processado contra video original
35
- #
36
- # @param [String] hrv video processado a testar validade
37
- # @return [true, false] sim ou nao video esta ok
38
- def vfok?(hrv)
39
- return false unless File.exist?(hrv.nome) && hrv.bitrate < 3000 && Time.parse(hrv.tempo) > Time.parse(tempo) - 60
40
-
41
- puts "rm \"#{nome}\" # #{hrv.nome} #{hrv.show}"
42
- true
43
- end
44
-
45
- # Testa validade videos processados em todos locais contra video original
46
- #
47
- # @param [Array<String>] ary array locais onde procurar videos
48
- # @param [String] pot pasta destino dos videos
49
- # @return [true, false] sim ou nao <local>/<video> esta ok
50
- def vdok?(ary, pot)
51
- if ary.empty? then false
52
- elsif vfok?(HRVideo.new("#{ary.first}/#{pot}/#{base}.mp4")) then true
53
- else vdok?(ary.drop(1), pot)
54
- end
55
- end
56
-
57
- # @return [String] aspect ratio comando conversao
58
- def aspect
59
- if ratio == '0:1' then height < 720 ? '' : ' -aspect 16:9'
60
- else " -aspect #{ratio}"
61
- end
62
- end
63
-
64
- # @return [String] video dimensions comando conversao
65
- def dimension
66
- if height < 480 then ' -s hd480'
67
- elsif height <= 720 then ' -s hd720'
68
- else ' -s hd1080'
69
- end
70
- end
71
-
72
- # @return [String] comando analise
73
- def cmd_probe
74
- "ffprobe -hide_banner -show_streams \"#{nome}\" 2>&1|grep -v title"
75
- end
76
-
77
- # Comando para processar videos
78
- #
79
- # @param [String] tempo do video processado
80
- # @return [String] comando conversao
81
- def cmd_mpeg(tempo)
82
- puts "processar #{base}.mp4 " + join_opcoes
83
- "ffmpeg #{geral} -i \"#{nome}\" -y -an " + join_opcoes +
84
- ' -metadata title= -metadata artist= -metadata comment= -metadata major_brand= -metadata compatible_brands=' +
85
- # para teste produz somente segundos
86
- tempo
87
- end
88
-
89
- # @return [String] opcoes para trabalho framerate & bitrate & dimenssoes
90
- def join_opcoes
91
- "-r #{[fps, 25].min} -b:v #{[bitrate, 2000].min}k" + dimension + aspect
92
- end
93
-
94
- # @return [String] opcoes gerais comando conversao
95
- def geral
96
- '-loglevel quiet -hide_banner' +
97
- # para ignorar segundos no inicio
98
- # ' -ss 15' \
99
- ''
100
- end
101
-
102
- # Processa videos
103
- #
104
- # @param [Hash] opcoes parametrizacao
105
- # @option opcoes [Array<String>] :d locais onde procurar videos
106
- # @option opcoes [<String>] :i pasta origem dos videos
107
- # @option opcoes [<String>] :o pasta destino dos videos
108
- # @option opcoes [<Boolean>] :t processa somente segundos para teste
109
- # @param [String] aot pasta destino dos videos absoluta
110
- def processa(opcoes, aot)
111
- return if ofok?(aot) || vdok?(opcoes[:d], opcoes[:o])
112
-
113
- system cmd_mpeg(opcoes[:t] ? ' -t 20' : '') + " #{aot}/#{base}.mp4"
114
- vfok?(HRVideo.new("#{aot}/#{base}.mp4"))
115
- end
116
-
117
- # Testa videos
118
- #
119
- # @param [Hash] opcoes parametrizacao
120
- # @option opcoes [Array<String>] :d locais onde procurar videos
121
- # @option opcoes [<String>] :i pasta origem dos videos
122
- # @option opcoes [<String>] :o pasta destino dos videos
123
- # @option opcoes [<Boolean>] :t processa somente segundos para teste
124
- # @param [String] aot pasta destino dos videos absoluta
125
- def testa(opcoes, aot)
126
- return if ofok?(aot) || vdok?(opcoes[:d], opcoes[:o])
127
-
128
- puts "ls -lh \"#{nome}\" # #{show}"
129
- end
130
- end
131
- end