active_encode 0.2 → 0.4

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 (55) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +9 -0
  3. data/README.md +1 -16
  4. data/active_encode.gemspec +4 -4
  5. data/app/jobs/active_encode/polling_job.rb +4 -4
  6. data/lib/active_encode/callbacks.rb +2 -21
  7. data/lib/active_encode/core.rb +1 -35
  8. data/lib/active_encode/engine_adapters.rb +1 -3
  9. data/lib/active_encode/engine_adapters/elastic_transcoder_adapter.rb +32 -28
  10. data/lib/active_encode/engine_adapters/ffmpeg_adapter.rb +243 -0
  11. data/lib/active_encode/engine_adapters/matterhorn_adapter.rb +64 -97
  12. data/lib/active_encode/engine_adapters/test_adapter.rb +0 -12
  13. data/lib/active_encode/engine_adapters/zencoder_adapter.rb +53 -44
  14. data/lib/active_encode/input.rb +6 -0
  15. data/lib/active_encode/output.rb +7 -0
  16. data/lib/active_encode/persistence.rb +1 -1
  17. data/lib/active_encode/polling.rb +2 -2
  18. data/lib/active_encode/status.rb +0 -3
  19. data/lib/active_encode/technical_metadata.rb +7 -0
  20. data/lib/active_encode/version.rb +1 -1
  21. data/spec/fixtures/ffmpeg/cancelled-id/error.log +0 -0
  22. data/spec/fixtures/ffmpeg/cancelled-id/input_metadata +90 -0
  23. data/spec/fixtures/ffmpeg/cancelled-id/pid +1 -0
  24. data/spec/fixtures/ffmpeg/cancelled-id/progress +11 -0
  25. data/spec/fixtures/ffmpeg/completed-id/error.log +0 -0
  26. data/spec/fixtures/ffmpeg/completed-id/input_metadata +102 -0
  27. data/spec/fixtures/ffmpeg/completed-id/output_metadata-high +90 -0
  28. data/spec/fixtures/ffmpeg/completed-id/output_metadata-low +90 -0
  29. data/spec/fixtures/ffmpeg/completed-id/pid +1 -0
  30. data/spec/fixtures/ffmpeg/completed-id/progress +11 -0
  31. data/spec/fixtures/ffmpeg/completed-id/video-high.mp4 +0 -0
  32. data/spec/fixtures/ffmpeg/completed-id/video-low.mp4 +0 -0
  33. data/spec/fixtures/ffmpeg/failed-id/error.log +1 -0
  34. data/spec/fixtures/ffmpeg/failed-id/input_metadata +90 -0
  35. data/spec/fixtures/ffmpeg/failed-id/pid +1 -0
  36. data/spec/fixtures/ffmpeg/failed-id/progress +11 -0
  37. data/spec/fixtures/ffmpeg/running-id/error.log +0 -0
  38. data/spec/fixtures/ffmpeg/running-id/input_metadata +90 -0
  39. data/spec/fixtures/ffmpeg/running-id/pid +1 -0
  40. data/spec/fixtures/ffmpeg/running-id/progress +11 -0
  41. data/spec/fixtures/fireworks.mp4 +0 -0
  42. data/spec/integration/elastic_transcoder_adapter_spec.rb +21 -12
  43. data/spec/integration/ffmpeg_adapter_spec.rb +120 -0
  44. data/spec/integration/matterhorn_adapter_spec.rb +30 -59
  45. data/spec/integration/zencoder_adapter_spec.rb +242 -22
  46. data/spec/shared_specs/engine_adapter_specs.rb +116 -16
  47. data/spec/units/core_spec.rb +31 -0
  48. data/spec/units/input_spec.rb +25 -0
  49. data/spec/units/output_spec.rb +28 -1
  50. data/spec/units/polling_job_spec.rb +10 -10
  51. metadata +51 -11
  52. data/lib/active_encode/engine_adapters/active_job_adapter.rb +0 -21
  53. data/lib/active_encode/engine_adapters/inline_adapter.rb +0 -47
  54. data/lib/active_encode/engine_adapters/shingoncoder_adapter.rb +0 -63
  55. data/spec/integration/shingoncoder_adapter_spec.rb +0 -170
@@ -32,14 +32,59 @@ describe ActiveEncode::EngineAdapters::ZencoderAdapter do
32
32
  it { is_expected.to be_a ActiveEncode::Base }
33
33
  its(:id) { is_expected.not_to be_empty }
34
34
  it { is_expected.to be_running }
35
- its(:output) { is_expected.to eq create_output }
35
+ # its(:output) { is_expected.to eq create_output }
36
36
  its(:current_operations) { is_expected.to be_empty }
37
37
  its(:percent_complete) { is_expected.to eq 0 }
38
38
  its(:errors) { is_expected.to be_empty }
39
39
  its(:created_at) { is_expected.to eq '2015-06-10T14:38:47Z' }
40
40
  its(:updated_at) { is_expected.to eq '2015-06-10T14:38:47Z' }
41
- its(:finished_at) { is_expected.to be_nil }
42
- its(:tech_metadata) { is_expected.to be_empty }
41
+
42
+ context 'input' do
43
+ subject { ActiveEncode::Base.create(file).input }
44
+
45
+ it { is_expected.to be_a ActiveEncode::Input }
46
+ its(:id) { is_expected.to eq "166179248" }
47
+ its(:url) { is_expected.to eq "https://archive.org/download/LuckyStr1948_2/LuckyStr1948_2_512kb.mp4" }
48
+ its(:width) { is_expected.to be_blank }
49
+ its(:height) { is_expected.to be_blank }
50
+ its(:frame_rate) { is_expected.to be_blank }
51
+ its(:duration) { is_expected.to be_blank }
52
+ its(:file_size) { is_expected.to be_blank }
53
+ its(:checksum) { is_expected.to be_blank }
54
+ its(:audio_codec) { is_expected.to be_blank }
55
+ its(:video_codec) { is_expected.to be_blank }
56
+ its(:audio_bitrate) { is_expected.to be_blank }
57
+ its(:video_bitrate) { is_expected.to be_blank }
58
+ its(:state) { is_expected.to eq :running }
59
+ its(:created_at) { is_expected.to eq "2015-06-10T14:38:47Z" }
60
+ its(:updated_at) { is_expected.to eq "2015-06-10T14:38:00Z" }
61
+ end
62
+
63
+ context 'output' do
64
+ let(:output) { ActiveEncode::Base.find('166019107').reload.output }
65
+ subject { output.first }
66
+
67
+ it 'is an array' do
68
+ expect(output).to be_a Array
69
+ end
70
+ it { is_expected.to be_a ActiveEncode::Output }
71
+ its(:id) { is_expected.to eq "511404522" }
72
+ its(:url) { is_expected.to eq "https://zencoder-temp-storage-us-east-1.s3.amazonaws.com/o/20150610/c09b61e4d130ddf923f0653418a80b9c/399ae101c3f99b4f318635e78a4e587a.mp4?AWSAccessKeyId=AKIAI456JQ76GBU7FECA&Signature=GY/9LMkQAiDOrMQwS5BkmOE200s%3D&Expires=1434033527" }
73
+ its(:label) { is_expected.to be_blank }
74
+ its(:width) { is_expected.to be_blank }
75
+ its(:height) { is_expected.to be_blank }
76
+ its(:frame_rate) { is_expected.to be_blank }
77
+ its(:duration) { is_expected.to be_blank }
78
+ its(:file_size) { is_expected.to be_blank }
79
+ its(:checksum) { is_expected.to be_blank }
80
+ its(:audio_codec) { is_expected.to be_blank }
81
+ its(:video_codec) { is_expected.to be_blank }
82
+ its(:audio_bitrate) { is_expected.to be_blank }
83
+ its(:video_bitrate) { is_expected.to be_blank }
84
+ its(:state) { is_expected.to eq :running }
85
+ its(:created_at) { is_expected.to eq "2015-06-10T14:38:47Z" }
86
+ its(:updated_at) { is_expected.to eq "2015-06-10T14:38:47Z" }
87
+ end
43
88
  end
44
89
 
45
90
  describe "#find" do
@@ -51,21 +96,67 @@ describe ActiveEncode::EngineAdapters::ZencoderAdapter do
51
96
  context "a running encode" do
52
97
  let(:details_response) { Zencoder::Response.new(body: JSON.parse(File.read('spec/fixtures/zencoder/job_details_running.json'))) }
53
98
  let(:progress_response) { Zencoder::Response.new(body: JSON.parse(File.read('spec/fixtures/zencoder/job_progress_running.json'))) }
54
- let(:running_output) { [{ id: "510582971", url: "https://zencoder-temp-storage-us-east-1.s3.amazonaws.com/o/20150609/48a6907086c012f68b9ca43461280515/1726d7ec3e24f2171bd07b2abb807b6c.mp4?AWSAccessKeyId=AKIAI456JQ76GBU7FECA&Signature=vSvlxU94wlQLEbpG3Zs8ibp4MoY%3D&Expires=1433953106", label: nil }] }
55
- let(:running_tech_metadata) { { audio_bitrate: "52", audio_codec: "aac", audio_channels: "2", duration: "57992", mime_type: "mpeg4", video_framerate: "29.97", height: "240", video_bitrate: "535", video_codec: "h264", width: "320" } }
99
+ # let(:running_output) { [{ id: "510582971", url: "https://zencoder-temp-storage-us-east-1.s3.amazonaws.com/o/20150609/48a6907086c012f68b9ca43461280515/1726d7ec3e24f2171bd07b2abb807b6c.mp4?AWSAccessKeyId=AKIAI456JQ76GBU7FECA&Signature=vSvlxU94wlQLEbpG3Zs8ibp4MoY%3D&Expires=1433953106", label: nil }] }
100
+ # let(:running_tech_metadata) { { audio_bitrate: "52", audio_codec: "aac", audio_channels: "2", duration: "57992", mime_type: "mpeg4", video_framerate: "29.97", height: "240", video_bitrate: "535", video_codec: "h264", width: "320" } }
56
101
 
57
102
  subject { ActiveEncode::Base.find('166019107') }
58
103
  it { is_expected.to be_a ActiveEncode::Base }
59
104
  its(:id) { is_expected.to eq '166019107' }
60
105
  it { is_expected.to be_running }
61
- its(:output) { is_expected.to eq running_output }
106
+ # its(:output) { is_expected.to eq running_output }
62
107
  its(:current_operations) { is_expected.to be_empty }
63
108
  its(:percent_complete) { is_expected.to eq 30.0 }
64
109
  its(:errors) { is_expected.to be_empty }
65
110
  its(:created_at) { is_expected.to eq '2015-06-09T16:18:26Z' }
66
111
  its(:updated_at) { is_expected.to eq '2015-06-09T16:18:28Z' }
67
- its(:finished_at) { is_expected.to be_nil }
68
- its(:tech_metadata) { is_expected.to eq running_tech_metadata }
112
+
113
+ # its(:tech_metadata) { is_expected.to eq running_tech_metadata }
114
+ context 'input' do
115
+ subject { ActiveEncode::Base.find('166019107').input }
116
+
117
+ it { is_expected.to be_a ActiveEncode::Input }
118
+ its(:id) { is_expected.to eq "165990056" }
119
+ its(:url) { is_expected.to eq "https://archive.org/download/LuckyStr1948_2/LuckyStr1948_2_512kb.mp4" }
120
+ its(:width) { is_expected.to eq 320 }
121
+ its(:height) { is_expected.to eq 240 }
122
+ its(:frame_rate) { is_expected.to eq 29.97 }
123
+ its(:duration) { is_expected.to eq 57992 }
124
+ its(:file_size) { is_expected.to be_blank }
125
+ its(:checksum) { is_expected.to be_blank }
126
+ its(:audio_codec) { is_expected.to eq "aac" }
127
+ its(:video_codec) { is_expected.to eq "h264" }
128
+ its(:audio_bitrate) { is_expected.to eq 52 }
129
+ its(:video_bitrate) { is_expected.to eq 535 }
130
+ its(:state) { is_expected.to eq :completed }
131
+ its(:created_at) { is_expected.to eq "2015-06-09T16:18:26Z" }
132
+ its(:updated_at) { is_expected.to eq "2015-06-09T16:18:32Z" }
133
+ end
134
+
135
+ context 'output' do
136
+ let(:output) { ActiveEncode::Base.find('166019107').output }
137
+ subject { output.first }
138
+
139
+ it 'is an array' do
140
+ expect(output).to be_a Array
141
+ end
142
+ it { is_expected.to be_a ActiveEncode::Output }
143
+ its(:id) { is_expected.to eq "510582971" }
144
+ its(:url) { is_expected.to eq "https://zencoder-temp-storage-us-east-1.s3.amazonaws.com/o/20150609/48a6907086c012f68b9ca43461280515/1726d7ec3e24f2171bd07b2abb807b6c.mp4?AWSAccessKeyId=AKIAI456JQ76GBU7FECA&Signature=vSvlxU94wlQLEbpG3Zs8ibp4MoY%3D&Expires=1433953106" }
145
+ its(:label) { is_expected.to be_blank }
146
+ its(:width) { is_expected.to be_blank }
147
+ its(:height) { is_expected.to be_blank }
148
+ its(:frame_rate) { is_expected.to be_blank }
149
+ its(:duration) { is_expected.to be_blank }
150
+ its(:file_size) { is_expected.to be_blank }
151
+ its(:checksum) { is_expected.to be_blank }
152
+ its(:audio_codec) { is_expected.to be_blank }
153
+ its(:video_codec) { is_expected.to be_blank }
154
+ its(:audio_bitrate) { is_expected.to be_blank }
155
+ its(:video_bitrate) { is_expected.to be_blank }
156
+ its(:state) { is_expected.to eq :running }
157
+ its(:created_at) { is_expected.to eq "2015-06-09T16:18:26Z" }
158
+ its(:updated_at) { is_expected.to eq "2015-06-09T16:18:32Z" }
159
+ end
69
160
  end
70
161
 
71
162
  context "a cancelled encode" do
@@ -81,28 +172,92 @@ describe ActiveEncode::EngineAdapters::ZencoderAdapter do
81
172
  its(:errors) { is_expected.to be_empty }
82
173
  its(:created_at) { is_expected.to eq '2015-06-08T20:43:23Z' }
83
174
  its(:updated_at) { is_expected.to eq '2015-06-08T20:43:26Z' }
84
- its(:finished_at) { is_expected.to eq '2015-06-08T20:43:26Z' }
85
- its(:tech_metadata) { is_expected.to be_empty }
175
+
176
+ context 'input' do
177
+ subject { ActiveEncode::Base.find('165866551').input }
178
+
179
+ it { is_expected.to be_a ActiveEncode::Input }
180
+ its(:id) { is_expected.to eq "165837500" }
181
+ its(:url) { is_expected.to eq "https://archive.org/download/LuckyStr1948_2/LuckyStr1948_2_512kb.mp4" }
182
+ its(:width) { is_expected.to be_blank }
183
+ its(:height) { is_expected.to be_blank }
184
+ its(:frame_rate) { is_expected.to be_blank }
185
+ its(:duration) { is_expected.to be_blank }
186
+ its(:file_size) { is_expected.to be_blank }
187
+ its(:checksum) { is_expected.to be_blank }
188
+ its(:audio_codec) { is_expected.to be_blank }
189
+ its(:video_codec) { is_expected.to be_blank }
190
+ its(:audio_bitrate) { is_expected.to be_blank }
191
+ its(:video_bitrate) { is_expected.to be_blank }
192
+ its(:state) { is_expected.to eq :cancelled }
193
+ its(:created_at) { is_expected.to eq "2015-06-08T20:43:23Z" }
194
+ its(:updated_at) { is_expected.to eq "2015-06-08T20:43:26Z" }
195
+ end
86
196
  end
87
197
 
88
198
  context "a completed encode" do
89
199
  let(:details_response) { Zencoder::Response.new(body: JSON.parse(File.read('spec/fixtures/zencoder/job_details_completed.json'))) }
90
200
  let(:progress_response) { Zencoder::Response.new(body: JSON.parse(File.read('spec/fixtures/zencoder/job_progress_completed.json'))) }
91
201
  let(:completed_output) { { id: "509856876", audio_bitrate: "53", audio_codec: "aac", audio_channels: "2", duration: "5000", mime_type: "mpeg4", video_framerate: "29.97", height: "240", video_bitrate: "549", video_codec: "h264", width: "320", url: "https://zencoder-temp-storage-us-east-1.s3.amazonaws.com/o/20150608/ebbe865f8ef1b960d7c2bb0663b88a12/0f1948dcb2fd701fba30ff21908fe460.mp4?AWSAccessKeyId=AKIAI456JQ76GBU7FECA&Signature=1LgIyl/el9E7zeyPxzd/%2BNwez6Y%3D&Expires=1433873646", label: nil } }
92
- let(:completed_tech_metadata) { { audio_bitrate: "52", audio_codec: "aac", audio_channels: "2", duration: "57992", mime_type: "mpeg4", video_framerate: "29.97", height: "240", video_bitrate: "535", video_codec: "h264", width: "320" } }
202
+ # let(:completed_tech_metadata) { { audio_bitrate: "52", audio_codec: "aac", audio_channels: "2", duration: "57992", mime_type: "mpeg4", video_framerate: "29.97", height: "240", video_bitrate: "535", video_codec: "h264", width: "320" } }
93
203
 
94
204
  subject { ActiveEncode::Base.find('165839139') }
95
205
  it { is_expected.to be_a ActiveEncode::Base }
96
206
  its(:id) { is_expected.to eq '165839139' }
97
207
  it { is_expected.to be_completed }
98
- its(:output) { is_expected.to include completed_output }
208
+ # its(:output) { is_expected.to include completed_output }
99
209
  its(:current_operations) { is_expected.to be_empty }
100
210
  its(:percent_complete) { is_expected.to eq 100 }
101
211
  its(:errors) { is_expected.to be_empty }
102
212
  its(:created_at) { is_expected.to eq '2015-06-08T18:13:53Z' }
103
213
  its(:updated_at) { is_expected.to eq '2015-06-08T18:14:06Z' }
104
- its(:finished_at) { is_expected.to eq '2015-06-08T18:14:06Z' }
105
- its(:tech_metadata) { is_expected.to eq completed_tech_metadata }
214
+
215
+ context 'input' do
216
+ subject { ActiveEncode::Base.find('165839139').input }
217
+
218
+ it { is_expected.to be_a ActiveEncode::Input }
219
+ its(:id) { is_expected.to eq "165810088" }
220
+ its(:url) { is_expected.to eq "https://archive.org/download/LuckyStr1948_2/LuckyStr1948_2_512kb.mp4" }
221
+ its(:width) { is_expected.to eq 320 }
222
+ its(:height) { is_expected.to eq 240 }
223
+ its(:frame_rate) { is_expected.to eq 29.97 }
224
+ its(:duration) { is_expected.to eq 57992 }
225
+ its(:file_size) { is_expected.to be_blank }
226
+ its(:checksum) { is_expected.to be_blank }
227
+ its(:audio_codec) { is_expected.to eq "aac" }
228
+ its(:video_codec) { is_expected.to eq "h264" }
229
+ its(:audio_bitrate) { is_expected.to eq 52 }
230
+ its(:video_bitrate) { is_expected.to eq 535 }
231
+ its(:state) { is_expected.to eq :completed }
232
+ its(:created_at) { is_expected.to eq "2015-06-08T18:13:53Z" }
233
+ its(:updated_at) { is_expected.to eq "2015-06-08T18:14:06Z" }
234
+ end
235
+
236
+ context 'output' do
237
+ let(:output) { ActiveEncode::Base.find('166019107').reload.output }
238
+ subject { output.first }
239
+
240
+ it 'is an array' do
241
+ expect(output).to be_a Array
242
+ end
243
+ it { is_expected.to be_a ActiveEncode::Output }
244
+ its(:id) { is_expected.to eq "509856876" }
245
+ its(:url) { is_expected.to eq "https://zencoder-temp-storage-us-east-1.s3.amazonaws.com/o/20150608/ebbe865f8ef1b960d7c2bb0663b88a12/0f1948dcb2fd701fba30ff21908fe460.mp4?AWSAccessKeyId=AKIAI456JQ76GBU7FECA&Signature=1LgIyl/el9E7zeyPxzd/%2BNwez6Y%3D&Expires=1433873646" }
246
+ its(:label) { is_expected.to be_blank }
247
+ its(:width) { is_expected.to eq 320 }
248
+ its(:height) { is_expected.to eq 240 }
249
+ its(:frame_rate) { is_expected.to eq 29.97 }
250
+ its(:duration) { is_expected.to eq 5000 }
251
+ its(:file_size) { is_expected.to be_blank }
252
+ its(:checksum) { is_expected.to be_blank }
253
+ its(:audio_codec) { is_expected.to eq "aac" }
254
+ its(:video_codec) { is_expected.to eq "h264" }
255
+ its(:audio_bitrate) { is_expected.to eq 53 }
256
+ its(:video_bitrate) { is_expected.to eq 549 }
257
+ its(:state) { is_expected.to eq :completed }
258
+ its(:created_at) { is_expected.to eq "2015-06-08T18:13:53Z" }
259
+ its(:updated_at) { is_expected.to eq "2015-06-08T18:14:06Z" }
260
+ end
106
261
  end
107
262
 
108
263
  context "a failed encode" do
@@ -117,11 +272,31 @@ describe ActiveEncode::EngineAdapters::ZencoderAdapter do
117
272
  it { is_expected.to be_failed }
118
273
  its(:current_operations) { is_expected.to be_empty }
119
274
  its(:percent_complete) { is_expected.to eq 0 }
120
- its(:errors) { is_expected.to include failed_errors }
275
+ its(:errors) { is_expected.to be_empty }
121
276
  its(:created_at) { is_expected.to eq '2015-06-09T20:52:57Z' }
122
277
  its(:updated_at) { is_expected.to eq '2015-06-09T20:53:00Z' }
123
- its(:finished_at) { is_expected.to eq '2015-06-09T20:53:00Z' }
124
- its(:tech_metadata) { is_expected.to be_empty }
278
+
279
+ context 'input' do
280
+ subject { ActiveEncode::Base.find('165866551').input }
281
+
282
+ it { is_expected.to be_a ActiveEncode::Input }
283
+ its(:id) { is_expected.to eq "166050851" }
284
+ its(:url) { is_expected.to eq "s3://zencoder-customer-ingest/uploads/2015-06-09/240330/187007/682c2d90-0eea-11e5-84c9-f158f44c3d50.xml" }
285
+ its(:errors) { is_expected.to include failed_errors }
286
+ its(:width) { is_expected.to be_blank }
287
+ its(:height) { is_expected.to be_blank }
288
+ its(:frame_rate) { is_expected.to be_blank }
289
+ its(:duration) { is_expected.to be_blank }
290
+ its(:file_size) { is_expected.to be_blank }
291
+ its(:checksum) { is_expected.to be_blank }
292
+ its(:audio_codec) { is_expected.to be_blank }
293
+ its(:video_codec) { is_expected.to be_blank }
294
+ its(:audio_bitrate) { is_expected.to be_blank }
295
+ its(:video_bitrate) { is_expected.to be_blank }
296
+ its(:state) { is_expected.to eq :failed }
297
+ its(:created_at) { is_expected.to eq "2015-06-09T20:52:57Z" }
298
+ its(:updated_at) { is_expected.to eq "2015-06-09T20:53:00Z" }
299
+ end
125
300
  end
126
301
  end
127
302
 
@@ -151,20 +326,65 @@ describe ActiveEncode::EngineAdapters::ZencoderAdapter do
151
326
 
152
327
  let(:details_response) { Zencoder::Response.new(body: JSON.parse(File.read('spec/fixtures/zencoder/job_details_running.json'))) }
153
328
  let(:progress_response) { Zencoder::Response.new(body: JSON.parse(File.read('spec/fixtures/zencoder/job_progress_running.json'))) }
154
- let(:reload_output) { [{ id: "510582971", url: "https://zencoder-temp-storage-us-east-1.s3.amazonaws.com/o/20150609/48a6907086c012f68b9ca43461280515/1726d7ec3e24f2171bd07b2abb807b6c.mp4?AWSAccessKeyId=AKIAI456JQ76GBU7FECA&Signature=vSvlxU94wlQLEbpG3Zs8ibp4MoY%3D&Expires=1433953106", label: nil }] }
155
- let(:reload_tech_metadata) { { audio_bitrate: "52", audio_codec: "aac", audio_channels: "2", duration: "57992", mime_type: "mpeg4", video_framerate: "29.97", height: "240", video_bitrate: "535", video_codec: "h264", width: "320" } }
329
+ # let(:reload_output) { [{ id: "510582971", url: "https://zencoder-temp-storage-us-east-1.s3.amazonaws.com/o/20150609/48a6907086c012f68b9ca43461280515/1726d7ec3e24f2171bd07b2abb807b6c.mp4?AWSAccessKeyId=AKIAI456JQ76GBU7FECA&Signature=vSvlxU94wlQLEbpG3Zs8ibp4MoY%3D&Expires=1433953106", label: nil }] }
330
+ # let(:reload_tech_metadata) { { audio_bitrate: "52", audio_codec: "aac", audio_channels: "2", duration: "57992", mime_type: "mpeg4", video_framerate: "29.97", height: "240", video_bitrate: "535", video_codec: "h264", width: "320" } }
156
331
 
157
332
  subject { ActiveEncode::Base.find('166019107').reload }
158
333
  it { is_expected.to be_a ActiveEncode::Base }
159
334
  its(:id) { is_expected.to eq '166019107' }
160
335
  it { is_expected.to be_running }
161
- its(:output) { is_expected.to eq reload_output }
336
+ # its(:output) { is_expected.to eq reload_output }
162
337
  its(:current_operations) { is_expected.to be_empty }
163
338
  its(:percent_complete) { is_expected.to eq 30.0 }
164
339
  its(:errors) { is_expected.to be_empty }
165
340
  its(:created_at) { is_expected.to eq '2015-06-09T16:18:26Z' }
166
341
  its(:updated_at) { is_expected.to eq '2015-06-09T16:18:28Z' }
167
- its(:finished_at) { is_expected.to be_nil }
168
- its(:tech_metadata) { is_expected.to eq reload_tech_metadata }
342
+
343
+ context 'input' do
344
+ subject { ActiveEncode::Base.find('166019107').reload.input }
345
+
346
+ it { is_expected.to be_a ActiveEncode::Input }
347
+ its(:id) { is_expected.to eq "165990056" }
348
+ its(:url) { is_expected.to eq "https://archive.org/download/LuckyStr1948_2/LuckyStr1948_2_512kb.mp4" }
349
+ its(:width) { is_expected.to eq 320 }
350
+ its(:height) { is_expected.to eq 240 }
351
+ its(:frame_rate) { is_expected.to eq 29.97 }
352
+ its(:duration) { is_expected.to eq 57992 }
353
+ its(:file_size) { is_expected.to be_blank }
354
+ its(:checksum) { is_expected.to be_blank }
355
+ its(:audio_codec) { is_expected.to eq "aac" }
356
+ its(:video_codec) { is_expected.to eq "h264" }
357
+ its(:audio_bitrate) { is_expected.to eq 52 }
358
+ its(:video_bitrate) { is_expected.to eq 535 }
359
+ its(:state) { is_expected.to eq :completed }
360
+ its(:created_at) { is_expected.to eq "2015-06-09T16:18:26Z" }
361
+ its(:updated_at) { is_expected.to eq "2015-06-09T16:18:32Z" }
362
+ end
363
+
364
+ context 'output' do
365
+ let(:output) { ActiveEncode::Base.find('166019107').reload.output }
366
+ subject { output.first }
367
+
368
+ it 'is an array' do
369
+ expect(output).to be_a Array
370
+ end
371
+ it { is_expected.to be_a ActiveEncode::Output }
372
+ its(:id) { is_expected.to eq "510582971" }
373
+ its(:url) { is_expected.to eq "https://zencoder-temp-storage-us-east-1.s3.amazonaws.com/o/20150609/48a6907086c012f68b9ca43461280515/1726d7ec3e24f2171bd07b2abb807b6c.mp4?AWSAccessKeyId=AKIAI456JQ76GBU7FECA&Signature=vSvlxU94wlQLEbpG3Zs8ibp4MoY%3D&Expires=1433953106" }
374
+ its(:label) { is_expected.to be_blank }
375
+ its(:width) { is_expected.to be_blank }
376
+ its(:height) { is_expected.to be_blank }
377
+ its(:frame_rate) { is_expected.to be_blank }
378
+ its(:duration) { is_expected.to be_blank }
379
+ its(:file_size) { is_expected.to be_blank }
380
+ its(:checksum) { is_expected.to be_blank }
381
+ its(:audio_codec) { is_expected.to be_blank }
382
+ its(:video_codec) { is_expected.to be_blank }
383
+ its(:audio_bitrate) { is_expected.to be_blank }
384
+ its(:video_bitrate) { is_expected.to be_blank }
385
+ its(:state) { is_expected.to eq :running }
386
+ its(:created_at) { is_expected.to eq "2015-06-09T16:18:26Z" }
387
+ its(:updated_at) { is_expected.to eq "2015-06-09T16:18:32Z" }
388
+ end
169
389
  end
170
390
  end
@@ -6,6 +6,9 @@ RSpec.shared_examples 'an ActiveEncode::EngineAdapter' do |*_flags|
6
6
  raise 'adapter must be set with `let(:canceled_job)`' unless defined? canceled_job
7
7
  raise 'adapter must be set with `let(:completed_job)`' unless defined? completed_job
8
8
  raise 'adapter must be set with `let(:failed_job)`' unless defined? failed_job
9
+ raise 'adapter must be set with `let(:completed_tech_metadata)`' unless defined? completed_tech_metadata
10
+ raise 'adapter must be set with `let(:completed_output)`' unless defined? completed_output
11
+ raise 'adapter must be set with `let(:failed_tech_metadata)`' unless defined? failed_tech_metadata
9
12
  end
10
13
 
11
14
  it { is_expected.to respond_to :create }
@@ -15,16 +18,29 @@ RSpec.shared_examples 'an ActiveEncode::EngineAdapter' do |*_flags|
15
18
  describe "#create" do
16
19
  subject { created_job }
17
20
 
18
- it { is_expected.to be_a ActiveEncode::Base }
21
+ it 'returns an ActiveEncode::Base object' do
22
+ expect(subject.class).to be ActiveEncode::Base
23
+ end
19
24
  its(:id) { is_expected.not_to be_empty }
20
25
  it { is_expected.to be_running }
21
26
  its(:current_operations) { is_expected.to be_empty }
22
27
  its(:percent_complete) { is_expected.to be < 100 }
23
28
  its(:errors) { is_expected.to be_empty }
24
29
  its(:created_at) { is_expected.to be_kind_of Time }
25
- its(:updated_at) { is_expected.to be_nil }
26
- its(:finished_at) { is_expected.to be_nil }
27
- its(:tech_metadata) { is_expected.to be_empty }
30
+ its(:updated_at) { is_expected.to be_kind_of Time }
31
+
32
+ it 'input is a valid ActiveEncode::Input object' do
33
+ expect(subject.input).to be_a ActiveEncode::Input
34
+ expect(subject.input).to be_valid
35
+ end
36
+
37
+ it 'output has only valid ActiveEncode::Output objects' do
38
+ expect(subject.output).to be_a Array
39
+ subject.output.each do |out|
40
+ expect(out).to be_a ActiveEncode::Output
41
+ expect(out).to be_valid
42
+ end
43
+ end
28
44
  end
29
45
 
30
46
  describe "#find" do
@@ -40,7 +56,19 @@ RSpec.shared_examples 'an ActiveEncode::EngineAdapter' do |*_flags|
40
56
  its(:errors) { is_expected.to be_empty }
41
57
  its(:created_at) { is_expected.to be_kind_of Time }
42
58
  its(:updated_at) { is_expected.to be > subject.created_at }
43
- its(:finished_at) { is_expected.to be_nil }
59
+
60
+ it 'input is a valid ActiveEncode::Input object' do
61
+ expect(subject.input).to be_a ActiveEncode::Input
62
+ expect(subject.input).to be_valid
63
+ end
64
+
65
+ it 'output has only valid ActiveEncode::Output objects' do
66
+ expect(subject.output).to be_a Array
67
+ subject.output.each do |out|
68
+ expect(out).to be_a ActiveEncode::Output
69
+ expect(out).to be_valid
70
+ end
71
+ end
44
72
  end
45
73
 
46
74
  context "a cancelled encode" do
@@ -54,8 +82,20 @@ RSpec.shared_examples 'an ActiveEncode::EngineAdapter' do |*_flags|
54
82
  its(:percent_complete) { is_expected.to be > 0 }
55
83
  its(:errors) { is_expected.to be_empty }
56
84
  its(:created_at) { is_expected.to be_kind_of Time }
57
- its(:finished_at) { is_expected.to be >= subject.created_at }
58
- its(:tech_metadata) { is_expected.to be_empty }
85
+ its(:updated_at) { is_expected.to be >= subject.created_at }
86
+
87
+ it 'input is a valid ActiveEncode::Input object' do
88
+ expect(subject.input).to be_a ActiveEncode::Input
89
+ expect(subject.input).to be_valid
90
+ end
91
+
92
+ it 'output has only valid ActiveEncode::Output objects' do
93
+ expect(subject.output).to be_a Array
94
+ subject.output.each do |out|
95
+ expect(out).to be_a ActiveEncode::Output
96
+ expect(out).to be_valid
97
+ end
98
+ end
59
99
  end
60
100
 
61
101
  context "a completed encode" do
@@ -66,13 +106,34 @@ RSpec.shared_examples 'an ActiveEncode::EngineAdapter' do |*_flags|
66
106
  end
67
107
  its(:id) { is_expected.to eq 'completed-id' }
68
108
  it { is_expected.to be_completed }
69
- its(:output) { is_expected.to eq completed_output }
70
109
  its(:percent_complete) { is_expected.to eq 100 }
71
110
  its(:errors) { is_expected.to be_empty }
72
111
  its(:created_at) { is_expected.to be_kind_of Time }
73
112
  its(:updated_at) { is_expected.to be > subject.created_at }
74
- its(:finished_at) { is_expected.to be >= subject.updated_at }
75
- its(:tech_metadata) { is_expected.to include completed_tech_metadata }
113
+
114
+ it 'input is a valid ActiveEncode::Input object' do
115
+ expect(subject.input).to be_a ActiveEncode::Input
116
+ expect(subject.input).to be_valid
117
+ end
118
+
119
+ it 'input has technical metadata' do
120
+ expect(subject.input.as_json.symbolize_keys).to include completed_tech_metadata
121
+ end
122
+
123
+ it 'output has only valid ActiveEncode::Output objects' do
124
+ expect(subject.output).to be_a Array
125
+ subject.output.each do |out|
126
+ expect(out).to be_a ActiveEncode::Output
127
+ expect(out).to be_valid
128
+ end
129
+ end
130
+
131
+ it 'output has technical metadata' do
132
+ subject.output.each do |output|
133
+ expected_output = completed_output.find {|expected_out| expected_out[:id] == output.id }
134
+ expect(output.as_json.symbolize_keys).to include expected_output
135
+ end
136
+ end
76
137
  end
77
138
 
78
139
  context "a failed encode" do
@@ -87,8 +148,23 @@ RSpec.shared_examples 'an ActiveEncode::EngineAdapter' do |*_flags|
87
148
  its(:errors) { is_expected.not_to be_empty }
88
149
  its(:created_at) { is_expected.to be_kind_of Time }
89
150
  its(:updated_at) { is_expected.to be > subject.created_at }
90
- its(:finished_at) { is_expected.to be >= subject.updated_at }
91
- its(:tech_metadata) { is_expected.to include failed_tech_metadata }
151
+
152
+ it 'input is a valid ActiveEncode::Input object' do
153
+ expect(subject.input).to be_a ActiveEncode::Input
154
+ expect(subject.input).to be_valid
155
+ end
156
+
157
+ it 'input has technical metadata' do
158
+ expect(subject.input.as_json.symbolize_keys).to include failed_tech_metadata
159
+ end
160
+
161
+ it 'output has only valid ActiveEncode::Output objects' do
162
+ expect(subject.output).to be_a Array
163
+ subject.output.each do |out|
164
+ expect(out).to be_a ActiveEncode::Output
165
+ expect(out).to be_valid
166
+ end
167
+ end
92
168
  end
93
169
  end
94
170
 
@@ -98,13 +174,25 @@ RSpec.shared_examples 'an ActiveEncode::EngineAdapter' do |*_flags|
98
174
  it 'returns an ActiveEncode::Base object' do
99
175
  expect(subject.class).to be ActiveEncode::Base
100
176
  end
101
- its(:id) { is_expected.to eq 'cancelled-id' }
177
+ its(:id) { is_expected.to eq cancelling_job.id }
102
178
  it { is_expected.to be_cancelled }
103
179
  its(:percent_complete) { is_expected.to be > 0 }
104
180
  its(:errors) { is_expected.to be_empty }
105
181
  its(:created_at) { is_expected.to be_kind_of Time }
106
- its(:finished_at) { is_expected.to be >= subject.created_at }
107
- its(:tech_metadata) { is_expected.to be_empty }
182
+ its(:updated_at) { is_expected.to be >= subject.created_at }
183
+
184
+ it 'input is a valid ActiveEncode::Input object' do
185
+ expect(subject.input).to be_a ActiveEncode::Input
186
+ expect(subject.input).to be_valid
187
+ end
188
+
189
+ it 'output has only valid ActiveEncode::Output objects' do
190
+ expect(subject.output).to be_a Array
191
+ subject.output.each do |out|
192
+ expect(out).to be_a ActiveEncode::Output
193
+ expect(out).to be_valid
194
+ end
195
+ end
108
196
  end
109
197
 
110
198
  describe "reload" do
@@ -119,6 +207,18 @@ RSpec.shared_examples 'an ActiveEncode::EngineAdapter' do |*_flags|
119
207
  its(:errors) { is_expected.to be_empty }
120
208
  its(:created_at) { is_expected.to be_kind_of Time }
121
209
  its(:updated_at) { is_expected.to be > subject.created_at }
122
- its(:finished_at) { is_expected.to be_nil }
210
+
211
+ it 'input is a valid ActiveEncode::Input object' do
212
+ expect(subject.input).to be_a ActiveEncode::Input
213
+ expect(subject.input).to be_valid
214
+ end
215
+
216
+ it 'output has only valid ActiveEncode::Output objects' do
217
+ expect(subject.output).to be_a Array
218
+ subject.output.each do |out|
219
+ expect(out).to be_a ActiveEncode::Output
220
+ expect(out).to be_valid
221
+ end
222
+ end
123
223
  end
124
224
  end