evideo 0.2.2 → 0.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c167bf3e8d3a7e66297b1b7aaa54b1c75ab45d7830dd7a98a215b711b258719d
4
- data.tar.gz: 47d61465595f915dc5657d86ba7b7416c127e5c54c6d65d0603b30e97a992e38
3
+ metadata.gz: 14df3f51ddcb3878e84f2f7eda9492c15bb0105303594bc191e9f35e9ac42c6e
4
+ data.tar.gz: 29b0e163690a9f43821bcada3c71d1cf876146c953e80df4d2025eeb76648ef9
5
5
  SHA512:
6
- metadata.gz: af6cbfe169434a52e054a749a24abc48dee8b78643d1850decc1da5be6178cef76fcf611afe96b211a2a8b0aae3753a4411cd3ccac958461372cb74330d602a6
7
- data.tar.gz: 5d5f53bf1264207abb9e66e8cbacddcd467dc282f9d3c3c52814f07e2dc670b70bd5a9a568d52e68f6488bc8da746ae126faf7ba609b0f05df2059c6188108ec
6
+ metadata.gz: 7c1ccf7f13e1072c27abc3c9d1f86e993f52711636c87e9849eece3ad20ce894a8c1ca9ca450e06f9aee044554f6ea91a09c36ffbe5ee5284feb91d2fb4a2b09
7
+ data.tar.gz: 03654ea2c6c21db1cc29d3d90bc8ea815cbba26688f8e5e1151520c15f9409faf073cef1bd64853b8f8fdaba48bbd342805589ea5dccabc71cbc1de7207ebb02
@@ -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.2)
4
+ evideo (0.2.7)
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.1)
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}/*.???").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}/*.???").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,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.2'
5
+ VERSION = '0.2.7'
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.2
4
+ version: 0.2.7
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-23 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