active_encode 0.4.1 → 0.8.0
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 +5 -5
- data/.circleci/config.yml +80 -0
- data/.rubocop.yml +9 -70
- data/.rubocop_todo.yml +68 -0
- data/CODE_OF_CONDUCT.md +36 -0
- data/CONTRIBUTING.md +23 -21
- data/Gemfile +5 -4
- data/LICENSE +11 -199
- data/README.md +135 -24
- data/SUPPORT.md +5 -0
- data/active_encode.gemspec +13 -3
- data/app/controllers/active_encode/encode_record_controller.rb +13 -0
- data/app/jobs/active_encode/polling_job.rb +1 -1
- data/app/models/active_encode/encode_record.rb +1 -0
- data/config/routes.rb +4 -0
- data/db/migrate/20180822021048_create_active_encode_encode_records.rb +1 -0
- data/db/migrate/20190702153755_add_create_options_to_active_encode_encode_records.rb +6 -0
- data/db/migrate/20190712174821_add_progress_to_active_encode_encode_records.rb +6 -0
- data/lib/active_encode.rb +1 -0
- data/lib/active_encode/base.rb +2 -2
- data/lib/active_encode/callbacks.rb +1 -0
- data/lib/active_encode/core.rb +4 -3
- data/lib/active_encode/engine.rb +1 -0
- data/lib/active_encode/engine_adapter.rb +1 -0
- data/lib/active_encode/engine_adapters.rb +4 -1
- data/lib/active_encode/engine_adapters/elastic_transcoder_adapter.rb +116 -38
- data/lib/active_encode/engine_adapters/ffmpeg_adapter.rb +141 -87
- data/lib/active_encode/engine_adapters/matterhorn_adapter.rb +5 -4
- data/lib/active_encode/engine_adapters/media_convert_adapter.rb +372 -0
- data/lib/active_encode/engine_adapters/media_convert_output.rb +104 -0
- data/lib/active_encode/engine_adapters/pass_through_adapter.rb +239 -0
- data/lib/active_encode/engine_adapters/test_adapter.rb +5 -4
- data/lib/active_encode/engine_adapters/zencoder_adapter.rb +3 -2
- data/lib/active_encode/errors.rb +6 -0
- data/lib/active_encode/global_id.rb +2 -1
- data/lib/active_encode/input.rb +3 -2
- data/lib/active_encode/output.rb +3 -2
- data/lib/active_encode/persistence.rb +11 -5
- data/lib/active_encode/polling.rb +3 -2
- data/lib/active_encode/spec/shared_specs.rb +2 -0
- data/{spec/shared_specs/engine_adapter_specs.rb → lib/active_encode/spec/shared_specs/engine_adapter.rb} +37 -38
- data/lib/active_encode/status.rb +1 -0
- data/lib/active_encode/technical_metadata.rb +3 -2
- data/lib/active_encode/version.rb +2 -1
- data/lib/file_locator.rb +93 -0
- data/spec/controllers/encode_record_controller_spec.rb +53 -0
- data/spec/fixtures/ffmpeg/cancelled-id/cancelled +0 -0
- data/spec/fixtures/file with space.low.mp4 +0 -0
- data/spec/fixtures/file with space.mp4 +0 -0
- data/spec/fixtures/fireworks.low.mp4 +0 -0
- data/spec/fixtures/media_convert/endpoints.json +1 -0
- data/spec/fixtures/media_convert/job_canceled.json +412 -0
- data/spec/fixtures/media_convert/job_canceling.json +1 -0
- data/spec/fixtures/media_convert/job_completed.json +359 -0
- data/spec/fixtures/media_convert/job_completed_detail.json +1 -0
- data/spec/fixtures/media_convert/job_completed_detail_query.json +1 -0
- data/spec/fixtures/media_convert/job_created.json +408 -0
- data/spec/fixtures/media_convert/job_failed.json +406 -0
- data/spec/fixtures/media_convert/job_progressing.json +414 -0
- data/spec/fixtures/pass_through/cancelled-id/cancelled +0 -0
- data/spec/fixtures/pass_through/cancelled-id/input_metadata +90 -0
- data/spec/fixtures/pass_through/completed-id/completed +0 -0
- data/spec/fixtures/pass_through/completed-id/input_metadata +102 -0
- data/spec/fixtures/pass_through/completed-id/output_metadata-high +90 -0
- data/spec/fixtures/pass_through/completed-id/output_metadata-low +90 -0
- data/spec/fixtures/pass_through/completed-id/video-high.mp4 +0 -0
- data/spec/fixtures/pass_through/completed-id/video-low.mp4 +0 -0
- data/spec/fixtures/pass_through/failed-id/error.log +1 -0
- data/spec/fixtures/pass_through/failed-id/input_metadata +90 -0
- data/spec/fixtures/pass_through/running-id/input_metadata +90 -0
- data/spec/integration/elastic_transcoder_adapter_spec.rb +63 -29
- data/spec/integration/ffmpeg_adapter_spec.rb +96 -24
- data/spec/integration/matterhorn_adapter_spec.rb +45 -44
- data/spec/integration/media_convert_adapter_spec.rb +126 -0
- data/spec/integration/pass_through_adapter_spec.rb +151 -0
- data/spec/integration/zencoder_adapter_spec.rb +210 -209
- data/spec/rails_helper.rb +1 -0
- data/spec/routing/encode_record_controller_routing_spec.rb +10 -0
- data/spec/spec_helper.rb +2 -2
- data/spec/test_app_templates/lib/generators/test_app_generator.rb +13 -12
- data/spec/units/callbacks_spec.rb +3 -2
- data/spec/units/core_spec.rb +26 -25
- data/spec/units/engine_adapter_spec.rb +1 -0
- data/spec/units/file_locator_spec.rb +129 -0
- data/spec/units/global_id_spec.rb +12 -11
- data/spec/units/input_spec.rb +8 -5
- data/spec/units/output_spec.rb +8 -5
- data/spec/units/persistence_spec.rb +15 -11
- data/spec/units/polling_job_spec.rb +7 -6
- data/spec/units/polling_spec.rb +1 -0
- data/spec/units/status_spec.rb +3 -3
- metadata +184 -18
- data/.travis.yml +0 -19
@@ -0,0 +1,104 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module ActiveEncode
|
3
|
+
module EngineAdapters
|
4
|
+
module MediaConvertOutput
|
5
|
+
class << self
|
6
|
+
AUDIO_SETTINGS = {
|
7
|
+
"AAC" => :aac_settings,
|
8
|
+
"AC3" => :ac3_settings,
|
9
|
+
"AIFF" => :aiff_settings,
|
10
|
+
"EAC3_ATMOS" => :eac_3_atmos_settings,
|
11
|
+
"EAC3" => :eac_3_settings,
|
12
|
+
"MP2" => :mp_2_settings,
|
13
|
+
"MP3" => :mp_3_settings,
|
14
|
+
"OPUS" => :opus_settings,
|
15
|
+
"VORBIS" => :vorbis_settings,
|
16
|
+
"WAV" => :wav_settings
|
17
|
+
}.freeze
|
18
|
+
|
19
|
+
VIDEO_SETTINGS = {
|
20
|
+
"AV1" => :av_1_settings,
|
21
|
+
"AVC_INTRA" => :avc_intra_settings,
|
22
|
+
"FRAME_CAPTURE" => :frame_capture_settings,
|
23
|
+
"H_264" => :h264_settings,
|
24
|
+
"H_265" => :h265_settings,
|
25
|
+
"MPEG2" => :mpeg_2_settings,
|
26
|
+
"PRORES" => :prores_settings,
|
27
|
+
"VC3" => :vc_3_settings,
|
28
|
+
"VP8" => :vp_8_settings,
|
29
|
+
"VP9" => :vp_9_settings,
|
30
|
+
"XAVC" => :xavc_settings
|
31
|
+
}.freeze
|
32
|
+
|
33
|
+
def tech_metadata(settings, output)
|
34
|
+
url = output.dig('outputFilePaths', 0)
|
35
|
+
{
|
36
|
+
width: output.dig('videoDetails', 'widthInPx'),
|
37
|
+
height: output.dig('videoDetails', 'heightInPx'),
|
38
|
+
frame_rate: extract_video_frame_rate(settings),
|
39
|
+
duration: output['durationInMs'],
|
40
|
+
audio_codec: extract_audio_codec(settings),
|
41
|
+
video_codec: extract_video_codec(settings),
|
42
|
+
audio_bitrate: extract_audio_bitrate(settings),
|
43
|
+
video_bitrate: extract_video_bitrate(settings),
|
44
|
+
url: url,
|
45
|
+
label: File.basename(url),
|
46
|
+
suffix: settings.name_modifier
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
def extract_audio_codec(settings)
|
51
|
+
settings.audio_descriptions.first.codec_settings.codec
|
52
|
+
rescue
|
53
|
+
nil
|
54
|
+
end
|
55
|
+
|
56
|
+
def extract_audio_codec_settings(settings)
|
57
|
+
codec_key = AUDIO_SETTINGS[extract_audio_codec(settings)]
|
58
|
+
settings.audio_descriptions.first.codec_settings[codec_key]
|
59
|
+
end
|
60
|
+
|
61
|
+
def extract_video_codec(settings)
|
62
|
+
settings.video_description.codec_settings.codec
|
63
|
+
rescue
|
64
|
+
nil
|
65
|
+
end
|
66
|
+
|
67
|
+
def extract_video_codec_settings(settings)
|
68
|
+
codec_key = VIDEO_SETTINGS[extract_video_codec(settings)]
|
69
|
+
settings.video_description.codec_settings[codec_key]
|
70
|
+
rescue
|
71
|
+
nil
|
72
|
+
end
|
73
|
+
|
74
|
+
def extract_audio_bitrate(settings)
|
75
|
+
codec_settings = extract_audio_codec_settings(settings)
|
76
|
+
return nil if codec_settings.nil?
|
77
|
+
try(codec_settings, :bitrate)
|
78
|
+
end
|
79
|
+
|
80
|
+
def extract_video_bitrate(settings)
|
81
|
+
codec_settings = extract_video_codec_settings(settings)
|
82
|
+
return nil if codec_settings.nil?
|
83
|
+
try(codec_settings, :bitrate) || try(codec_settings, :max_bitrate)
|
84
|
+
end
|
85
|
+
|
86
|
+
def extract_video_frame_rate(settings)
|
87
|
+
codec_settings = extract_video_codec_settings(settings)
|
88
|
+
return nil if codec_settings.nil?
|
89
|
+
(codec_settings.framerate_numerator.to_f / codec_settings.framerate_denominator.to_f).round(2)
|
90
|
+
rescue
|
91
|
+
nil
|
92
|
+
end
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
def try(struct, key)
|
97
|
+
struct[key]
|
98
|
+
rescue
|
99
|
+
nil
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,239 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'fileutils'
|
3
|
+
require 'nokogiri'
|
4
|
+
require 'shellwords'
|
5
|
+
require 'file_locator'
|
6
|
+
|
7
|
+
# PassThroughAdapter accepts an input file url and a number of derivative urls in the options
|
8
|
+
# E.g. `create(input, outputs: [{ label: 'low', url: 'file:///derivatives/low.mp4' }, { label: 'high', url: 'file:///derivatives/high.mp4' }])`
|
9
|
+
# This adapter mirrors the ffmpeg adapter but differs in a few ways:
|
10
|
+
# 1. It starts by copying the derivative files to the work directory
|
11
|
+
# 2. It runs Mediainfo on the input and output files and skips ffmpeg
|
12
|
+
# 3. All work is done in the create method so it's status is always completed or failed
|
13
|
+
module ActiveEncode
|
14
|
+
module EngineAdapters
|
15
|
+
class PassThroughAdapter
|
16
|
+
WORK_DIR = ENV["ENCODE_WORK_DIR"] || "encodes" # Should read from config
|
17
|
+
MEDIAINFO_PATH = ENV["MEDIAINFO_PATH"] || "mediainfo"
|
18
|
+
|
19
|
+
def create(input_url, options = {})
|
20
|
+
# Decode file uris for ffmpeg (mediainfo works either way)
|
21
|
+
input_url = URI.decode(input_url) if input_url.starts_with? "file:///"
|
22
|
+
|
23
|
+
new_encode = ActiveEncode::Base.new(input_url, options)
|
24
|
+
new_encode.id = SecureRandom.uuid
|
25
|
+
new_encode.current_operations = []
|
26
|
+
new_encode.output = []
|
27
|
+
|
28
|
+
# Create a working directory that holds all output files related to the encode
|
29
|
+
FileUtils.mkdir_p working_path("", new_encode.id)
|
30
|
+
FileUtils.mkdir_p working_path("outputs", new_encode.id)
|
31
|
+
|
32
|
+
# Extract technical metadata from input file
|
33
|
+
`#{MEDIAINFO_PATH} --Output=XML --LogFile=#{working_path("input_metadata", new_encode.id)} #{input_url.shellescape}`
|
34
|
+
new_encode.input = build_input new_encode
|
35
|
+
new_encode.input.id = new_encode.id
|
36
|
+
new_encode.created_at, new_encode.updated_at = get_times new_encode.id
|
37
|
+
|
38
|
+
if new_encode.input.duration.blank?
|
39
|
+
new_encode.state = :failed
|
40
|
+
new_encode.percent_complete = 1
|
41
|
+
|
42
|
+
new_encode.errors = if new_encode.input.file_size.blank?
|
43
|
+
["#{input_url} does not exist or is not accessible"]
|
44
|
+
else
|
45
|
+
["Error inspecting input: #{input_url}"]
|
46
|
+
end
|
47
|
+
|
48
|
+
write_errors new_encode
|
49
|
+
return new_encode
|
50
|
+
end
|
51
|
+
|
52
|
+
# For saving filename to label map used to find the label when building outputs
|
53
|
+
filename_label_hash = {}
|
54
|
+
|
55
|
+
# Copy derivatives to work directory
|
56
|
+
options[:outputs].each do |opt|
|
57
|
+
url = opt[:url]
|
58
|
+
output_path = working_path("outputs/#{sanitize_base opt[:url]}#{File.extname opt[:url]}", new_encode.id)
|
59
|
+
FileUtils.cp FileLocator.new(url).location, output_path
|
60
|
+
filename_label_hash[output_path] = opt[:label]
|
61
|
+
end
|
62
|
+
|
63
|
+
# Write filename-to-label map so we can retrieve them on build_output
|
64
|
+
File.write working_path("filename_label.yml", new_encode.id), filename_label_hash.to_yaml
|
65
|
+
|
66
|
+
new_encode.percent_complete = 1
|
67
|
+
new_encode.state = :running
|
68
|
+
new_encode.errors = []
|
69
|
+
|
70
|
+
new_encode
|
71
|
+
rescue StandardError => e
|
72
|
+
new_encode.state = :failed
|
73
|
+
new_encode.percent_complete = 1
|
74
|
+
new_encode.errors = [e.full_message]
|
75
|
+
write_errors new_encode
|
76
|
+
return new_encode
|
77
|
+
end
|
78
|
+
|
79
|
+
# Return encode object from file system
|
80
|
+
def find(id, opts = {})
|
81
|
+
encode_class = opts[:cast]
|
82
|
+
encode_class ||= ActiveEncode::Base
|
83
|
+
encode = encode_class.new(nil, opts)
|
84
|
+
encode.id = id
|
85
|
+
encode.created_at, encode.updated_at = get_times encode.id
|
86
|
+
encode.input = build_input encode
|
87
|
+
encode.input.id = encode.id
|
88
|
+
encode.output = []
|
89
|
+
encode.current_operations = []
|
90
|
+
|
91
|
+
encode.errors = read_errors(id)
|
92
|
+
if encode.errors.present?
|
93
|
+
encode.state = :failed
|
94
|
+
encode.percent_complete = 1
|
95
|
+
elsif cancelled?(id)
|
96
|
+
encode.state = :cancelled
|
97
|
+
encode.percent_complete = 1
|
98
|
+
elsif completed?(id)
|
99
|
+
encode.state = :completed
|
100
|
+
encode.percent_complete = 100
|
101
|
+
else
|
102
|
+
encode.output = build_outputs encode
|
103
|
+
encode.state = :completed
|
104
|
+
encode.percent_complete = 100
|
105
|
+
end
|
106
|
+
|
107
|
+
encode
|
108
|
+
rescue StandardError => e
|
109
|
+
encode.state = :failed
|
110
|
+
encode.percent_complete = 1
|
111
|
+
encode.errors = [e.full_message]
|
112
|
+
write_errors encode
|
113
|
+
return encode
|
114
|
+
end
|
115
|
+
|
116
|
+
# Cancel ongoing encode using pid file
|
117
|
+
def cancel(id)
|
118
|
+
# Check for errors and if not then create cancelled file else raise CancelError?
|
119
|
+
if running?(id)
|
120
|
+
File.write(working_path("cancelled", id), "")
|
121
|
+
find id
|
122
|
+
else
|
123
|
+
raise CancelError
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
private
|
128
|
+
|
129
|
+
def running?(id)
|
130
|
+
!cancelled?(id) || !failed?(id) || !completed?(id)
|
131
|
+
end
|
132
|
+
|
133
|
+
def cancelled?(id)
|
134
|
+
File.exist? working_path("cancelled", id)
|
135
|
+
end
|
136
|
+
|
137
|
+
def failed?(id)
|
138
|
+
read_errors(id).present?
|
139
|
+
end
|
140
|
+
|
141
|
+
def completed?(id)
|
142
|
+
File.exist? working_path("completed", id)
|
143
|
+
end
|
144
|
+
|
145
|
+
def get_times(id)
|
146
|
+
updated_at = if File.file? working_path("completed", id)
|
147
|
+
File.mtime(working_path("completed", id))
|
148
|
+
elsif File.file? working_path("cancelled", id)
|
149
|
+
File.mtime(working_path("cancelled", id))
|
150
|
+
elsif File.file? working_path("error.log", id)
|
151
|
+
File.mtime(working_path("error.log", id))
|
152
|
+
else
|
153
|
+
File.mtime(working_path("input_metadata", id))
|
154
|
+
end
|
155
|
+
|
156
|
+
[File.mtime(working_path("input_metadata", id)), updated_at]
|
157
|
+
end
|
158
|
+
|
159
|
+
def write_errors(encode)
|
160
|
+
File.write(working_path("error.log", encode.id), encode.errors.join("\n"))
|
161
|
+
end
|
162
|
+
|
163
|
+
def read_errors(id)
|
164
|
+
err_path = working_path("error.log", id)
|
165
|
+
error = File.read(err_path) if File.file? err_path
|
166
|
+
if error.present?
|
167
|
+
[error]
|
168
|
+
else
|
169
|
+
[]
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def build_input(encode)
|
174
|
+
input = ActiveEncode::Input.new
|
175
|
+
metadata = get_tech_metadata(working_path("input_metadata", encode.id))
|
176
|
+
input.url = metadata[:url]
|
177
|
+
input.assign_tech_metadata(metadata)
|
178
|
+
created_at = File.mtime(working_path("input_metadata", encode.id))
|
179
|
+
input.created_at = created_at
|
180
|
+
input.updated_at = created_at
|
181
|
+
|
182
|
+
input
|
183
|
+
end
|
184
|
+
|
185
|
+
def build_outputs(encode)
|
186
|
+
id = encode.id
|
187
|
+
outputs = []
|
188
|
+
filename_label_hash = YAML.safe_load(File.read(working_path("filename_label.yml", id))) if File.exist?(working_path("filename_label.yml", id))
|
189
|
+
Dir["#{File.absolute_path(working_path('outputs', id))}/*"].each do |file_path|
|
190
|
+
output = ActiveEncode::Output.new
|
191
|
+
output.url = "file://#{file_path}"
|
192
|
+
output.label = filename_label_hash[file_path] if filename_label_hash
|
193
|
+
output.id = "#{encode.input.id}-#{output.label}"
|
194
|
+
output.created_at = encode.created_at
|
195
|
+
output.updated_at = File.mtime file_path
|
196
|
+
|
197
|
+
# Extract technical metadata from output file
|
198
|
+
metadata_path = working_path("output_metadata-#{output.label}", id)
|
199
|
+
`#{MEDIAINFO_PATH} --Output=XML --LogFile=#{metadata_path} #{output.url}` unless File.file? metadata_path
|
200
|
+
output.assign_tech_metadata(get_tech_metadata(metadata_path))
|
201
|
+
|
202
|
+
outputs << output
|
203
|
+
end
|
204
|
+
File.write(working_path("completed", id), "")
|
205
|
+
|
206
|
+
outputs
|
207
|
+
end
|
208
|
+
|
209
|
+
def sanitize_base(input_url)
|
210
|
+
File.basename(input_url, File.extname(input_url)).gsub(/[^0-9A-Za-z.\-]/, '_')
|
211
|
+
end
|
212
|
+
|
213
|
+
def working_path(path, id)
|
214
|
+
File.join(WORK_DIR, id, path)
|
215
|
+
end
|
216
|
+
|
217
|
+
def get_tech_metadata(file_path)
|
218
|
+
doc = Nokogiri::XML File.read(file_path)
|
219
|
+
doc.remove_namespaces!
|
220
|
+
duration = get_xpath_text(doc, '//Duration/text()', :to_f)
|
221
|
+
duration *= 1000 unless duration.nil? # Convert to milliseconds
|
222
|
+
{ url: get_xpath_text(doc, '//media/@ref', :to_s),
|
223
|
+
width: get_xpath_text(doc, '//Width/text()', :to_f),
|
224
|
+
height: get_xpath_text(doc, '//Height/text()', :to_f),
|
225
|
+
frame_rate: get_xpath_text(doc, '//FrameRate/text()', :to_f),
|
226
|
+
duration: duration,
|
227
|
+
file_size: get_xpath_text(doc, '//FileSize/text()', :to_i),
|
228
|
+
audio_codec: get_xpath_text(doc, '//track[@type="Audio"]/CodecID/text()', :to_s),
|
229
|
+
audio_bitrate: get_xpath_text(doc, '//track[@type="Audio"]/BitRate/text()', :to_i),
|
230
|
+
video_codec: get_xpath_text(doc, '//track[@type="Video"]/CodecID/text()', :to_s),
|
231
|
+
video_bitrate: get_xpath_text(doc, '//track[@type="Video"]/BitRate/text()', :to_i) }
|
232
|
+
end
|
233
|
+
|
234
|
+
def get_xpath_text(doc, xpath, cast_method)
|
235
|
+
doc.xpath(xpath).first&.text&.send(cast_method)
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module ActiveEncode
|
2
3
|
module EngineAdapters
|
3
4
|
class TestAdapter
|
@@ -9,8 +10,8 @@ module ActiveEncode
|
|
9
10
|
new_encode = ActiveEncode::Base.new(input_url, options)
|
10
11
|
new_encode.id = SecureRandom.uuid
|
11
12
|
new_encode.state = :running
|
12
|
-
new_encode.created_at = Time.now
|
13
|
-
new_encode.updated_at = Time.now
|
13
|
+
new_encode.created_at = Time.now.utc
|
14
|
+
new_encode.updated_at = Time.now.utc
|
14
15
|
@encodes[new_encode.id] = new_encode
|
15
16
|
new_encode
|
16
17
|
end
|
@@ -18,14 +19,14 @@ module ActiveEncode
|
|
18
19
|
def find(id, _opts = {})
|
19
20
|
new_encode = @encodes[id]
|
20
21
|
# Update the updated_at time to simulate changes
|
21
|
-
new_encode.updated_at = Time.now
|
22
|
+
new_encode.updated_at = Time.now.utc
|
22
23
|
new_encode
|
23
24
|
end
|
24
25
|
|
25
26
|
def cancel(id)
|
26
27
|
new_encode = @encodes[id]
|
27
28
|
new_encode.state = :cancelled
|
28
|
-
new_encode.updated_at = Time.now
|
29
|
+
new_encode.updated_at = Time.now.utc
|
29
30
|
new_encode
|
30
31
|
end
|
31
32
|
end
|
@@ -1,13 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module ActiveEncode
|
2
3
|
module EngineAdapters
|
3
4
|
class ZencoderAdapter
|
4
5
|
# TODO: add a stub for an input helper (supplied by an initializer) that transforms encode.input.url into a zencoder accepted url
|
5
|
-
def create(input_url,
|
6
|
+
def create(input_url, _options = {})
|
6
7
|
response = Zencoder::Job.create(input: input_url.to_s)
|
7
8
|
build_encode(get_job_details(response.body["id"]))
|
8
9
|
end
|
9
10
|
|
10
|
-
def find(id,
|
11
|
+
def find(id, _opts = {})
|
11
12
|
build_encode(get_job_details(id))
|
12
13
|
end
|
13
14
|
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'globalid'
|
2
3
|
|
3
4
|
module ActiveEncode
|
@@ -9,7 +10,7 @@ module ActiveEncode
|
|
9
10
|
other.is_a?(ActiveEncode::Base) && to_global_id == other.to_global_id
|
10
11
|
end
|
11
12
|
|
12
|
-
def to_global_id(
|
13
|
+
def to_global_id(_options = {})
|
13
14
|
super(app: 'ActiveEncode')
|
14
15
|
end
|
15
16
|
end
|
data/lib/active_encode/input.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module ActiveEncode
|
2
3
|
class Input
|
3
4
|
include Status
|
@@ -8,8 +9,8 @@ module ActiveEncode
|
|
8
9
|
|
9
10
|
def valid?
|
10
11
|
id.present? && url.present? &&
|
11
|
-
|
12
|
-
|
12
|
+
created_at.is_a?(Time) && updated_at.is_a?(Time) &&
|
13
|
+
updated_at >= created_at
|
13
14
|
end
|
14
15
|
end
|
15
16
|
end
|
data/lib/active_encode/output.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module ActiveEncode
|
2
3
|
class Output
|
3
4
|
include Status
|
@@ -9,8 +10,8 @@ module ActiveEncode
|
|
9
10
|
|
10
11
|
def valid?
|
11
12
|
id.present? && url.present? && label.present? &&
|
12
|
-
|
13
|
-
|
13
|
+
created_at.is_a?(Time) && updated_at.is_a?(Time) &&
|
14
|
+
updated_at >= created_at
|
14
15
|
end
|
15
16
|
end
|
16
17
|
end
|