evideo 0.2.4 → 0.2.5

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: 7f5c77658b5bcd0344f7eff6ab91922381d9d49eccd003b29244b363c9b43502
4
+ data.tar.gz: b19c5ff8dd141e15cb19c41f2ea0a927a3c3d773b64ffe4a4e99c52f1d8d5556
5
5
  SHA512:
6
- metadata.gz: 7bb0acee95ef8a2307bdc1b525d82293fca925bc94cd8031dfa860affddeb40b6e52cca607f6315dacc343cf0b89ca79125112fe075d33a1cb7a1a36c1cfeb7b
7
- data.tar.gz: a7803cb72e5ff2105c3939deb56960babafba44fce72f26e9001e0191ca27b549110c8e87b1f556e725d10a3461f5792ade603f33646753d34a337c0c16307b0
6
+ metadata.gz: 62f8ae5efa2db98752f862eec528ef809efd86c76ac71117bfcffeeaaebee104a5af7cf9cf6f26cb9d2660f3ad04d7880bd38ee784ce1a371efd0d2c2307ca4b
7
+ data.tar.gz: e618be2769fce85c76319c7c72e5b7612164892a5a85e7e9d01a658a188249dfc47abed78af3e4fb355f16b1eabacb17f650af81bcdccd8600fe033de65fefe4
@@ -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.4)
4
+ evideo (0.2.5)
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,9 @@ DEPENDENCIES
17
70
  bundler
18
71
  evideo!
19
72
  rake
73
+ reek
74
+ rubocop
75
+ solargraph
20
76
 
21
77
  BUNDLED WITH
22
- 2.1.2
78
+ 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
@@ -5,15 +5,16 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
5
  require 'evideo/version'
6
6
 
7
7
  Gem::Specification.new do |spec|
8
- spec.name = 'evideo'
9
- spec.version = Evideo::VERSION
10
- spec.authors = ['Hernâni Rodrigues Vaz']
11
- spec.email = ['hernanirvaz@gmail.com']
12
- spec.homepage = 'https://github.com/hernanilr/evideo'
13
- spec.license = 'MIT'
8
+ spec.name = 'evideo'
9
+ spec.version = Evideo::VERSION
10
+ spec.authors = ['Hernâni Rodrigues Vaz']
11
+ spec.email = ['hernanirvaz@gmail.com']
12
+ spec.homepage = 'https://github.com/hernanilr/evideo'
13
+ spec.license = 'MIT'
14
+ spec.required_ruby_version = '~> 2.7'
14
15
 
15
16
  spec.summary = 'Processa ficheiros video.'
16
- spec.description = spec.summary + ' Pode alterar bitrate, framerate, height, aspect ratio e elimina metadata.'
17
+ spec.description = "#{spec.summary} Pode alterar bitrate, framerate, height, aspect ratio e elimina metadata."
17
18
 
18
19
  spec.metadata['homepage_uri'] = spec.homepage
19
20
  spec.metadata['yard.run'] = 'yard'
@@ -21,15 +22,19 @@ Gem::Specification.new do |spec|
21
22
  # Specify which files should be added to the gem when it is released.
22
23
  # The `git ls-files -z` loads the files in the RubyGem that have been
23
24
  # 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
25
+ spec.files =
26
+ Dir.chdir(File.expand_path(__dir__)) do
27
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
28
+ end
27
29
  spec.bindir = 'exe'
28
30
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
29
31
  spec.require_paths = ['lib']
30
32
 
31
- spec.add_development_dependency 'bundler'
32
- spec.add_development_dependency 'rake'
33
+ spec.add_development_dependency('bundler')
34
+ spec.add_development_dependency('rake')
35
+ spec.add_development_dependency('reek')
36
+ spec.add_development_dependency('rubocop')
37
+ spec.add_development_dependency('solargraph')
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)
@@ -1,45 +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, 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'
17
19
 
18
20
  desc 'conv', 'converte videos'
19
- option :t, type: :boolean, default: false, desc: 'Processa somente segundos para teste'
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
20
25
  def conv
21
- Dir.glob("#{fin}/*.???").sort.each do |f|
22
- 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
23
31
  end
24
32
  end
25
33
 
26
34
  desc 'test', 'testa videos'
35
+ # testa videos
27
36
  def test
28
- Dir.glob("#{fin}/*.???").sort.each do |f|
29
- HRVideo.new(f).testa(options, fout)
37
+ Dir.glob("#{ipasta}/*.???").sort.each do |file|
38
+ puts(Video.new(file, options).inout)
30
39
  end
31
40
  end
32
41
 
33
42
  default_task :test
34
43
  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]}"
44
+ # @return [String] pasta absoluta inicial dos videos
45
+ def ipasta
46
+ "#{options[:d][0]}/#{options[:i]}"
43
47
  end
44
48
  end
45
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.4'
5
+ VERSION = '0.2.5'
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.5
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: 2020-10-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -38,6 +38,48 @@ 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'
41
83
  - !ruby/object:Gem::Dependency
42
84
  name: thor
43
85
  requirement: !ruby/object:Gem::Requirement
@@ -63,6 +105,8 @@ extensions: []
63
105
  extra_rdoc_files: []
64
106
  files:
65
107
  - ".gitignore"
108
+ - ".rubocop.yml"
109
+ - ".travis.yml"
66
110
  - Gemfile
67
111
  - Gemfile.lock
68
112
  - LICENSE.txt
@@ -74,8 +118,9 @@ files:
74
118
  - exe/ev
75
119
  - exe/evideo
76
120
  - lib/evideo.rb
77
- - lib/evideo/hrvideo.rb
78
- - lib/evideo/hrvprocessa.rb
121
+ - lib/evideo/processa.rb
122
+ - lib/evideo/vars1.rb
123
+ - lib/evideo/vars2.rb
79
124
  - lib/evideo/version.rb
80
125
  homepage: https://github.com/hernanilr/evideo
81
126
  licenses:
@@ -89,9 +134,9 @@ require_paths:
89
134
  - lib
90
135
  required_ruby_version: !ruby/object:Gem::Requirement
91
136
  requirements:
92
- - - ">="
137
+ - - "~>"
93
138
  - !ruby/object:Gem::Version
94
- version: '0'
139
+ version: '2.7'
95
140
  required_rubygems_version: !ruby/object:Gem::Requirement
96
141
  requirements:
97
142
  - - ">="
@@ -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