evideo 0.2.1 → 0.2.6

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: ebefc113933dc1cc99fab42d3aecd5b907231b2bcf70d9364572305e303a5554
4
- data.tar.gz: e68bd951fd8912ceea23ec54a4a3774f2234ae505e6b065e9c20b3bd9ed18fcd
3
+ metadata.gz: 3e95f6fe9a764eccbe36b8c5728b9f942c363dcb449374d968bff61ded18bca0
4
+ data.tar.gz: c39b511c469f058761eefc4cd29c2534c4b95beeb5d15215b8782ebbfb5ac58e
5
5
  SHA512:
6
- metadata.gz: e8690ca607ae90682154d61498c1236aa4f1433527c07be0dd4b0a73c7b7a3f2c04f3e5804e033ead09b49ccb9aa39469466a284c65a897e2e4bbcff4bddfd10
7
- data.tar.gz: f03bea64673a278436199ba8c623a57d84448103e277cfeda18e9532485bb70e44441f9015149d2b8cea5536e8066660efd07715f202a2552caa6ea8df40b50a
6
+ metadata.gz: c272a8c11fe29e35f1e30d8d582ae1601ff0c4cfd2d14ddb832687b20bc40f28854afc5126771b318d7591155403360929e04a8031ddd806eac95210d10ecfb1
7
+ data.tar.gz: 18a35fcbde99a6e45819be875443848c7a0b15a584e4efcc3db2d48236338cdfc05afde7f0b9c1b15160836877555d551d2ff0be1577db58636e45e07d161cb0
@@ -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
@@ -0,0 +1,6 @@
1
+ ---
2
+ sudo: false
3
+ language: ruby
4
+ cache: bundler
5
+ rvm:
6
+ - 2.7.0
@@ -1,14 +1,67 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- evideo (0.2.1)
4
+ evideo (0.2.6)
5
5
  thor
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
+ ast (2.4.1)
11
+ backport (1.1.2)
12
+ benchmark (0.1.0)
13
+ e2mmap (0.1.0)
14
+ jaro_winkler (1.5.4)
15
+ kwalify (0.7.2)
16
+ maruku (0.7.3)
17
+ mini_portile2 (2.4.0)
18
+ nokogiri (1.10.10)
19
+ mini_portile2 (~> 2.4.0)
20
+ parallel (1.19.2)
21
+ parser (2.7.2.0)
22
+ ast (~> 2.4.1)
23
+ psych (3.2.0)
24
+ rainbow (3.0.0)
10
25
  rake (13.0.1)
26
+ reek (6.0.2)
27
+ kwalify (~> 0.7.0)
28
+ parser (>= 2.5.0.0, < 2.8, != 2.5.1.1)
29
+ psych (~> 3.1)
30
+ rainbow (>= 2.0, < 4.0)
31
+ regexp_parser (1.8.2)
32
+ reverse_markdown (2.0.0)
33
+ nokogiri
34
+ rexml (3.2.4)
35
+ rubocop (0.93.1)
36
+ parallel (~> 1.10)
37
+ parser (>= 2.7.1.5)
38
+ rainbow (>= 2.2.2, < 4.0)
39
+ regexp_parser (>= 1.8)
40
+ rexml
41
+ rubocop-ast (>= 0.6.0)
42
+ ruby-progressbar (~> 1.7)
43
+ unicode-display_width (>= 1.4.0, < 2.0)
44
+ rubocop-ast (1.0.0)
45
+ parser (>= 2.7.1.5)
46
+ ruby-progressbar (1.10.1)
47
+ solargraph (0.39.17)
48
+ backport (~> 1.1)
49
+ benchmark
50
+ bundler (>= 1.17.2)
51
+ e2mmap
52
+ jaro_winkler (~> 1.5)
53
+ maruku (~> 0.7, >= 0.7.3)
54
+ nokogiri (~> 1.9, >= 1.9.1)
55
+ parser (~> 2.3)
56
+ reverse_markdown (>= 1.0.5, < 3)
57
+ rubocop (~> 0.52)
58
+ thor (~> 1.0)
59
+ tilt (~> 2.0)
60
+ yard (~> 0.9, >= 0.9.24)
11
61
  thor (1.0.1)
62
+ tilt (2.0.10)
63
+ unicode-display_width (1.7.0)
64
+ yard (0.9.25)
12
65
 
13
66
  PLATFORMS
14
67
  ruby
@@ -17,6 +70,10 @@ DEPENDENCIES
17
70
  bundler
18
71
  evideo!
19
72
  rake
73
+ reek
74
+ rubocop
75
+ solargraph
76
+ yard
20
77
 
21
78
  BUNDLED WITH
22
- 2.1.2
79
+ 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
@@ -11,28 +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 +
17
- ' Pode alterar bitrate, framerate, height,' \
18
- ' aspect ratio e elimina metadata.'
15
+ spec.description = "#{spec.summary} Pode alterar bitrate, framerate, height, aspect ratio e elimina metadata."
19
16
 
17
+ spec.required_ruby_version = Gem::Requirement.new('~> 2.7')
20
18
  spec.metadata['homepage_uri'] = spec.homepage
21
- spec.metadata['yard.run'] = 'yard'
19
+ spec.metadata['yard.run'] = 'yard'
22
20
 
23
21
  # Specify which files should be added to the gem when it is released.
24
22
  # The `git ls-files -z` loads the files in the RubyGem that have been
25
23
  # added into git.
26
- spec.files = Dir.chdir(File.expand_path(__dir__)) do
27
- `git ls-files -z`.split("\x0")
28
- .reject { |f| f.match(%r{^(test|spec|features)/}) }
29
- 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
30
28
  spec.bindir = 'exe'
31
29
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
32
30
  spec.require_paths = ['lib']
33
31
 
34
- spec.add_development_dependency 'bundler'
35
- 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')
36
38
 
37
- spec.add_dependency 'thor'
39
+ spec.add_dependency('thor')
38
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)
@@ -1,46 +1,49 @@
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,
14
- default: ["/home/#{ID}/lust", "/media/#{ID}/hrv2"],
15
- desc: 'Onde procurar videos'
16
- class_option :i, banner: 'IN', default: 'ftv', desc: 'Pasta origem'
17
- 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
+
18
20
  desc 'conv', 'converte videos'
19
- option :t, type: :boolean, default: false, desc: 'Processa somente segundos para teste'
20
- # Processa videos
21
+ option :x, type: :boolean, default: false, desc: 'executa/mostra comando converte videos'
22
+ option :s, type: :numeric, default: 0, desc: 'Segundos cortados no inicio do video final 0=sem cortes'
23
+ option :t, type: :numeric, default: 0, desc: 'Segundos duracao video final 0=sem cortes'
24
+ # converte videos
21
25
  def conv
22
- Dir.glob("#{fin}/c*.???").sort.each do |f|
23
- HRVideo.new(f).processa(options, fout)
26
+ # cria pasta final para videos processados
27
+ system("mkdir -p #{ipasta}/#{options[:o]}")
28
+
29
+ Dir.glob("#{ipasta}/*.???").sort.each do |file|
30
+ Video.new(file, options).processa
24
31
  end
25
32
  end
26
33
 
27
34
  desc 'test', 'testa videos'
28
- # Analisa videos
35
+ # testa videos
29
36
  def test
30
- Dir.glob("#{fin}/c*.???").sort.each do |f|
31
- HRVideo.new(f).testa(options, fout)
37
+ Dir.glob("#{ipasta}/*.???").sort.each do |file|
38
+ puts(Video.new(file, options).inout)
32
39
  end
33
40
  end
34
- default_task :conv
35
- no_commands do
36
- # @return [String] pasta absoluta origem dos videos
37
- def fin
38
- "#{options[:d].first}/#{options[:i]}"
39
- end
40
41
 
41
- # @return [String] pasta absoluta destino dos videos
42
- def fout
43
- "#{options[:d].first}/#{options[:o]}"
42
+ default_task :test
43
+ no_commands do
44
+ # @return [String] pasta absoluta inicial dos videos
45
+ def ipasta
46
+ "#{options[:d][0]}/#{options[:i]}"
44
47
  end
45
48
  end
46
49
  end
@@ -0,0 +1,103 @@
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
+ # @return [String] dimensions do comando processar video
69
+ def fdimensions
70
+ if iheight < 480 then ' -s hd480'
71
+ elsif iheight <= 720 then ' -s hd720'
72
+ else ' -s hd1080'
73
+ end
74
+ end
75
+
76
+ # @return [String] aspect ratio do comando processar video
77
+ def fratio
78
+ ART.include?(iratio) ? " -aspect 16:9 -filter:v 'pad=ih*16/9:ih:(ow-iw)/2:(oh-ih)/2'" : ''
79
+ end
80
+
81
+ # @return [String] cortes inicio video & duracao do video final processado
82
+ def fcuts
83
+ ict = Integer(ops[:s])
84
+ fct = Integer(ops[:t])
85
+ "#{ict.positive? ? " -ss #{ict}" : ''}#{fct.positive? ? " -t #{fct}" : ''}"
86
+ end
87
+
88
+ # @param [String] ficheiro video
89
+ # @return [String] comando probe
90
+ def cmd_prob(ficheiro)
91
+ "ffprobe -hide_banner -show_streams #{ficheiro} 2>&1|grep -v title"
92
+ end
93
+
94
+ # @param [String] base ficheiro video final
95
+ # @return [String] comando mpeg
96
+ def cmd_mpeg(base)
97
+ oout = "#{base}.out"
98
+ "ffmpeg -loglevel quiet -hide_banner -i #{inome} -y -an #{fparams}#{fcuts} "\
99
+ '-metadata title= -metadata artist= -metadata comment= -metadata major_brand= -metadata compatible_brands= '\
100
+ "#{base}.mp4 >#{oout} 2>&1;[ -s #{oout} ] || rm #{oout}"
101
+ end
102
+ end
103
+ 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.1'
5
+ VERSION = '0.2.6'
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.1
4
+ version: 0.2.6
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-07-20 00:00:00.000000000 Z
11
+ date: 2020-10-22 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,9 +148,9 @@ 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
  - - ">="
@@ -1,95 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Evideo
4
- # permite analizar string output do comando sonda video
5
- class HRVideo < String
6
- # @return [String] nome do ficheiro video
7
- attr_reader :video
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 :duration
14
- # @return [String] bitrate do ficheiro video
15
- attr_reader :bitrate
16
- # @return [String] frequencia audio do ficheiro video
17
- attr_reader :audio
18
-
19
- # Duration: 01:01:08.50, start: 0.000000, bitrate: 2228 kb/s
20
- R1 = /duration:\s+(\d\d:\d\d:\d\d).*bitrate:\s+(\d+)\s+kb/i.freeze
21
- # Stream #0:0: Video: h264 (Main), yuv420p(tv, bt709, progressive), 1280x720
22
- # [SAR 1:1 DAR 16:9], 23.98 fps, 23.98 tbr, 1k tbn, 180k tbc (default)
23
- R2 = /stream.*video:.*x\s*(\d+).*\s+(\d+\.*\d*)\s+fps/i.freeze
24
- # display_aspect_ratio=16:9
25
- R3 = /display_aspect_ratio\s*=\s*(\d+:\d+)$/i.freeze
26
- # Stream #0:1(eng): Audio: aac (LC), 48000 Hz, stereo, fltp (default)
27
- # Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 127 kb/s (default)
28
- R4 = /stream.*audio:.*\s+(\d+)\s+hz/i.freeze
29
-
30
- def initialize(fvideo)
31
- @video = fvideo
32
- @ext = File.extname(fvideo)
33
- @base = File.basename(fvideo, @ext).downcase
34
- @duration = '00:00:00'
35
- @bitrate = 0
36
- @probe = `#{cmd_probe}` if File.exist?(fvideo)
37
- return unless @probe
38
-
39
- tr1 = @probe.scan(R1).flatten
40
- @duration = tr1[0].to_s
41
- @bitrate = tr1[1].to_i
42
- end
43
-
44
- # Parametrizar height e frame rate
45
- def r2
46
- return unless @probe
47
-
48
- tr2 = @probe.scan(R2).flatten
49
- @height = tr2[0].to_i
50
- @fps = tr2[1].to_f
51
- end
52
-
53
- # Parametrizar aspect ratio
54
- def r3
55
- return unless @probe
56
-
57
- @ratio = @probe.scan(R3).flatten[0]
58
- end
59
-
60
- # Parametrizar audio
61
- def r4
62
- return unless @probe
63
-
64
- @audio = @probe.scan(R4).flatten[0].to_i
65
- end
66
-
67
- # @return [String] audio
68
- def audio
69
- r4 unless @audio
70
-
71
- @audio
72
- end
73
-
74
- # @return [String] height
75
- def height
76
- r2 unless @height
77
-
78
- @height
79
- end
80
-
81
- # @return [String] frame rate
82
- def fps
83
- r2 unless @fps
84
-
85
- @fps
86
- end
87
-
88
- # @return [String] aspect ratio
89
- def ratio
90
- r3 unless @ratio
91
-
92
- @ratio
93
- end
94
- end
95
- end
@@ -1,125 +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 < String
8
- # @return [String] tempo: rate:
9
- def show
10
- return video unless @probe
11
-
12
- "tempo: #{duration} 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 esta ok
19
- def ofok?(aot)
20
- return false unless (bitrate < 3000 && ext == '.mp4') || Time.parse(duration) < Time.parse('00:01:00')
21
- return false unless ratio == '16:9' && height > 480
22
- return false unless audio == 0
23
-
24
- puts "mv \"#{video} #{aot}/#{base}.mp4\" # #{show}"
25
- true
26
- end
27
-
28
- # Testa validade video processado contra video original
29
- #
30
- # @param [String] file video processado a testar validade
31
- # @return [true, false] sim ou nao video esta ok
32
- def vfok?(file)
33
- return false unless File.exist?(file.video) &&
34
- file.bitrate < 3000 && Time.parse(file.duration) > Time.parse(duration) - 60
35
-
36
- puts "rm \"#{video}\" # #{file.video} #{file.show}"
37
- true
38
- end
39
-
40
- # Testa validade videos processados em todos locais contra video original
41
- #
42
- # @param [Array<String>] ary array locais onde procurar videos
43
- # @param [String] pot pasta destino dos videos
44
- # @return [true, false] sim ou nao <local>/<video> esta ok
45
- def vdok?(ary, pot)
46
- if ary.empty? then false
47
- elsif vfok?(HRVideo.new("#{ary.first}/#{pot}/#{base}.mp4")) then true
48
- else vdok?(ary.drop(1), pot)
49
- end
50
- end
51
-
52
- # @return [String] aspect ratio comando conversao
53
- def aspect
54
- if ratio == '0:1' then height < 720 ? '' : ' -aspect 16:9'
55
- else " -aspect #{ratio}"
56
- end
57
- end
58
-
59
- # @return [String] video dimensions comando conversao
60
- def dimension
61
- if height < 480 then ' -s hd480'
62
- elsif height <= 720 then ' -s hd720'
63
- else ' -s hd1080'
64
- end
65
- end
66
-
67
- # @return [String] comando analise
68
- def cmd_probe
69
- "ffprobe -hide_banner -show_streams \"#{video}\" 2>&1|grep -v title"
70
- end
71
-
72
- # Comando para processar videos
73
- #
74
- # @param [String] tempo do video processado
75
- # @return [String] comando conversao
76
- def cmd_mpeg(tempo)
77
- puts "processar #{base}.mp4 -r #{[fps, 25].min} -b:v #{[bitrate, 2000].min}k" + dimension + aspect + tempo
78
- "ffmpeg #{geral} -i \"#{video}\" -y -an " +
79
- # framerate & bitrate
80
- "-r #{[fps, 25].min} -b:v #{[bitrate, 2000].min}k" +
81
- dimension + aspect +
82
- ' -metadata title= -metadata artist= -metadata comment=' \
83
- ' -metadata major_brand= -metadata compatible_brands=' +
84
- # para teste produz somente segundos
85
- tempo
86
- end
87
-
88
- # @return [String] opcoes gerais comando conversao
89
- def geral
90
- '-loglevel quiet -hide_banner' +
91
- # para ignorar segundos no inicio
92
- # ' -ss 15' \
93
- ''
94
- end
95
-
96
- # Processa videos
97
- #
98
- # @param [Hash] opcoes parametrizacao
99
- # @option opcoes [Array<String>] :d locais onde procurar videos
100
- # @option opcoes [<String>] :i pasta origem dos videos
101
- # @option opcoes [<String>] :o pasta destino dos videos
102
- # @option opcoes [<Boolean>] :t processa somente segundos para teste
103
- # @param [String] aot pasta destino dos videos absoluta
104
- def processa(opcoes, aot)
105
- return if ofok?(aot) || vdok?(opcoes[:d], opcoes[:o])
106
-
107
- system cmd_mpeg(opcoes[:t] ? ' -t 20' : '') + " #{aot}/#{base}.mp4"
108
- vfok?(HRVideo.new("#{aot}/#{base}.mp4"))
109
- end
110
-
111
- # Testa videos
112
- #
113
- # @param [Hash] opcoes parametrizacao
114
- # @option opcoes [Array<String>] :d locais onde procurar videos
115
- # @option opcoes [<String>] :i pasta origem dos videos
116
- # @option opcoes [<String>] :o pasta destino dos videos
117
- # @option opcoes [<Boolean>] :t processa somente segundos para teste
118
- # @param [String] aot pasta destino dos videos absoluta
119
- def testa(opcoes, aot)
120
- return if ofok?(aot) || vdok?(opcoes[:d], opcoes[:o])
121
-
122
- puts "ls \"#{video}\" # #{show}"
123
- end
124
- end
125
- end