active_encode 0.7.0 → 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.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -0
  3. data/.rubocop_todo.yml +1 -0
  4. data/Gemfile +2 -1
  5. data/README.md +69 -0
  6. data/active_encode.gemspec +5 -2
  7. data/lib/active_encode/engine_adapters.rb +1 -0
  8. data/lib/active_encode/engine_adapters/elastic_transcoder_adapter.rb +1 -1
  9. data/lib/active_encode/engine_adapters/ffmpeg_adapter.rb +12 -2
  10. data/lib/active_encode/engine_adapters/media_convert_adapter.rb +372 -0
  11. data/lib/active_encode/engine_adapters/media_convert_output.rb +104 -0
  12. data/lib/active_encode/polling.rb +1 -1
  13. data/lib/active_encode/spec/shared_specs.rb +2 -0
  14. data/{spec/shared_specs/engine_adapter_specs.rb → lib/active_encode/spec/shared_specs/engine_adapter.rb} +36 -36
  15. data/lib/active_encode/version.rb +1 -1
  16. data/lib/file_locator.rb +1 -1
  17. data/spec/fixtures/media_convert/endpoints.json +1 -0
  18. data/spec/fixtures/media_convert/job_canceled.json +412 -0
  19. data/spec/fixtures/media_convert/job_canceling.json +1 -0
  20. data/spec/fixtures/media_convert/job_completed.json +359 -0
  21. data/spec/fixtures/media_convert/job_completed_detail.json +1 -0
  22. data/spec/fixtures/media_convert/job_completed_detail_query.json +1 -0
  23. data/spec/fixtures/media_convert/job_created.json +408 -0
  24. data/spec/fixtures/media_convert/job_failed.json +406 -0
  25. data/spec/fixtures/media_convert/job_progressing.json +414 -0
  26. data/spec/integration/elastic_transcoder_adapter_spec.rb +4 -4
  27. data/spec/integration/ffmpeg_adapter_spec.rb +2 -2
  28. data/spec/integration/matterhorn_adapter_spec.rb +39 -39
  29. data/spec/integration/media_convert_adapter_spec.rb +126 -0
  30. data/spec/integration/pass_through_adapter_spec.rb +2 -2
  31. data/spec/integration/zencoder_adapter_spec.rb +198 -198
  32. data/spec/spec_helper.rb +0 -1
  33. data/spec/units/core_spec.rb +17 -17
  34. data/spec/units/file_locator_spec.rb +1 -1
  35. data/spec/units/global_id_spec.rb +8 -8
  36. data/spec/units/persistence_spec.rb +9 -9
  37. metadata +87 -23
@@ -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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
- require 'active_support'
2
+ require 'active_support/core_ext/integer/time'
3
3
  require 'active_model/callbacks'
4
4
 
5
5
  module ActiveEncode
@@ -0,0 +1,2 @@
1
+ # frozen_string_literal: true
2
+ require 'active_encode/spec/shared_specs/engine_adapter.rb'
@@ -21,13 +21,13 @@ RSpec.shared_examples 'an ActiveEncode::EngineAdapter' do |*_flags|
21
21
  it 'returns an ActiveEncode::Base object' do
22
22
  expect(subject.class).to be ActiveEncode::Base
23
23
  end
24
- its(:id) { is_expected.not_to be_empty }
24
+ it { expect(subject.id).to be_present }
25
25
  it { is_expected.to be_running }
26
- its(:current_operations) { is_expected.to be_empty }
27
- its(:percent_complete) { is_expected.to be < 100 }
28
- its(:errors) { is_expected.to be_empty }
29
- its(:created_at) { is_expected.to be_kind_of Time }
30
- its(:updated_at) { is_expected.to be_kind_of Time }
26
+ it { expect(subject.current_operations).to be_empty }
27
+ it { expect(subject.percent_complete).to be < 100 }
28
+ it { expect(subject.errors).to be_empty }
29
+ it { expect(subject.created_at).to be_kind_of Time }
30
+ it { expect(subject.updated_at).to be_kind_of Time }
31
31
 
32
32
  it 'input is a valid ActiveEncode::Input object' do
33
33
  expect(subject.input).to be_a ActiveEncode::Input
@@ -50,12 +50,12 @@ RSpec.shared_examples 'an ActiveEncode::EngineAdapter' do |*_flags|
50
50
  it 'returns an ActiveEncode::Base object' do
51
51
  expect(subject.class).to be ActiveEncode::Base
52
52
  end
53
- its(:id) { is_expected.to be_present }
53
+ it { expect(subject.id).to be_present }
54
54
  it { is_expected.to be_running }
55
- its(:percent_complete) { is_expected.to be > 0 }
56
- its(:errors) { is_expected.to be_empty }
57
- its(:created_at) { is_expected.to be_kind_of Time }
58
- its(:updated_at) { is_expected.to be >= subject.created_at }
55
+ it { expect(subject.percent_complete).to be_positive }
56
+ it { expect(subject.errors).to be_empty }
57
+ it { expect(subject.created_at).to be_kind_of Time }
58
+ it { expect(subject.updated_at).to be >= subject.created_at }
59
59
 
60
60
  it 'input is a valid ActiveEncode::Input object' do
61
61
  expect(subject.input).to be_a ActiveEncode::Input
@@ -77,12 +77,12 @@ RSpec.shared_examples 'an ActiveEncode::EngineAdapter' do |*_flags|
77
77
  it 'returns an ActiveEncode::Base object' do
78
78
  expect(subject.class).to be ActiveEncode::Base
79
79
  end
80
- its(:id) { is_expected.to be_present }
80
+ it { expect(subject.id).to be_present }
81
81
  it { is_expected.to be_cancelled }
82
- its(:percent_complete) { is_expected.to be > 0 }
83
- its(:errors) { is_expected.to be_empty }
84
- its(:created_at) { is_expected.to be_kind_of Time }
85
- its(:updated_at) { is_expected.to be >= subject.created_at }
82
+ it { expect(subject.percent_complete).to be_positive }
83
+ it { expect(subject.errors).to be_empty }
84
+ it { expect(subject.created_at).to be_kind_of Time }
85
+ it { expect(subject.updated_at).to be >= subject.created_at }
86
86
 
87
87
  it 'input is a valid ActiveEncode::Input object' do
88
88
  expect(subject.input).to be_a ActiveEncode::Input
@@ -104,12 +104,12 @@ RSpec.shared_examples 'an ActiveEncode::EngineAdapter' do |*_flags|
104
104
  it 'returns an ActiveEncode::Base object' do
105
105
  expect(subject.class).to be ActiveEncode::Base
106
106
  end
107
- its(:id) { is_expected.to be_present }
107
+ it { expect(subject.id).to be_present }
108
108
  it { is_expected.to be_completed }
109
- its(:percent_complete) { is_expected.to eq 100 }
110
- its(:errors) { is_expected.to be_empty }
111
- its(:created_at) { is_expected.to be_kind_of Time }
112
- its(:updated_at) { is_expected.to be > subject.created_at }
109
+ it { expect(subject.percent_complete).to eq 100 }
110
+ it { expect(subject.errors).to be_empty }
111
+ it { expect(subject.created_at).to be_kind_of Time }
112
+ it { expect(subject.updated_at).to be > subject.created_at }
113
113
 
114
114
  it 'input is a valid ActiveEncode::Input object' do
115
115
  expect(subject.input).to be_a ActiveEncode::Input
@@ -142,12 +142,12 @@ RSpec.shared_examples 'an ActiveEncode::EngineAdapter' do |*_flags|
142
142
  it 'returns an ActiveEncode::Base object' do
143
143
  expect(subject.class).to be ActiveEncode::Base
144
144
  end
145
- its(:id) { is_expected.to be_present }
145
+ it { expect(subject.id).to be_present }
146
146
  it { is_expected.to be_failed }
147
- its(:percent_complete) { is_expected.to be > 0 }
148
- its(:errors) { is_expected.not_to be_empty }
149
- its(:created_at) { is_expected.to be_kind_of Time }
150
- its(:updated_at) { is_expected.to be > subject.created_at }
147
+ it { expect(subject.percent_complete).to be_positive }
148
+ it { expect(subject.errors).not_to be_empty }
149
+ it { expect(subject.created_at).to be_kind_of Time }
150
+ it { expect(subject.updated_at).to be > subject.created_at }
151
151
 
152
152
  it 'input is a valid ActiveEncode::Input object' do
153
153
  expect(subject.input).to be_a ActiveEncode::Input
@@ -174,12 +174,12 @@ RSpec.shared_examples 'an ActiveEncode::EngineAdapter' do |*_flags|
174
174
  it 'returns an ActiveEncode::Base object' do
175
175
  expect(subject.class).to be ActiveEncode::Base
176
176
  end
177
- its(:id) { is_expected.to eq cancelling_job.id }
177
+ it { expect(subject.id).to eq cancelling_job.id }
178
178
  it { is_expected.to be_cancelled }
179
- its(:percent_complete) { is_expected.to be > 0 }
180
- its(:errors) { is_expected.to be_empty }
181
- its(:created_at) { is_expected.to be_kind_of Time }
182
- its(:updated_at) { is_expected.to be >= subject.created_at }
179
+ it { expect(subject.percent_complete).to be_positive }
180
+ it { expect(subject.errors).to be_empty }
181
+ it { expect(subject.created_at).to be_kind_of Time }
182
+ it { expect(subject.updated_at).to be >= subject.created_at }
183
183
 
184
184
  it 'input is a valid ActiveEncode::Input object' do
185
185
  expect(subject.input).to be_a ActiveEncode::Input
@@ -201,11 +201,11 @@ RSpec.shared_examples 'an ActiveEncode::EngineAdapter' do |*_flags|
201
201
  it 'returns an ActiveEncode::Base object' do
202
202
  expect(subject.class).to be ActiveEncode::Base
203
203
  end
204
- its(:id) { is_expected.to be_present }
205
- its(:percent_complete) { is_expected.to be > 0 }
206
- its(:errors) { is_expected.to be_empty }
207
- its(:created_at) { is_expected.to be_kind_of Time }
208
- its(:updated_at) { is_expected.to be >= subject.created_at }
204
+ it { expect(subject.id).to be_present }
205
+ it { expect(subject.percent_complete).to be_positive }
206
+ it { expect(subject.errors).to be_empty }
207
+ it { expect(subject.created_at).to be_kind_of Time }
208
+ it { expect(subject.updated_at).to be >= subject.created_at }
209
209
 
210
210
  it 'input is a valid ActiveEncode::Input object' do
211
211
  expect(subject.input).to be_a ActiveEncode::Input
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module ActiveEncode
3
- VERSION = '0.7.0'
3
+ VERSION = '0.8.0'
4
4
  end
data/lib/file_locator.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  require 'addressable/uri'
3
- require 'aws-sdk'
3
+ require 'aws-sdk-s3'
4
4
 
5
5
  class FileLocator
6
6
  attr_reader :source
@@ -0,0 +1 @@
1
+ {"endpoints":[{"url":"https://stub.mediaconvert.us-east-1.amazonaws.com"}]}
@@ -0,0 +1,412 @@
1
+ {
2
+ "job": {
3
+ "acceleration_settings": {
4
+ "mode": "DISABLED"
5
+ },
6
+ "acceleration_status": "NOT_APPLICABLE",
7
+ "arn": "arn:aws:mediaconvert:us-east-1:123456789012:jobs/1625859001514-vvqfwj",
8
+ "created_at": "2021-07-09T14:30:01.000-05:00",
9
+ "id": "1625859001514-vvqfwj",
10
+ "messages": {
11
+ "info": [
12
+
13
+ ],
14
+ "warning": [
15
+
16
+ ]
17
+ },
18
+ "priority": 0,
19
+ "queue": "arn:aws:mediaconvert:us-east-1:123456789012:queues/Default",
20
+ "role": "arn:aws:iam::123456789012:role/service-role/MediaConvert_Default_Role",
21
+ "settings": {
22
+ "inputs": [
23
+ {
24
+ "audio_selectors": {
25
+ "Audio Selector 1": {
26
+ "default_selection": "DEFAULT"
27
+ }
28
+ },
29
+ "file_input": "s3://input-bucket/test_files/source_file.mp4",
30
+ "timecode_source": "ZEROBASED",
31
+ "video_selector": {
32
+ }
33
+ }
34
+ ],
35
+ "output_groups": [
36
+ {
37
+ "output_group_settings": {
38
+ "hls_group_settings": {
39
+ "destination": "s3://output-bucket/active-encode-test/output",
40
+ "min_segment_length": 0,
41
+ "segment_control": "SEGMENTED_FILES",
42
+ "segment_length": 10
43
+ },
44
+ "type": "HLS_GROUP_SETTINGS"
45
+ },
46
+ "outputs": [
47
+ {
48
+ "audio_descriptions": [
49
+ {
50
+ "audio_type": 0,
51
+ "audio_type_control": "FOLLOW_INPUT",
52
+ "codec_settings": {
53
+ "aac_settings": {
54
+ "audio_description_broadcaster_mix": "NORMAL",
55
+ "bitrate": 128000,
56
+ "codec_profile": "LC",
57
+ "coding_mode": "CODING_MODE_2_0",
58
+ "rate_control_mode": "CBR",
59
+ "raw_format": "NONE",
60
+ "sample_rate": 48000,
61
+ "specification": "MPEG4"
62
+ },
63
+ "codec": "AAC"
64
+ },
65
+ "language_code_control": "FOLLOW_INPUT"
66
+ }
67
+ ],
68
+ "container_settings": {
69
+ "container": "M3U8",
70
+ "m3u_8_settings": {
71
+ "audio_frames_per_pes": 4,
72
+ "audio_pids": [
73
+ 482,
74
+ 483,
75
+ 484,
76
+ 485,
77
+ 486,
78
+ 487,
79
+ 488,
80
+ 489,
81
+ 490,
82
+ 491,
83
+ 492,
84
+ 493,
85
+ 494,
86
+ 495,
87
+ 496,
88
+ 497,
89
+ 498
90
+ ],
91
+ "pat_interval": 0,
92
+ "pcr_control": "PCR_EVERY_PES_PACKET",
93
+ "pmt_interval": 0,
94
+ "pmt_pid": 480,
95
+ "private_metadata_pid": 503,
96
+ "program_number": 1,
97
+ "scte_35_pid": 500,
98
+ "timed_metadata_pid": 502,
99
+ "video_pid": 481
100
+ }
101
+ },
102
+ "name_modifier": "-1080",
103
+ "preset": "System-Avc_16x9_1080p_29_97fps_8500kbps",
104
+ "video_description": {
105
+ "afd_signaling": "NONE",
106
+ "anti_alias": "ENABLED",
107
+ "codec_settings": {
108
+ "codec": "H_264",
109
+ "h264_settings": {
110
+ "adaptive_quantization": "HIGH",
111
+ "bitrate": 8500000,
112
+ "codec_level": "LEVEL_4",
113
+ "codec_profile": "HIGH",
114
+ "entropy_encoding": "CABAC",
115
+ "field_encoding": "PAFF",
116
+ "flicker_adaptive_quantization": "DISABLED",
117
+ "framerate_control": "SPECIFIED",
118
+ "framerate_conversion_algorithm": "DUPLICATE_DROP",
119
+ "framerate_denominator": 1001,
120
+ "framerate_numerator": 30000,
121
+ "gop_b_reference": "DISABLED",
122
+ "gop_closed_cadence": 1,
123
+ "gop_size": 90.0,
124
+ "gop_size_units": "FRAMES",
125
+ "hrd_buffer_initial_fill_percentage": 90,
126
+ "hrd_buffer_size": 12750000,
127
+ "interlace_mode": "PROGRESSIVE",
128
+ "min_i_interval": 0,
129
+ "number_b_frames_between_reference_frames": 1,
130
+ "number_reference_frames": 3,
131
+ "par_control": "SPECIFIED",
132
+ "par_denominator": 1,
133
+ "par_numerator": 1,
134
+ "quality_tuning_level": "MULTI_PASS_HQ",
135
+ "rate_control_mode": "CBR",
136
+ "repeat_pps": "DISABLED",
137
+ "scene_change_detect": "ENABLED",
138
+ "slices": 1,
139
+ "slow_pal": "DISABLED",
140
+ "spatial_adaptive_quantization": "ENABLED",
141
+ "syntax": "DEFAULT",
142
+ "telecine": "NONE",
143
+ "temporal_adaptive_quantization": "ENABLED",
144
+ "unregistered_sei_timecode": "DISABLED"
145
+ }
146
+ },
147
+ "color_metadata": "INSERT",
148
+ "drop_frame_timecode": "ENABLED",
149
+ "height": 1080,
150
+ "respond_to_afd": "NONE",
151
+ "scaling_behavior": "DEFAULT",
152
+ "sharpness": 50,
153
+ "timecode_insertion": "DISABLED",
154
+ "video_preprocessors": {
155
+ "deinterlacer": {
156
+ "algorithm": "INTERPOLATE",
157
+ "control": "NORMAL",
158
+ "mode": "DEINTERLACE"
159
+ }
160
+ },
161
+ "width": 1920
162
+ }
163
+ },
164
+ {
165
+ "audio_descriptions": [
166
+ {
167
+ "audio_type": 0,
168
+ "audio_type_control": "FOLLOW_INPUT",
169
+ "codec_settings": {
170
+ "aac_settings": {
171
+ "audio_description_broadcaster_mix": "NORMAL",
172
+ "bitrate": 96000,
173
+ "codec_profile": "HEV1",
174
+ "coding_mode": "CODING_MODE_2_0",
175
+ "rate_control_mode": "CBR",
176
+ "raw_format": "NONE",
177
+ "sample_rate": 48000,
178
+ "specification": "MPEG4"
179
+ },
180
+ "codec": "AAC"
181
+ },
182
+ "language_code_control": "FOLLOW_INPUT"
183
+ }
184
+ ],
185
+ "container_settings": {
186
+ "container": "M3U8",
187
+ "m3u_8_settings": {
188
+ "audio_frames_per_pes": 4,
189
+ "audio_pids": [
190
+ 482,
191
+ 483,
192
+ 484,
193
+ 485,
194
+ 486,
195
+ 487,
196
+ 488,
197
+ 489,
198
+ 490,
199
+ 491,
200
+ 492,
201
+ 493,
202
+ 494,
203
+ 495,
204
+ 496,
205
+ 497,
206
+ 498
207
+ ],
208
+ "pat_interval": 0,
209
+ "pcr_control": "PCR_EVERY_PES_PACKET",
210
+ "pmt_interval": 0,
211
+ "pmt_pid": 480,
212
+ "private_metadata_pid": 503,
213
+ "program_number": 1,
214
+ "scte_35_pid": 500,
215
+ "timed_metadata_pid": 502,
216
+ "video_pid": 481
217
+ }
218
+ },
219
+ "name_modifier": "-720",
220
+ "preset": "System-Avc_16x9_720p_29_97fps_5000kbps",
221
+ "video_description": {
222
+ "afd_signaling": "NONE",
223
+ "anti_alias": "ENABLED",
224
+ "codec_settings": {
225
+ "codec": "H_264",
226
+ "h264_settings": {
227
+ "adaptive_quantization": "HIGH",
228
+ "bitrate": 5000000,
229
+ "codec_level": "LEVEL_3_1",
230
+ "codec_profile": "MAIN",
231
+ "entropy_encoding": "CABAC",
232
+ "field_encoding": "PAFF",
233
+ "flicker_adaptive_quantization": "DISABLED",
234
+ "framerate_control": "SPECIFIED",
235
+ "framerate_conversion_algorithm": "DUPLICATE_DROP",
236
+ "framerate_denominator": 1001,
237
+ "framerate_numerator": 30000,
238
+ "gop_b_reference": "DISABLED",
239
+ "gop_closed_cadence": 1,
240
+ "gop_size": 90.0,
241
+ "gop_size_units": "FRAMES",
242
+ "hrd_buffer_initial_fill_percentage": 90,
243
+ "hrd_buffer_size": 7500000,
244
+ "interlace_mode": "PROGRESSIVE",
245
+ "min_i_interval": 0,
246
+ "number_b_frames_between_reference_frames": 1,
247
+ "number_reference_frames": 3,
248
+ "par_control": "SPECIFIED",
249
+ "par_denominator": 1,
250
+ "par_numerator": 1,
251
+ "quality_tuning_level": "MULTI_PASS_HQ",
252
+ "rate_control_mode": "CBR",
253
+ "repeat_pps": "DISABLED",
254
+ "scene_change_detect": "ENABLED",
255
+ "slices": 1,
256
+ "slow_pal": "DISABLED",
257
+ "spatial_adaptive_quantization": "ENABLED",
258
+ "syntax": "DEFAULT",
259
+ "telecine": "NONE",
260
+ "temporal_adaptive_quantization": "ENABLED",
261
+ "unregistered_sei_timecode": "DISABLED"
262
+ }
263
+ },
264
+ "color_metadata": "INSERT",
265
+ "drop_frame_timecode": "ENABLED",
266
+ "height": 720,
267
+ "respond_to_afd": "NONE",
268
+ "scaling_behavior": "DEFAULT",
269
+ "sharpness": 50,
270
+ "timecode_insertion": "DISABLED",
271
+ "video_preprocessors": {
272
+ "deinterlacer": {
273
+ "algorithm": "INTERPOLATE",
274
+ "control": "NORMAL",
275
+ "mode": "DEINTERLACE"
276
+ }
277
+ },
278
+ "width": 1280
279
+ }
280
+ },
281
+ {
282
+ "audio_descriptions": [
283
+ {
284
+ "audio_type": 0,
285
+ "audio_type_control": "FOLLOW_INPUT",
286
+ "codec_settings": {
287
+ "aac_settings": {
288
+ "audio_description_broadcaster_mix": "NORMAL",
289
+ "bitrate": 96000,
290
+ "codec_profile": "HEV1",
291
+ "coding_mode": "CODING_MODE_2_0",
292
+ "rate_control_mode": "CBR",
293
+ "raw_format": "NONE",
294
+ "sample_rate": 48000,
295
+ "specification": "MPEG4"
296
+ },
297
+ "codec": "AAC"
298
+ },
299
+ "language_code_control": "FOLLOW_INPUT"
300
+ }
301
+ ],
302
+ "container_settings": {
303
+ "container": "M3U8",
304
+ "m3u_8_settings": {
305
+ "audio_frames_per_pes": 4,
306
+ "audio_pids": [
307
+ 482,
308
+ 483,
309
+ 484,
310
+ 485,
311
+ 486,
312
+ 487,
313
+ 488,
314
+ 489,
315
+ 490,
316
+ 491,
317
+ 492,
318
+ 493,
319
+ 494,
320
+ 495,
321
+ 496,
322
+ 497,
323
+ 498
324
+ ],
325
+ "pat_interval": 0,
326
+ "pcr_control": "PCR_EVERY_PES_PACKET",
327
+ "pmt_interval": 0,
328
+ "pmt_pid": 480,
329
+ "private_metadata_pid": 503,
330
+ "program_number": 1,
331
+ "scte_35_pid": 500,
332
+ "timed_metadata_pid": 502,
333
+ "video_pid": 481
334
+ }
335
+ },
336
+ "name_modifier": "-540",
337
+ "preset": "System-Avc_16x9_540p_29_97fps_3500kbps",
338
+ "video_description": {
339
+ "afd_signaling": "NONE",
340
+ "anti_alias": "ENABLED",
341
+ "codec_settings": {
342
+ "codec": "H_264",
343
+ "h264_settings": {
344
+ "adaptive_quantization": "HIGH",
345
+ "bitrate": 3500000,
346
+ "codec_level": "LEVEL_3_1",
347
+ "codec_profile": "MAIN",
348
+ "entropy_encoding": "CABAC",
349
+ "field_encoding": "PAFF",
350
+ "flicker_adaptive_quantization": "DISABLED",
351
+ "framerate_control": "SPECIFIED",
352
+ "framerate_conversion_algorithm": "DUPLICATE_DROP",
353
+ "framerate_denominator": 1001,
354
+ "framerate_numerator": 30000,
355
+ "gop_b_reference": "DISABLED",
356
+ "gop_closed_cadence": 1,
357
+ "gop_size": 90.0,
358
+ "gop_size_units": "FRAMES",
359
+ "hrd_buffer_initial_fill_percentage": 90,
360
+ "hrd_buffer_size": 5250000,
361
+ "interlace_mode": "PROGRESSIVE",
362
+ "min_i_interval": 0,
363
+ "number_b_frames_between_reference_frames": 3,
364
+ "number_reference_frames": 3,
365
+ "par_control": "SPECIFIED",
366
+ "par_denominator": 1,
367
+ "par_numerator": 1,
368
+ "quality_tuning_level": "MULTI_PASS_HQ",
369
+ "rate_control_mode": "CBR",
370
+ "repeat_pps": "DISABLED",
371
+ "scene_change_detect": "ENABLED",
372
+ "slices": 1,
373
+ "slow_pal": "DISABLED",
374
+ "spatial_adaptive_quantization": "ENABLED",
375
+ "syntax": "DEFAULT",
376
+ "telecine": "NONE",
377
+ "temporal_adaptive_quantization": "ENABLED",
378
+ "unregistered_sei_timecode": "DISABLED"
379
+ }
380
+ },
381
+ "color_metadata": "INSERT",
382
+ "drop_frame_timecode": "ENABLED",
383
+ "height": 540,
384
+ "respond_to_afd": "NONE",
385
+ "scaling_behavior": "DEFAULT",
386
+ "sharpness": 50,
387
+ "timecode_insertion": "DISABLED",
388
+ "video_preprocessors": {
389
+ "deinterlacer": {
390
+ "algorithm": "INTERPOLATE",
391
+ "control": "NORMAL",
392
+ "mode": "DEINTERLACE"
393
+ }
394
+ },
395
+ "width": 960
396
+ }
397
+ }
398
+ ]
399
+ }
400
+ ]
401
+ },
402
+ "status": "CANCELED",
403
+ "status_update_interval": "SECONDS_60",
404
+ "timing": {
405
+ "finish_time": "2021-07-09T14:30:22.000-05:00",
406
+ "start_time": "2021-07-09T14:30:04.000-05:00",
407
+ "submit_time": "2021-07-09T14:30:01.000-05:00"
408
+ },
409
+ "user_metadata": {
410
+ }
411
+ }
412
+ }