libis-format 1.2.9 → 1.3.2
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 +4 -4
- data/Gemfile +4 -0
- data/bin/{pdf_copy → pdf_tool} +3 -2
- data/data/types.yml +1 -1
- data/lib/libis/format/command_line.rb +2 -3
- data/lib/libis/format/config.rb +17 -20
- data/lib/libis/format/converter/base.rb +9 -16
- data/lib/libis/format/converter/chain.rb +36 -28
- data/lib/libis/format/converter/email_converter.rb +5 -8
- data/lib/libis/format/converter/fop_pdf_converter.rb +4 -6
- data/lib/libis/format/converter/image_converter.rb +51 -58
- data/lib/libis/format/converter/jp2_converter.rb +33 -35
- data/lib/libis/format/converter/office_converter.rb +19 -23
- data/lib/libis/format/converter/pdf_converter.rb +133 -52
- data/lib/libis/format/converter/repository.rb +7 -13
- data/lib/libis/format/converter/spreadsheet_converter.rb +7 -11
- data/lib/libis/format/converter/video_converter.rb +41 -55
- data/lib/libis/format/converter/xslt_converter.rb +14 -13
- data/lib/libis/format/converter.rb +1 -1
- data/lib/libis/format/identifier.rb +41 -43
- data/lib/libis/format/tool/droid.rb +29 -30
- data/lib/libis/format/tool/ff_mpeg.rb +11 -13
- data/lib/libis/format/tool/fido.rb +1 -1
- data/lib/libis/format/tool/pdf_optimizer.rb +21 -27
- data/lib/libis/format/tool/pdf_to_pdfa.rb +2 -6
- data/lib/libis/format/tool/pdf_tool.rb +52 -0
- data/lib/libis/format/tool/pdfa_validator.rb +2 -3
- data/lib/libis/format/tool/spreadsheet_to_ods.rb +23 -20
- data/lib/libis/format/tool.rb +2 -2
- data/lib/libis/format/type_database.rb +51 -28
- data/lib/libis/format/type_database_impl.rb +57 -24
- data/lib/libis/format/version.rb +1 -1
- data/lib/libis/format.rb +3 -2
- data/lib/libis-format.rb +2 -0
- data/tools/PdfTool.jar +0 -0
- data/tools/pdfbox/pdfbox-app-3.0.3.jar +0 -0
- data/tools/pdfbox/{preflight-app-2.0.13.jar → preflight-app-3.0.3.jar} +0 -0
- metadata +8 -10
- data/lib/libis/format/tool/pdf_copy.rb +0 -57
- data/lib/libis/format/tool/pdf_merge.rb +0 -58
- data/lib/libis/format/tool/pdf_split.rb +0 -56
- data/tools/pdfbox/pdfbox-app-2.0.13.jar +0 -0
@@ -1,9 +1,9 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative 'base'
|
4
4
|
|
5
5
|
require 'libis/tools/extend/hash'
|
6
|
-
require 'libis/format/tool/
|
6
|
+
require 'libis/format/tool/pdf_tool'
|
7
7
|
require 'libis/format/tool/pdf_to_pdfa'
|
8
8
|
require 'libis/format/tool/pdfa_validator'
|
9
9
|
require 'libis/format/tool/pdf_optimizer'
|
@@ -11,20 +11,19 @@ require 'libis/format/tool/pdf_optimizer'
|
|
11
11
|
module Libis
|
12
12
|
module Format
|
13
13
|
module Converter
|
14
|
-
|
15
14
|
class PdfConverter < Libis::Format::Converter::Base
|
16
|
-
|
17
15
|
def self.input_types
|
18
16
|
[:PDF]
|
19
17
|
end
|
20
18
|
|
21
19
|
def self.output_types(format = nil)
|
22
20
|
return [] unless input_types.include?(format)
|
23
|
-
|
21
|
+
|
22
|
+
%i[PDF PDFA]
|
24
23
|
end
|
25
24
|
|
26
25
|
def pdf_convert(_)
|
27
|
-
#force usage of this converter
|
26
|
+
# force usage of this converter
|
28
27
|
end
|
29
28
|
|
30
29
|
# Set metadata for Pdf file
|
@@ -40,15 +39,15 @@ module Libis
|
|
40
39
|
def metadata(values = {})
|
41
40
|
values.key_strings_to_symbols!
|
42
41
|
values.each do |k, v|
|
43
|
-
next unless [
|
44
|
-
@options[
|
42
|
+
next unless %i[title author creator keywords subject].include?(k)
|
43
|
+
(@options[:metadata] ||= {})[k] = v
|
45
44
|
end
|
46
45
|
end
|
47
46
|
|
48
47
|
# Select a partial list of pages
|
49
48
|
# @param [String] selection as described in com.itextpdf.text.pdf.SequenceList: [!][o][odd][e][even]start-end
|
50
49
|
def range(selection)
|
51
|
-
@options[:
|
50
|
+
@options[:select] = {range: [selection].flatten.compact.join(',')}
|
52
51
|
end
|
53
52
|
|
54
53
|
# Create or use a watermark image.
|
@@ -56,10 +55,12 @@ module Libis
|
|
56
55
|
# The watermark options are (use symbols):
|
57
56
|
# - text: text to create a watermark from
|
58
57
|
# - file: watermark image to use
|
58
|
+
# - image: same as above
|
59
59
|
# - rotation: rotation of the watermark text (in degrees; integer number)
|
60
60
|
# - size: font size of the watermark text
|
61
61
|
# - opacity: opacity of the watermark (fraction 0.0 - 1.0)
|
62
|
-
# - gap: size of the gap between watermark instances. Integer value is absolute size in points (1/72 inch).
|
62
|
+
# - gap: size of the gap between watermark instances. Integer value is absolute size in points (1/72 inch).
|
63
|
+
# Fractions are percentage of widht/height.
|
63
64
|
# If both options are given, the file will be used as-is if it exists and is a valid image file. Otherwise the
|
64
65
|
# file will be created or overwritten with a newly created watermark image.
|
65
66
|
#
|
@@ -69,16 +70,56 @@ module Libis
|
|
69
70
|
# @param [Hash] options Hash of options for watermark creation.
|
70
71
|
def watermark(options = {})
|
71
72
|
options.key_strings_to_symbols!
|
72
|
-
if options[:file]
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
73
|
+
if options[:file] || options[:image]
|
74
|
+
watermark_image(options)
|
75
|
+
elsif options[:text]
|
76
|
+
watermark_text(options)
|
77
|
+
elsif options[:banner]
|
78
|
+
watermark_banner(options)
|
78
79
|
end
|
79
|
-
|
80
|
-
|
81
|
-
|
80
|
+
end
|
81
|
+
|
82
|
+
def watermark_image(options = {})
|
83
|
+
options.key_strings_to_symbols!
|
84
|
+
@options[:watermark] = {command: 'image'}
|
85
|
+
@options[:watermark][:data] = options[:file] || options[:image]
|
86
|
+
@options[:watermark][:opacity] = options[:opacity] || '0.3'
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
def watermark_text(options = {})
|
91
|
+
options.key_strings_to_symbols!
|
92
|
+
@options[:watermark] = {command: 'text'}
|
93
|
+
@options[:watermark][:data] = (options[:text] || '© LIBIS').split('\n')
|
94
|
+
@options[:watermark][:rotation] = options[:rotation] if options[:rotation]
|
95
|
+
@options[:watermark][:size] = options[:size] if options[:size]
|
96
|
+
@options[:watermark][:gap] = options[:gap] if options[:gap].to_s =~ /^\s*\d+\s*$/
|
97
|
+
@options[:watermark][:padding] = options[:gap] if options[:gap].to_s =~ /^\s*(0+\.\d+|1\.0+)\s*$/
|
98
|
+
@options[:watermark][:padding] = options[:padding] if options[:padding]
|
99
|
+
@options[:watermark][:opacity] = options[:opacity] || '0.3'
|
100
|
+
end
|
101
|
+
|
102
|
+
# Create a vertical banner to the right side of each page
|
103
|
+
#
|
104
|
+
# The banner options are:
|
105
|
+
# - banner: text to put in the banner
|
106
|
+
# - add_filename: append filename to the text (use any value to enable)
|
107
|
+
# - fontsize: size of the font (in points)
|
108
|
+
# - width: width of the banner
|
109
|
+
# - (background|text)_color_(red|green|blue): color components of background and text
|
110
|
+
def watermark_banner(options = {})
|
111
|
+
options.key_strings_to_symbols!
|
112
|
+
@options[:watermark] = {command: 'banner'}
|
113
|
+
@options[:watermark][:data] = (options[:banner] || '© LIBIS')
|
114
|
+
@options[:watermark][:add_filename] = !!options[:add_filename]
|
115
|
+
@options[:watermark][:size] = options[:fontsize] if options[:fontsize]
|
116
|
+
@options[:watermark][:width] = options[:width] if options[:width]
|
117
|
+
@options[:watermark][:background_red] = options[:background_color_red] if options[:background_color_red]
|
118
|
+
@options[:watermark][:background_green] = options[:background_color_green] if options[:background_color_green]
|
119
|
+
@options[:watermark][:background_blue] = options[:background_color_blue] if options[:background_color_blue]
|
120
|
+
@options[:watermark][:text_red] = options[:text_color_red] if options[:text_color_red]
|
121
|
+
@options[:watermark][:text_green] = options[:text_color_green] if options[:text_color_green]
|
122
|
+
@options[:watermark][:text_blue] = options[:text_color_blue] if options[:text_color_blue]
|
82
123
|
end
|
83
124
|
|
84
125
|
# Optimize the PDF
|
@@ -88,7 +129,7 @@ module Libis
|
|
88
129
|
#
|
89
130
|
# - 0 : lowest quality (Acrobat Distiller 'Screen Optimized' equivalent)
|
90
131
|
# - 1 : medium quality (Acrobat Distiller 'eBook' equivalent)
|
91
|
-
# - 2 : good quality
|
132
|
+
# - 2 : good quality (Acrobat Distiller 'Default' equivalent)
|
92
133
|
# - 3 : high quality (Acrobat Distiller 'Print Optimized' equivalent)
|
93
134
|
# - 4 : highest quality (Acrobat Distiller 'Prepress Optimized' equivalent)
|
94
135
|
#
|
@@ -96,7 +137,7 @@ module Libis
|
|
96
137
|
#
|
97
138
|
# @param [Integer] setting quality setting. [0-4]
|
98
139
|
def optimize(setting = 1)
|
99
|
-
@options[
|
140
|
+
@options[:optimize] = %w[screen ebook default printer prepress][setting] if (0..4).include?(setting)
|
100
141
|
end
|
101
142
|
|
102
143
|
def convert(source, target, format, opts = {})
|
@@ -104,84 +145,124 @@ module Libis
|
|
104
145
|
|
105
146
|
result = nil
|
106
147
|
|
107
|
-
|
108
|
-
result =
|
109
|
-
return nil unless result
|
148
|
+
unless @options.empty?
|
149
|
+
result = convert_pdf(source, target)
|
110
150
|
source = result
|
111
151
|
end
|
112
152
|
|
113
|
-
|
114
|
-
result =
|
115
|
-
return nil unless result
|
153
|
+
if source && (quality = @options.delete(:optimize))
|
154
|
+
result = optimize_pdf(source, target, quality)
|
116
155
|
source = result
|
117
156
|
end
|
118
157
|
|
119
|
-
if format == :PDFA
|
158
|
+
if source && (format == :PDFA)
|
120
159
|
result = pdf_to_pdfa(source, target)
|
121
160
|
end
|
122
161
|
|
123
|
-
{
|
162
|
+
{
|
124
163
|
files: [result],
|
125
164
|
converter: self.class.name
|
126
165
|
}
|
127
|
-
|
128
166
|
end
|
129
167
|
|
130
|
-
|
168
|
+
protected
|
131
169
|
|
170
|
+
def optimize_pdf(source, target, quality)
|
132
171
|
using_temp(target) do |tmpname|
|
133
172
|
result = Libis::Format::Tool::PdfOptimizer.run(source, tmpname, quality)
|
134
|
-
unless result[:
|
173
|
+
unless result[:err].empty?
|
135
174
|
error("Pdf optimization encountered errors:\n%s", (result[:err] + result[:out]).join("\n"))
|
136
|
-
|
175
|
+
return nil
|
137
176
|
end
|
138
177
|
tmpname
|
139
178
|
end
|
140
179
|
end
|
141
180
|
|
142
181
|
def convert_pdf(source, target)
|
182
|
+
result = source
|
183
|
+
result = add_watermark(result, target, @options[:watermark]) if @options[:watermark]
|
184
|
+
result = add_metadata(result, target, @options[:metadata]) if @options[:metadata]
|
185
|
+
result = select_range(result, target, @options[:select]) if @options[:select]
|
186
|
+
return result
|
187
|
+
end
|
188
|
+
|
189
|
+
def options_to_args(options)
|
190
|
+
options.map do |k, v|
|
191
|
+
key = "--#{k.to_s.tr_s('_', '-')}"
|
192
|
+
value = v
|
193
|
+
case value
|
194
|
+
when TrueClass
|
195
|
+
value = nil
|
196
|
+
when FalseClass
|
197
|
+
value = key = nil
|
198
|
+
when Array
|
199
|
+
value = value.map(&:to_s)
|
200
|
+
else
|
201
|
+
value = v.to_s
|
202
|
+
end
|
203
|
+
[key, value]
|
204
|
+
end.flatten.compact
|
205
|
+
end
|
206
|
+
|
207
|
+
def add_watermark(source, target, options)
|
208
|
+
command = options.delete(:command)
|
209
|
+
data = [options.delete(:data)].flatten.compact
|
210
|
+
args = data + options_to_args(options)
|
211
|
+
|
212
|
+
using_temp(target) do |tmpname|
|
213
|
+
result = Libis::Format::Tool::PdfTool.run(['watermark', command], source, tmpname, *args)
|
214
|
+
unless result[:err].empty?
|
215
|
+
error("Pdf watermarking encountered errors:\n%s", result[:err].join(join("\n")))
|
216
|
+
return nil
|
217
|
+
end
|
218
|
+
tmpname
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
def add_metadata(source, target, options)
|
223
|
+
args = options_to_args(options)
|
143
224
|
|
144
225
|
using_temp(target) do |tmpname|
|
145
|
-
result = Libis::Format::Tool::
|
146
|
-
source, tmpname,
|
147
|
-
@options.map {|k, v|
|
148
|
-
if v.nil?
|
149
|
-
nil
|
150
|
-
else
|
151
|
-
["--#{k}", (v.is_a?(Array) ? v : v.to_s)]
|
152
|
-
end}.flatten
|
153
|
-
)
|
226
|
+
result = Libis::Format::Tool::PdfTool.run('metadata', source, tmpname, *args)
|
154
227
|
unless result[:err].empty?
|
155
|
-
error("Pdf
|
156
|
-
|
228
|
+
error("Pdf metadata encountered errors:\n%s", result[:err].join(join("\n")))
|
229
|
+
return nil
|
157
230
|
end
|
158
231
|
tmpname
|
159
232
|
end
|
233
|
+
end
|
234
|
+
|
235
|
+
def select_range(source, target, options)
|
236
|
+
args = options_to_args(options)
|
160
237
|
|
238
|
+
using_temp(target) do |tmpname|
|
239
|
+
result = Libis::Format::Tool::PdfTool.run('select', source, tmpname, *args)
|
240
|
+
unless result[:err].empty?
|
241
|
+
error("Pdf select encountered errors:\n%s", result[:err].join(join("\n")))
|
242
|
+
return nil
|
243
|
+
end
|
244
|
+
tmpname
|
245
|
+
end
|
161
246
|
end
|
162
247
|
|
163
248
|
def pdf_to_pdfa(source, target)
|
164
|
-
|
165
249
|
using_temp(target) do |tmpname|
|
166
250
|
result = Libis::Format::Tool::PdfToPdfa.run source, tmpname
|
167
251
|
|
168
|
-
|
169
|
-
error("Pdf/A conversion encountered errors:\n%s", (result[:
|
170
|
-
|
252
|
+
unless result[:status].zero?
|
253
|
+
error("Pdf/A conversion encountered errors:\n%s", (result[:out] + result[:err]).join("\n"))
|
254
|
+
return nil
|
171
255
|
else
|
172
256
|
r = Libis::Format::Tool::PdfaValidator.run tmpname
|
173
257
|
if r[:status] != 0
|
174
258
|
error "Pdf/A file failed to validate with following errors:\n%s", (r[:err] || r[:out] || []).join("\n")
|
175
|
-
|
259
|
+
return nil
|
176
260
|
end
|
177
261
|
end
|
178
262
|
tmpname
|
179
263
|
end
|
180
|
-
|
181
264
|
end
|
182
|
-
|
183
265
|
end
|
184
|
-
|
185
266
|
end
|
186
267
|
end
|
187
268
|
end
|
@@ -1,6 +1,5 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'set'
|
4
3
|
require 'singleton'
|
5
4
|
|
6
5
|
require 'libis/tools/logger'
|
@@ -11,7 +10,6 @@ require_relative 'chain'
|
|
11
10
|
module Libis
|
12
11
|
module Format
|
13
12
|
module Converter
|
14
|
-
|
15
13
|
class Repository
|
16
14
|
include Singleton
|
17
15
|
include ::Libis::Tools::Logger
|
@@ -24,15 +22,15 @@ module Libis
|
|
24
22
|
@converters_glob = File.join(File.dirname(__FILE__), '*_converter.rb')
|
25
23
|
end
|
26
24
|
|
27
|
-
def
|
25
|
+
def self.register(converter_class)
|
28
26
|
instance.converters.add? converter_class
|
29
27
|
end
|
30
28
|
|
31
|
-
def
|
29
|
+
def self.get_converters # rubocop:disable Naming/AccessorMethodName
|
32
30
|
instance.get_converters
|
33
31
|
end
|
34
32
|
|
35
|
-
def get_converters
|
33
|
+
def get_converters # rubocop:disable Naming/AccessorMethodName
|
36
34
|
if converters.empty?
|
37
35
|
Dir.glob(converters_glob).each do |filename|
|
38
36
|
# noinspection RubyResolve
|
@@ -42,12 +40,12 @@ module Libis
|
|
42
40
|
converters
|
43
41
|
end
|
44
42
|
|
45
|
-
def
|
43
|
+
def self.get_converter_chain(src_type, tgt_type, operations = {})
|
46
44
|
instance.get_converter_chain src_type, tgt_type, operations
|
47
45
|
end
|
48
46
|
|
49
47
|
def get_converter_chain(src_type, tgt_type, operations = {})
|
50
|
-
msg = "conversion from #{src_type
|
48
|
+
msg = "conversion from #{src_type} to #{tgt_type}"
|
51
49
|
chain_list = find_chains src_type, tgt_type, operations
|
52
50
|
# if chain_list.length > 1
|
53
51
|
# warn "Found more than one conversion chain for #{msg}. Picking the first one."
|
@@ -70,7 +68,6 @@ module Libis
|
|
70
68
|
end
|
71
69
|
|
72
70
|
def build_chains(chain)
|
73
|
-
|
74
71
|
found = []
|
75
72
|
chains = [chain]
|
76
73
|
|
@@ -81,18 +78,15 @@ module Libis
|
|
81
78
|
new_chains += chains.map { |c| c.append(converter) }.flatten
|
82
79
|
end
|
83
80
|
|
84
|
-
found = new_chains.select
|
81
|
+
found = new_chains.select(&:valid?)
|
85
82
|
return found unless found.empty?
|
86
83
|
|
87
84
|
chains = new_chains
|
88
85
|
end
|
89
86
|
|
90
87
|
found
|
91
|
-
|
92
88
|
end
|
93
|
-
|
94
89
|
end
|
95
|
-
|
96
90
|
end
|
97
91
|
end
|
98
92
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative 'base'
|
4
4
|
|
@@ -8,35 +8,31 @@ require 'libis/format/type_database'
|
|
8
8
|
module Libis
|
9
9
|
module Format
|
10
10
|
module Converter
|
11
|
-
|
12
11
|
class SpreadsheetConverter < Libis::Format::Converter::Base
|
13
|
-
|
14
12
|
def self.input_types
|
15
|
-
[
|
16
|
-
|
17
|
-
|
18
|
-
|
13
|
+
%i[
|
14
|
+
MSXLS
|
15
|
+
MSXLSX
|
16
|
+
OO_CALC
|
19
17
|
]
|
20
18
|
end
|
21
19
|
|
22
20
|
def self.output_types(format = nil)
|
23
21
|
return [] unless input_types.include?(format)
|
22
|
+
|
24
23
|
[:OO_CALC]
|
25
24
|
end
|
26
25
|
|
27
26
|
def spreadsheet_convert(_)
|
28
|
-
#force usage of this converter
|
27
|
+
# force usage of this converter
|
29
28
|
end
|
30
29
|
|
31
30
|
def convert(source, target, format, opts = {})
|
32
31
|
super
|
33
32
|
|
34
33
|
Format::Tool::SpreadsheetToOds.run(source, target)
|
35
|
-
|
36
34
|
end
|
37
|
-
|
38
35
|
end
|
39
|
-
|
40
36
|
end
|
41
37
|
end
|
42
38
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'base'
|
2
4
|
require 'libis/format/tool/ff_mpeg'
|
3
5
|
|
@@ -6,24 +8,19 @@ require 'fileutils'
|
|
6
8
|
module Libis
|
7
9
|
module Format
|
8
10
|
module Converter
|
9
|
-
|
10
11
|
class VideoConverter < Libis::Format::Converter::Base
|
11
|
-
|
12
12
|
def self.input_types
|
13
|
-
[
|
13
|
+
%i[WEBM MP4 MPG MKV MJP2 QTFF AVI OGGV WMV DV FLV SWF]
|
14
14
|
end
|
15
15
|
|
16
16
|
def self.output_types(format = nil)
|
17
17
|
return [] unless input_types.include?(format)
|
18
|
-
[:GIF, :WEBM, :MP4, :MPG, :MKV, :MJP2, :QTFF, :AVI, :OGGV, :WMV, :DV, :FLV, :SWF]
|
19
|
-
end
|
20
18
|
|
21
|
-
|
22
|
-
super
|
19
|
+
%i[GIF WEBM MP4 MPG MKV MJP2 QTFF AVI OGGV WMV DV FLV SWF]
|
23
20
|
end
|
24
21
|
|
25
|
-
def quiet(
|
26
|
-
@flags[:quiet] = !!
|
22
|
+
def quiet(value)
|
23
|
+
@flags[:quiet] = !!value
|
27
24
|
end
|
28
25
|
|
29
26
|
def format(format)
|
@@ -126,10 +123,10 @@ module Libis
|
|
126
123
|
|
127
124
|
# @param [Boolean] value If set to true automatically selects optimal format for web viewing. Default: false
|
128
125
|
def web_stream(value)
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
126
|
+
return unless value
|
127
|
+
|
128
|
+
@options[:video_codec] = 'h264'
|
129
|
+
@options[:audio_codec] = 'acc'
|
133
130
|
end
|
134
131
|
|
135
132
|
# @param [String] name name of a preset. See FFMpeg documentation for more info
|
@@ -170,7 +167,7 @@ module Libis
|
|
170
167
|
|
171
168
|
elsif File.directory?(source)
|
172
169
|
|
173
|
-
sources = Dir[File.join(source, '**', '*')].reject {|p| File.directory? p}
|
170
|
+
sources = Dir[File.join(source, '**', '*')].reject { |p| File.directory? p }
|
174
171
|
assemble_and_convert(sources, target)
|
175
172
|
|
176
173
|
else
|
@@ -183,14 +180,13 @@ module Libis
|
|
183
180
|
files: [target],
|
184
181
|
converter: self.class.name
|
185
182
|
}
|
186
|
-
|
187
183
|
end
|
188
184
|
|
189
185
|
def assemble_and_convert(sources, target)
|
190
|
-
Tempfile.create(%w
|
191
|
-
sources.each {|src| f.puts src}
|
186
|
+
Tempfile.create(%w[list .txt]) do |f|
|
187
|
+
sources.each { |src| f.puts src }
|
192
188
|
opts[:global] ||= []
|
193
|
-
opts[:global] += %w
|
189
|
+
opts[:global] += %w[-f concat]
|
194
190
|
f.close
|
195
191
|
target = convert_file(f.to_path, target)
|
196
192
|
end
|
@@ -201,15 +197,15 @@ module Libis
|
|
201
197
|
|
202
198
|
def convert_file(source, target)
|
203
199
|
# FLV special: only supports aac and speex audio codecs
|
204
|
-
format = (@options[:format] || File.extname(target)[1
|
205
|
-
@options[:audio_codec] ||= 'aac' if %w
|
200
|
+
format = (@options[:format] || File.extname(target)[1..]).to_s.downcase
|
201
|
+
@options[:audio_codec] ||= 'aac' if %w[flv].include?(format)
|
206
202
|
|
207
203
|
# SWF special: only supports mp3 audio codec
|
208
|
-
format = (@options[:format] || File.extname(target)[1
|
209
|
-
@options[:audio_codec] ||= 'mp3' if %w
|
204
|
+
format = (@options[:format] || File.extname(target)[1..]).to_s.downcase
|
205
|
+
@options[:audio_codec] ||= 'mp3' if %w[swf].include?(format)
|
210
206
|
|
211
207
|
# Set up FFMpeg command line parameters
|
212
|
-
opts = {global: [], input: [], filter: [], output: []}
|
208
|
+
opts = { global: [], input: [], filter: [], output: [] }
|
213
209
|
opts[:global] << '-hide_banner'
|
214
210
|
opts[:global] << '-loglevel' << (@options[:quiet] ? 'fatal' : 'warning')
|
215
211
|
|
@@ -217,29 +213,21 @@ module Libis
|
|
217
213
|
@options[:watermark_opacity] ||= 0.5
|
218
214
|
if @options[:watermark_image]
|
219
215
|
opts[:filter] << '-i' << @options[:watermark_image] << '-filter_complex'
|
220
|
-
opts[:filter] <<
|
221
|
-
|
216
|
+
opts[:filter] << Kernel.format('[1:v]format=argb,colorchannelmixer=aa=%f[wm];[0:v][wm]overlay=%s',
|
217
|
+
@options[:watermark_opacity], watermark_position_text)
|
222
218
|
elsif @options[:watermark_text]
|
223
219
|
@options[:watermark_text_size] ||= 10
|
224
220
|
@options[:watermark_text_color] ||= 'white'
|
225
221
|
@options[:watermark_text_shadow_color] ||= 'black'
|
226
222
|
@options[:watermark_text_shadow_offset] ||= 1
|
227
|
-
filter_text = "drawtext=text='%s':%s:fontfile=%s:fontsize=%d:fontcolor=%s@%f"
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
]
|
236
|
-
filter_text += ':shadowcolor=%s@%f:shadowx=%d:shadowy=%d' %
|
237
|
-
[
|
238
|
-
@options[:watermark_text_shadow_color],
|
239
|
-
@options[:watermark_opacity],
|
240
|
-
@options[:watermark_text_shadow_offset],
|
241
|
-
@options[:watermark_text_shadow_offset]
|
242
|
-
] if @options[:watermark_text_shadow_offset] > 0
|
223
|
+
filter_text = Kernel.format("drawtext=text='%s':%s:fontfile=%s:fontsize=%d:fontcolor=%s@%f",
|
224
|
+
@options[:watermark_text], watermark_position_text(true), Config[:watermark_font],
|
225
|
+
@options[:watermark_text_size], @options[:watermark_text_color], @options[:watermark_opacity])
|
226
|
+
if (@options[:watermark_text_shadow_offset]).positive?
|
227
|
+
filter_text += Kernel.format(':shadowcolor=%s@%f:shadowx=%d:shadowy=%d',
|
228
|
+
@options[:watermark_text_shadow_color], @options[:watermark_opacity],
|
229
|
+
@options[:watermark_text_shadow_offset], @options[:watermark_text_shadow_offset])
|
230
|
+
end
|
243
231
|
opts[:filter] << '-vf' << filter_text
|
244
232
|
end
|
245
233
|
opts[:output] << '-ac' << @options[:audio_channels] if @options[:audio_channels]
|
@@ -251,7 +239,7 @@ module Libis
|
|
251
239
|
opts[:output] << '-map_metadata:g' << '0:g' # Copy global metadata
|
252
240
|
opts[:output] << '-map_metadata:s:a' << '0:s:a' # Copy audio metadata
|
253
241
|
opts[:output] << '-map_metadata:s:v' << '0:s:v' # Copy video metadata
|
254
|
-
opts[:input] << '-accurate_seek' << (@options[:start].to_i
|
242
|
+
opts[:input] << '-accurate_seek' << (@options[:start].to_i.negative? ? '-sseof' : '-ss') << @options[:start] if @options[:start]
|
255
243
|
opts[:input] << '-t' << @options[:duration] if @options[:duration]
|
256
244
|
opts[:output] << '-qscale' << @options[:video_quality] if @options[:video_quality]
|
257
245
|
opts[:output] << '-q:a' << @options[:audio_quality] if @options[:audio_quality]
|
@@ -277,21 +265,19 @@ module Libis
|
|
277
265
|
w = for_text ? 'tw' : 'w'
|
278
266
|
h = for_text ? 'th' : 'h'
|
279
267
|
case @options[:watermark_position]
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
268
|
+
when 'bottom_left'
|
269
|
+
"x=#{margin}:y=H-#{h}-#{margin}"
|
270
|
+
when 'top_left'
|
271
|
+
"x=#{margin}:y=#{margin}"
|
272
|
+
when 'bottom_right'
|
273
|
+
"x=W-#{w}-#{margin}:y=H-#{h}-#{margin}"
|
274
|
+
when 'top_right'
|
275
|
+
"x=W-#{w}-#{margin}:y=#{margin}"
|
276
|
+
else
|
277
|
+
"x=#{margin}:y=H-#{h}-#{margin}"
|
290
278
|
end
|
291
279
|
end
|
292
|
-
|
293
280
|
end
|
294
|
-
|
295
281
|
end
|
296
282
|
end
|
297
|
-
end
|
283
|
+
end
|