libis-format 1.2.9 → 1.3.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|