-
Notifications
You must be signed in to change notification settings - Fork 164
Expand file tree
/
Copy pathdetect-crop.rb
More file actions
137 lines (113 loc) · 2.86 KB
/
detect-crop.rb
File metadata and controls
137 lines (113 loc) · 2.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#!/usr/bin/env ruby
#
# detect-crop.rb
#
# Copyright (c) 2025 Lisa Melton
#
require 'English'
require 'open3'
require 'optparse'
require 'tempfile'
module Cropping
class UsageError < RuntimeError
end
class Command
def about
<<-HERE
detect-crop.rb 2025.01.28
Copyright (c) 2025 Lisa Melton
HERE
end
def usage
<<-HERE
Detect unused outside area of video tracks.
Usage: #{File.basename($PROGRAM_NAME)} [OPTION]... [FILE]...
Prints TOP:BOTTOM:LEFT:RIGHT crop values to standard output
Options:
-m, --mode auto|conservative
set crop mode (default: conservative)
-h, --help display this help and exit
--version output version information and exit
Requires `HandBrakeCLI`.
HERE
end
def initialize
@input_count = 0
@mode = 'conservative'
end
def run
begin
OptionParser.new do |opts|
define_options opts
opts.on '-h', '--help' do
puts usage
exit
end
opts.on '--version' do
puts about
exit
end
end.parse!
rescue OptionParser::ParseError => e
raise UsageError, e
end
fail UsageError, 'missing argument' if ARGV.empty?
@input_count = ARGV.count
ARGV.each { |arg| process_input arg }
exit
rescue UsageError => e
Kernel.warn "#{$PROGRAM_NAME}: #{e}"
Kernel.warn "Try `#{File.basename($PROGRAM_NAME)} --help` for more information."
exit false
rescue StandardError => e
Kernel.warn "#{$PROGRAM_NAME}: #{e}"
exit(-1)
rescue SignalException
puts
exit(-1)
end
def define_options(opts)
opts.on '--debug' do
@debug = true
end
opts.on '-m', '--mode ARG' do |arg|
@mode = case arg
when 'auto', 'conservative'
arg
else
fail UsageError, "unsupported crop mode: #{arg}"
end
end
end
def process_input(path)
output = Tempfile.new('detect-crop')
begin
unused, info, status = Open3.capture3(
'HandBrakeCLI',
'--input', path,
'--output', output.path,
'--format', 'av_mkv',
'--stop-at', 'seconds:1',
'--crop-mode', @mode,
'--encoder', 'x265_10bit',
'--encoder-preset', 'ultrafast',
'--audio', '0'
)
fail "scanning media failed: #{path}" unless status.exitstatus == 0
ensure
output.close
output.unlink
end
crop = '0:0:0:0'
info.each_line do |line|
next unless line.valid_encoding?
if line =~ %r{, crop \((\d+/\d+/\d+/\d+)\): }
crop = $1.gsub('/', ':')
break
end
end
puts crop + (@input_count > 1 ? ",\"#{path.gsub(/"/, '""')}\"" : '')
end
end
end
Cropping::Command.new.run