active_encode 0.4.1 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. checksums.yaml +5 -5
  2. data/.circleci/config.yml +80 -0
  3. data/.rubocop.yml +9 -70
  4. data/.rubocop_todo.yml +68 -0
  5. data/CODE_OF_CONDUCT.md +36 -0
  6. data/CONTRIBUTING.md +23 -21
  7. data/Gemfile +5 -4
  8. data/LICENSE +11 -199
  9. data/README.md +135 -24
  10. data/SUPPORT.md +5 -0
  11. data/active_encode.gemspec +13 -3
  12. data/app/controllers/active_encode/encode_record_controller.rb +13 -0
  13. data/app/jobs/active_encode/polling_job.rb +1 -1
  14. data/app/models/active_encode/encode_record.rb +1 -0
  15. data/config/routes.rb +4 -0
  16. data/db/migrate/20180822021048_create_active_encode_encode_records.rb +1 -0
  17. data/db/migrate/20190702153755_add_create_options_to_active_encode_encode_records.rb +6 -0
  18. data/db/migrate/20190712174821_add_progress_to_active_encode_encode_records.rb +6 -0
  19. data/lib/active_encode.rb +1 -0
  20. data/lib/active_encode/base.rb +2 -2
  21. data/lib/active_encode/callbacks.rb +1 -0
  22. data/lib/active_encode/core.rb +4 -3
  23. data/lib/active_encode/engine.rb +1 -0
  24. data/lib/active_encode/engine_adapter.rb +1 -0
  25. data/lib/active_encode/engine_adapters.rb +4 -1
  26. data/lib/active_encode/engine_adapters/elastic_transcoder_adapter.rb +116 -38
  27. data/lib/active_encode/engine_adapters/ffmpeg_adapter.rb +141 -87
  28. data/lib/active_encode/engine_adapters/matterhorn_adapter.rb +5 -4
  29. data/lib/active_encode/engine_adapters/media_convert_adapter.rb +372 -0
  30. data/lib/active_encode/engine_adapters/media_convert_output.rb +104 -0
  31. data/lib/active_encode/engine_adapters/pass_through_adapter.rb +239 -0
  32. data/lib/active_encode/engine_adapters/test_adapter.rb +5 -4
  33. data/lib/active_encode/engine_adapters/zencoder_adapter.rb +3 -2
  34. data/lib/active_encode/errors.rb +6 -0
  35. data/lib/active_encode/global_id.rb +2 -1
  36. data/lib/active_encode/input.rb +3 -2
  37. data/lib/active_encode/output.rb +3 -2
  38. data/lib/active_encode/persistence.rb +11 -5
  39. data/lib/active_encode/polling.rb +3 -2
  40. data/lib/active_encode/spec/shared_specs.rb +2 -0
  41. data/{spec/shared_specs/engine_adapter_specs.rb → lib/active_encode/spec/shared_specs/engine_adapter.rb} +37 -38
  42. data/lib/active_encode/status.rb +1 -0
  43. data/lib/active_encode/technical_metadata.rb +3 -2
  44. data/lib/active_encode/version.rb +2 -1
  45. data/lib/file_locator.rb +93 -0
  46. data/spec/controllers/encode_record_controller_spec.rb +53 -0
  47. data/spec/fixtures/ffmpeg/cancelled-id/cancelled +0 -0
  48. data/spec/fixtures/file with space.low.mp4 +0 -0
  49. data/spec/fixtures/file with space.mp4 +0 -0
  50. data/spec/fixtures/fireworks.low.mp4 +0 -0
  51. data/spec/fixtures/media_convert/endpoints.json +1 -0
  52. data/spec/fixtures/media_convert/job_canceled.json +412 -0
  53. data/spec/fixtures/media_convert/job_canceling.json +1 -0
  54. data/spec/fixtures/media_convert/job_completed.json +359 -0
  55. data/spec/fixtures/media_convert/job_completed_detail.json +1 -0
  56. data/spec/fixtures/media_convert/job_completed_detail_query.json +1 -0
  57. data/spec/fixtures/media_convert/job_created.json +408 -0
  58. data/spec/fixtures/media_convert/job_failed.json +406 -0
  59. data/spec/fixtures/media_convert/job_progressing.json +414 -0
  60. data/spec/fixtures/pass_through/cancelled-id/cancelled +0 -0
  61. data/spec/fixtures/pass_through/cancelled-id/input_metadata +90 -0
  62. data/spec/fixtures/pass_through/completed-id/completed +0 -0
  63. data/spec/fixtures/pass_through/completed-id/input_metadata +102 -0
  64. data/spec/fixtures/pass_through/completed-id/output_metadata-high +90 -0
  65. data/spec/fixtures/pass_through/completed-id/output_metadata-low +90 -0
  66. data/spec/fixtures/pass_through/completed-id/video-high.mp4 +0 -0
  67. data/spec/fixtures/pass_through/completed-id/video-low.mp4 +0 -0
  68. data/spec/fixtures/pass_through/failed-id/error.log +1 -0
  69. data/spec/fixtures/pass_through/failed-id/input_metadata +90 -0
  70. data/spec/fixtures/pass_through/running-id/input_metadata +90 -0
  71. data/spec/integration/elastic_transcoder_adapter_spec.rb +63 -29
  72. data/spec/integration/ffmpeg_adapter_spec.rb +96 -24
  73. data/spec/integration/matterhorn_adapter_spec.rb +45 -44
  74. data/spec/integration/media_convert_adapter_spec.rb +126 -0
  75. data/spec/integration/pass_through_adapter_spec.rb +151 -0
  76. data/spec/integration/zencoder_adapter_spec.rb +210 -209
  77. data/spec/rails_helper.rb +1 -0
  78. data/spec/routing/encode_record_controller_routing_spec.rb +10 -0
  79. data/spec/spec_helper.rb +2 -2
  80. data/spec/test_app_templates/lib/generators/test_app_generator.rb +13 -12
  81. data/spec/units/callbacks_spec.rb +3 -2
  82. data/spec/units/core_spec.rb +26 -25
  83. data/spec/units/engine_adapter_spec.rb +1 -0
  84. data/spec/units/file_locator_spec.rb +129 -0
  85. data/spec/units/global_id_spec.rb +12 -11
  86. data/spec/units/input_spec.rb +8 -5
  87. data/spec/units/output_spec.rb +8 -5
  88. data/spec/units/persistence_spec.rb +15 -11
  89. data/spec/units/polling_job_spec.rb +7 -6
  90. data/spec/units/polling_spec.rb +1 -0
  91. data/spec/units/status_spec.rb +3 -3
  92. metadata +184 -18
  93. data/.travis.yml +0 -19
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'active_support'
2
3
 
3
4
  module ActiveEncode
@@ -9,8 +10,10 @@ module ActiveEncode
9
10
  persist(persistence_model_attributes(encode))
10
11
  end
11
12
 
12
- after_create do |encode|
13
- persist(persistence_model_attributes(encode))
13
+ around_create do |encode, block|
14
+ create_options = encode.options
15
+ encode = block.call
16
+ persist(persistence_model_attributes(encode, create_options))
14
17
  end
15
18
 
16
19
  after_cancel do |encode|
@@ -29,8 +32,8 @@ module ActiveEncode
29
32
  model.update(encode_attributes) # Don't fail if persisting doesn't succeed?
30
33
  end
31
34
 
32
- def persistence_model_attributes(encode)
33
- {
35
+ def persistence_model_attributes(encode, create_options = nil)
36
+ attributes = {
34
37
  global_id: encode.to_global_id.to_s,
35
38
  state: encode.state,
36
39
  adapter: encode.class.engine_adapter.class.name,
@@ -38,8 +41,11 @@ module ActiveEncode
38
41
  # Need to ensure that these values come through or else validations will fail
39
42
  created_at: encode.created_at,
40
43
  updated_at: encode.updated_at,
41
- raw_object: encode.to_json
44
+ raw_object: encode.to_json,
45
+ progress: encode.percent_complete
42
46
  }
47
+ attributes[:create_options] = create_options.to_json if create_options.present?
48
+ attributes
43
49
  end
44
50
  end
45
51
  end
@@ -1,4 +1,5 @@
1
- require 'active_support'
1
+ # frozen_string_literal: true
2
+ require 'active_support/core_ext/integer/time'
2
3
  require 'active_model/callbacks'
3
4
 
4
5
  module ActiveEncode
@@ -8,7 +9,7 @@ module ActiveEncode
8
9
  POLLING_WAIT_TIME = 10.seconds.freeze
9
10
 
10
11
  CALLBACKS = [
11
- :after_status_update, :after_failed, :after_cancelled, :after_completed
12
+ :after_status_update, :after_failed, :after_cancelled, :after_completed
12
13
  ].freeze
13
14
 
14
15
  included do
@@ -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 eq 'running-id' }
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 eq 'cancelled-id' }
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 eq 'completed-id' }
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
@@ -130,7 +130,7 @@ RSpec.shared_examples 'an ActiveEncode::EngineAdapter' do |*_flags|
130
130
 
131
131
  it 'output has technical metadata' do
132
132
  subject.output.each do |output|
133
- expected_output = completed_output.find {|expected_out| expected_out[:id] == output.id }
133
+ expected_output = completed_output.find { |expected_out| expected_out[:id] == output.id }
134
134
  expect(output.as_json.symbolize_keys).to include expected_output
135
135
  end
136
136
  end
@@ -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 eq 'failed-id' }
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,12 +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 eq 'running-id' }
205
- it { is_expected.to be_running }
206
- its(:percent_complete) { is_expected.to be > 0 }
207
- its(:errors) { is_expected.to be_empty }
208
- its(:created_at) { is_expected.to be_kind_of Time }
209
- 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 }
210
209
 
211
210
  it 'input is a valid ActiveEncode::Input object' do
212
211
  expect(subject.input).to be_a ActiveEncode::Input
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'active_support'
2
3
 
3
4
  module ActiveEncode
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'active_support'
2
3
 
3
4
  module ActiveEncode
@@ -23,10 +24,10 @@ module ActiveEncode
23
24
  attr_accessor :video_bitrate
24
25
  end
25
26
 
26
- def assign_tech_metadata metadata
27
+ def assign_tech_metadata(metadata)
27
28
  [:width, :height, :frame_rate, :duration, :file_size, :checksum,
28
29
  :audio_codec, :video_codec, :audio_bitrate, :video_bitrate].each do |field|
29
- self.send("#{field}=", metadata[field]) if metadata.has_key?(field)
30
+ send("#{field}=", metadata[field]) if metadata.key?(field)
30
31
  end
31
32
  end
32
33
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module ActiveEncode
2
- VERSION = '0.4.1'.freeze
3
+ VERSION = '0.8.0'
3
4
  end
@@ -0,0 +1,93 @@
1
+ # frozen_string_literal: true
2
+ require 'addressable/uri'
3
+ require 'aws-sdk-s3'
4
+
5
+ class FileLocator
6
+ attr_reader :source
7
+
8
+ class S3File
9
+ attr_reader :bucket, :key
10
+
11
+ def initialize(uri)
12
+ uri = Addressable::URI.parse(uri)
13
+ @bucket = URI.decode(uri.host)
14
+ @key = URI.decode(uri.path).sub(%r{^/*(.+)/*$}, '\1')
15
+ end
16
+
17
+ def object
18
+ @object ||= Aws::S3::Object.new(bucket_name: bucket, key: key)
19
+ end
20
+ end
21
+
22
+ def initialize(source)
23
+ @source = source
24
+ end
25
+
26
+ def uri
27
+ if @uri.nil?
28
+ if source.is_a? File
29
+ @uri = Addressable::URI.parse("file://#{URI.encode(File.expand_path(source))}")
30
+ else
31
+ encoded_source = source
32
+ begin
33
+ @uri = Addressable::URI.parse(encoded_source)
34
+ rescue URI::InvalidURIError
35
+ if encoded_source == source
36
+ encoded_source = URI.encode(encoded_source)
37
+ retry
38
+ else
39
+ raise
40
+ end
41
+ end
42
+
43
+ @uri = Addressable::URI.parse("file://#{URI.encode(File.expand_path(source))}") if @uri.scheme.nil?
44
+ end
45
+ end
46
+ @uri
47
+ end
48
+
49
+ def location
50
+ case uri.scheme
51
+ when 's3'
52
+ S3File.new(uri).object.presigned_url(:get)
53
+ when 'file'
54
+ URI.decode(uri.path)
55
+ else
56
+ @uri.to_s
57
+ end
58
+ end
59
+
60
+ def exist?
61
+ case uri.scheme
62
+ when 's3'
63
+ S3File.new(uri).object.exists?
64
+ when 'file'
65
+ File.exist?(location)
66
+ else
67
+ false
68
+ end
69
+ end
70
+ alias exists? exist?
71
+
72
+ def reader
73
+ case uri.scheme
74
+ when 's3'
75
+ S3File.new(uri).object.get.body
76
+ when 'file'
77
+ File.open(location, 'r')
78
+ else
79
+ Kernel.open(uri.to_s, 'r')
80
+ end
81
+ end
82
+
83
+ def attachment
84
+ case uri.scheme
85
+ when 's3'
86
+ uri
87
+ when 'file'
88
+ File.open(location, 'r')
89
+ else
90
+ location
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+ require 'rails_helper'
3
+
4
+ describe ActiveEncode::EncodeRecordController, type: :controller, db_clean: true do
5
+ routes { ActiveEncode::Engine.routes }
6
+
7
+ let(:encode_record) { ActiveEncode::EncodeRecord.create(id: 1, global_id: "app://ActiveEncode/Encode/1", state: "running", adapter: "ffmpeg", title: "Test", raw_object: raw_object, progress: 100) }
8
+ let(:raw_object) do
9
+ "{\"input\":{\"url\":\"file:///Users/cjcolvar/Documents/Code/samvera/active_encode/spec/fixtures/fireworks.mp4\",\"width\":960.0,\"height\":540.0,\"frame_rate\":29.671,\"duration\":6024,\"file_size\":1629578,\"audio_codec\":\"mp4a-40-2\",\"video_codec\":\"avc1\",\"audio_bitrate\":69737,\"video_bitrate\":2092780,\"created_at\":\"2018-12-17T16:54:50.401-05:00\",\"updated_at\":\"2018-12-17T16:54:50.401-05:00\",\"id\":\"8156\"},\"options\":{},\"id\":\"35efa965-ec51-409d-9495-2ae9669adbcc\",\"output\":[{\"url\":\"file:///Users/cjcolvar/Documents/Code/samvera/active_encode/.internal_test_app/encodes/35efa965-ec51-409d-9495-2ae9669adbcc/outputs/fireworks-low.mp4\",\"label\":\"low\",\"id\":\"8156-low\",\"created_at\":\"2018-12-17T16:54:50.401-05:00\",\"updated_at\":\"2018-12-17T16:54:59.169-05:00\",\"width\":640.0,\"height\":480.0,\"frame_rate\":29.671,\"duration\":6038,\"file_size\":905987,\"audio_codec\":\"mp4a-40-2\",\"video_codec\":\"avc1\",\"audio_bitrate\":72000,\"video_bitrate\":1126859},{\"url\":\"file:///Users/cjcolvar/Documents/Code/samvera/active_encode/.internal_test_app/encodes/35efa965-ec51-409d-9495-2ae9669adbcc/outputs/fireworks-high.mp4\",\"label\":\"high\",\"id\":\"8156-high\",\"created_at\":\"2018-12-17T16:54:50.401-05:00\",\"updated_at\":\"2018-12-17T16:54:59.169-05:00\",\"width\":1280.0,\"height\":720.0,\"frame_rate\":29.671,\"duration\":6038,\"file_size\":2102027,\"audio_codec\":\"mp4a-40-2\",\"video_codec\":\"avc1\",\"audio_bitrate\":72000,\"video_bitrate\":2721866}],\"state\":\"completed\",\"errors\":[],\"created_at\":\"2018-12-17T16:54:50.401-05:00\",\"updated_at\":\"2018-12-17T16:54:59.169-05:00\",\"current_operations\":[],\"percent_complete\":100,\"global_id\":{\"uri\":\"gid://ActiveEncode/Encode/35efa965-ec51-409d-9495-2ae9669adbcc\"}}"
10
+ end
11
+
12
+ before do
13
+ encode_record
14
+ end
15
+
16
+ describe 'GET show' do
17
+ before do
18
+ get :show, params: { id: record_id }
19
+ end
20
+
21
+ context 'when record exists' do
22
+ let(:record_id) { 1 }
23
+
24
+ it "responds with a 200 status code" do
25
+ expect(response.status).to eq 200
26
+ end
27
+
28
+ it "responds with JSON" do
29
+ expect(response.content_type).to include "application/json"
30
+ end
31
+
32
+ it "returns the encode record's raw json object" do
33
+ expect(response.body).to eq raw_object
34
+ end
35
+ end
36
+
37
+ context 'when record does not exist' do
38
+ let(:record_id) { "non-existant" }
39
+
40
+ it "responds with a 404 status code" do
41
+ expect(response.status).to eq 404
42
+ end
43
+
44
+ it "responds with JSON" do
45
+ expect(response.content_type).to include "application/json"
46
+ end
47
+
48
+ it "returns the encode record's raw json object" do
49
+ expect(response.body).to eq "{\"message\":\"Couldn't find ActiveEncode::EncodeRecord with 'id'=#{record_id}\"}"
50
+ end
51
+ end
52
+ end
53
+ end
File without changes
Binary file
Binary file
@@ -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
+ }