animoto 1.3.1 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +41 -41
- data/lib/animoto.rb +1 -1
- data/lib/animoto/manifests/directing.rb +39 -15
- data/lib/animoto/manifests/rendering.rb +22 -1
- data/lib/animoto/postroll.rb +34 -0
- data/lib/animoto/postrolls/custom_footage.rb +30 -0
- data/lib/animoto/resources/jobs/directing_and_rendering.rb +11 -2
- data/lib/animoto/resources/jobs/rendering.rb +11 -2
- data/lib/animoto/resources/video.rb +9 -2
- data/lib/animoto/styles.rb +10 -0
- data/spec/animoto/manifests/directing_spec.rb +51 -6
- data/spec/animoto/manifests/rendering_spec.rb +21 -2
- data/spec/animoto/resources/jobs/directing_and_rendering_spec.rb +7 -2
- data/spec/animoto/resources/jobs/rendering_spec.rb +6 -1
- data/spec/animoto/resources/video_spec.rb +7 -2
- metadata +10 -9
data/README.md
CHANGED
@@ -23,7 +23,7 @@ Animoto services from a Ruby environment or using the Ruby language.
|
|
23
23
|
<a name="what_is_covered_in_this_document"></a>
|
24
24
|
## What is covered in this document
|
25
25
|
|
26
|
-
This document covers the technical details of the Animoto API Ruby client and
|
26
|
+
This document covers the technical details of the Animoto API Ruby client and
|
27
27
|
provides a general overview of its use.
|
28
28
|
|
29
29
|
This document does not cover the details of the Animoto API itself. For such information please see the [Animoto API documentation][api_docs]
|
@@ -97,32 +97,32 @@ client and using HTTP callbacks for status updates.
|
|
97
97
|
# Create a new client using our application key and secret
|
98
98
|
client = Client.new("application_key", "secret")
|
99
99
|
|
100
|
-
# create a directing and rendering manifest with the video title and
|
100
|
+
# create a directing and rendering manifest with the video title and
|
101
101
|
# producer. Also include rendering parameters like resolution, framerate,
|
102
102
|
# and format.
|
103
103
|
manifest = Manifests::DirectingAndRendering.new(
|
104
|
-
:title => "Amazing Title!",
|
105
|
-
:resolution => "720p",
|
106
|
-
:framerate => 24,
|
104
|
+
:title => "Amazing Title!",
|
105
|
+
:resolution => "720p",
|
106
|
+
:framerate => 24,
|
107
107
|
:format => 'h264'
|
108
108
|
)
|
109
|
-
|
109
|
+
|
110
110
|
# Add some images, text, and footage to our manifest.
|
111
111
|
manifest << Assets::Image.new("http://website.com/picture.png")
|
112
112
|
manifest << Assets::Image.new("http://website.com/hooray.png", :spotlit => true)
|
113
113
|
manifest << Assets::TitleCard.new("Woohoo!", "Hooray for everything!")
|
114
114
|
manifest << Assets::Footage.new("http://website.com/movie.mp4", :duration => 3.5)
|
115
|
-
|
115
|
+
|
116
116
|
# Setup the soundtrack.
|
117
117
|
manifest << Assets::Song.new("http://website.com/song.mp3", :artist => "Fishy Joe")
|
118
|
-
|
119
|
-
# Setup to get http callbacks for status notification (see below for
|
118
|
+
|
119
|
+
# Setup to get http callbacks for status notification (see below for
|
120
120
|
# polling example).
|
121
121
|
manifest.http_callback_url = "http://mysite.com/animoto_callback"
|
122
122
|
manifest.http_callback_format = "json"
|
123
123
|
|
124
|
-
# Send the manifest to the API. Your app will be notified of
|
125
|
-
# completion/failure via an HTTP POST to
|
124
|
+
# Send the manifest to the API. Your app will be notified of
|
125
|
+
# completion/failure via an HTTP POST to
|
126
126
|
# "http://mysite.com/animoto_callback"
|
127
127
|
client.direct_and_render!(manifest)
|
128
128
|
|
@@ -141,29 +141,29 @@ status.
|
|
141
141
|
# Create a directing manifest. The directing manifest controls the images
|
142
142
|
# and other visual elements that will be in our final video.
|
143
143
|
manifest = Manifests::Directing.new(:title => "Amazing Title!")
|
144
|
-
|
144
|
+
|
145
145
|
# Add some images, text, and footage to our manifest.
|
146
146
|
manifest << Assets::Image.new("http://website.com/picture.png")
|
147
147
|
manifest << Assets::Image.new("http://website.com/hooray.png", :spotlit => true)
|
148
148
|
manifest << Assets::TitleCard.new("Woohoo!", "Hooray for everything!")
|
149
149
|
manifest << Assets::Footage.new("http://website.com/movie.mp4", :duration => 3.5)
|
150
|
-
|
150
|
+
|
151
151
|
# Setup the soundtrack.
|
152
152
|
manifest << Assets::Song.new("http://website.com/song.mp3")
|
153
153
|
|
154
154
|
# Request a new directing job by sending the API our directing manifest.
|
155
155
|
directing_job = client.direct!(manifest)
|
156
|
-
|
156
|
+
|
157
157
|
# Poll the service until the directing job is done.
|
158
158
|
while directing_job.pending?
|
159
159
|
sleep(30)
|
160
160
|
client.reload!(directing_job)
|
161
161
|
end
|
162
162
|
|
163
|
-
# If the directing job finished successfully, there will be a "storyboard"
|
163
|
+
# If the directing job finished successfully, there will be a "storyboard"
|
164
164
|
# associated with this job.
|
165
165
|
if storyboard = directing_job.storyboard
|
166
|
-
|
166
|
+
|
167
167
|
# Now it's time to render the storyboard into a video. First we create
|
168
168
|
# a rendering manifest.
|
169
169
|
manifest = Manifests::Rendering.new(
|
@@ -172,10 +172,10 @@ status.
|
|
172
172
|
:framerate => 24,
|
173
173
|
:format => 'h264'
|
174
174
|
)
|
175
|
-
|
175
|
+
|
176
176
|
# Send the manifest to the API.
|
177
177
|
rendering_job = client.render!(manifest)
|
178
|
-
|
178
|
+
|
179
179
|
# Poll the service until the rendering job is done
|
180
180
|
while rendering_job.pending?
|
181
181
|
sleep(30)
|
@@ -192,7 +192,7 @@ status.
|
|
192
192
|
raise rendering_job.errors.first
|
193
193
|
end
|
194
194
|
else
|
195
|
-
# Looks like there was a problem. Perhaps one of the assets wasn't
|
195
|
+
# Looks like there was a problem. Perhaps one of the assets wasn't
|
196
196
|
# retrieved or was corrupt...
|
197
197
|
raise directing_job.errors.first
|
198
198
|
end
|
@@ -208,17 +208,17 @@ be rendered.
|
|
208
208
|
|
209
209
|
require 'animoto/client'
|
210
210
|
include Animoto
|
211
|
-
|
211
|
+
|
212
212
|
client = Client.new("key", "secret")
|
213
|
-
|
213
|
+
|
214
214
|
# Make a directing manifest and direct it as detailed above.
|
215
215
|
# Afterwards, we can make a StoryboardBundling manifest and bundle up the
|
216
216
|
# storyboard we just made.
|
217
|
-
|
217
|
+
|
218
218
|
storyboard = directing_job.storyboard
|
219
219
|
bundling_manifest = Manifests::StoryboardBundling.new(storyboard)
|
220
220
|
bundling_job = client.bundle!(bundling_manifest)
|
221
|
-
|
221
|
+
|
222
222
|
# Poll the service until the bundling job is complete.
|
223
223
|
# As with all jobs, HTTP callbacks are also supported, but we're just
|
224
224
|
# going for a simple example here.
|
@@ -226,33 +226,33 @@ be rendered.
|
|
226
226
|
sleep(30)
|
227
227
|
client.reload!(bundling_job)
|
228
228
|
end
|
229
|
-
|
229
|
+
|
230
230
|
# The bundle_url returned points to where you can download the storyboard
|
231
231
|
# bundle. Downloading the bundle and archiving it elsewhere is outside the
|
232
232
|
# scope of the client's functionality.
|
233
233
|
puts bundling_job.bundle_url
|
234
|
-
|
234
|
+
|
235
235
|
# After you have a handle for the storyboard bundle, the original storyboard
|
236
236
|
# can be deleted.
|
237
237
|
client.delete!(storyboard)
|
238
|
-
|
238
|
+
|
239
239
|
Turning a bundle back into a storyboard is just as simple.
|
240
240
|
|
241
241
|
require 'animoto/client'
|
242
242
|
include Animoto
|
243
|
-
|
243
|
+
|
244
244
|
client = Client.new("key", "secret")
|
245
|
-
|
245
|
+
|
246
246
|
# Make a storyboard unbundling manifest with the url to your archived storyboard bundle.
|
247
|
-
unbundling_manifest =
|
247
|
+
unbundling_manifest = Manifests::StoryboardUnbundling.new(:bundle_url => "http://your-storage-solution.com/path/to/your/bundle")
|
248
248
|
unbundling_job = client.unbundle!(unbundling_manifest)
|
249
|
-
|
249
|
+
|
250
250
|
# Poll the service until unbundling is complete.
|
251
251
|
while unbundling_job.pending?
|
252
252
|
sleep(30)
|
253
253
|
client.reload!(unbundling_job)
|
254
254
|
end
|
255
|
-
|
255
|
+
|
256
256
|
# Now you can use the storyboard to render a video.
|
257
257
|
rendering_manifest = Manifests::Rendering.new(
|
258
258
|
unbundling_job.storyboard,
|
@@ -261,9 +261,9 @@ Turning a bundle back into a storyboard is just as simple.
|
|
261
261
|
:format => 'h264'
|
262
262
|
)
|
263
263
|
rendering_job = client.render!(rendering_manifest)
|
264
|
-
|
264
|
+
|
265
265
|
# Now proceed with using your render as detailed above.
|
266
|
-
|
266
|
+
|
267
267
|
|
268
268
|
<a name="how_to_contribute"></a>
|
269
269
|
## How to contribute to this client
|
@@ -279,21 +279,21 @@ on coding standards, new features, etc.
|
|
279
279
|
|
280
280
|
## Copyright Information
|
281
281
|
|
282
|
-
Copyright © 2010 Animoto Inc. All rights reserved.
|
282
|
+
Copyright © 2010 Animoto Inc. All rights reserved.
|
283
283
|
|
284
|
-
Notice – this software is owned by Animoto Inc. (“Animoto”) and is being licensed to you in source code form on the condition that you comply these terms. By continuing to use the software, you are agreeing to be bound by these terms. If you disagree with these terms, you must immediately stop using the software and permanently destroy it, or return it to Animoto.
|
284
|
+
Notice – this software is owned by Animoto Inc. (“Animoto”) and is being licensed to you in source code form on the condition that you comply these terms. By continuing to use the software, you are agreeing to be bound by these terms. If you disagree with these terms, you must immediately stop using the software and permanently destroy it, or return it to Animoto.
|
285
285
|
|
286
|
-
Animoto hereby grants to you a limited, personal, worldwide, nontransferable license to copy, execute, compile, reproduce, modify, prepare and have prepared derivative works of the software solely for the Purpose. The “Purpose” shall mean use of the software for accessing the Animoto Application Programming Interface (“API”) in accordance with Animoto’s Terms of Service, and any other terms and conditions applicable to your Animoto user account.
|
286
|
+
Animoto hereby grants to you a limited, personal, worldwide, nontransferable license to copy, execute, compile, reproduce, modify, prepare and have prepared derivative works of the software solely for the Purpose. The “Purpose” shall mean use of the software for accessing the Animoto Application Programming Interface (“API”) in accordance with Animoto’s Terms of Service, and any other terms and conditions applicable to your Animoto user account.
|
287
287
|
|
288
|
-
For purposes of clarity, you agree that you have no right to use the software for any other purpose other than the Purpose as defined above. This license does not include the right to distribute, transfer, sell, or otherwise commercialize the software or any portion thereof.
|
288
|
+
For purposes of clarity, you agree that you have no right to use the software for any other purpose other than the Purpose as defined above. This license does not include the right to distribute, transfer, sell, or otherwise commercialize the software or any portion thereof.
|
289
289
|
|
290
|
-
To the extent you make any derivative works from software, you hereby grant back to Animoto a worldwide, irrevocable, perpetual, sublicenseable, assignable, royalty-free license to such derivative works, in source and object code form.
|
290
|
+
To the extent you make any derivative works from software, you hereby grant back to Animoto a worldwide, irrevocable, perpetual, sublicenseable, assignable, royalty-free license to such derivative works, in source and object code form.
|
291
291
|
|
292
|
-
You agree to include these terms in all copies made of the software, and to not remove or alter the above copyright notice or these terms in such copies.
|
292
|
+
You agree to include these terms in all copies made of the software, and to not remove or alter the above copyright notice or these terms in such copies.
|
293
293
|
|
294
|
-
THIS SOFTWARE IS PROVIDED "AS IS," WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, OR THE WARRANTY OF NON-INFRINGEMENT.
|
294
|
+
THIS SOFTWARE IS PROVIDED "AS IS," WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, OR THE WARRANTY OF NON-INFRINGEMENT.
|
295
295
|
|
296
|
-
IN NO EVENT SHALL ANIMOTO BE LIABLE TO YOU OR ANY THIRD PARTY FOR ANY SPECIAL, PUNITIVE, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING, WITHOUT LIMITATION, THOSE RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ANIMOTO HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OF THIS SOFTWARE.
|
296
|
+
IN NO EVENT SHALL ANIMOTO BE LIABLE TO YOU OR ANY THIRD PARTY FOR ANY SPECIAL, PUNITIVE, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING, WITHOUT LIMITATION, THOSE RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ANIMOTO HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OF THIS SOFTWARE.
|
297
297
|
|
298
298
|
You agree to indemnify defend and hold Animoto, its parents, subsidiaries, affiliates, officers and employees, harmless from any liabilities, claims, expenses or demands, including reasonable attorneys’ fees and costs, made by any third party due to or arising out of your use of this software, derivative works created by you, the violation of laws, rules, regulations or these terms, and the infringement of any intellectual property right by your derivative works or by you.
|
299
299
|
|
data/lib/animoto.rb
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
require 'animoto/styles'
|
2
|
+
require 'animoto/postroll'
|
3
|
+
require 'animoto/postrolls/custom_footage'
|
4
|
+
|
1
5
|
module Animoto
|
2
6
|
module Manifests
|
3
7
|
class Directing < Animoto::Manifests::Base
|
@@ -7,10 +11,14 @@ module Animoto
|
|
7
11
|
attr_accessor :title
|
8
12
|
|
9
13
|
# The pacing, representing how quickly the visuals elements will be cycled.
|
10
|
-
# Valid values are '
|
14
|
+
# Valid values are 'very_slow', 'slow', 'moderate', 'fast', 'very_fast' and 'auto'.
|
15
|
+
# Faster songs will naturally cycle through images faster than slower songs. The
|
16
|
+
# 'moderate' pacing is about 4 beats per image. With 'auto', Animoto's cinematic
|
17
|
+
# artificial intelligence will decide what pacing will be best. The default pacing
|
18
|
+
# is 'auto'.
|
11
19
|
# @return [String]
|
12
20
|
attr_accessor :pacing
|
13
|
-
|
21
|
+
|
14
22
|
# The array of visual objects in this manifest.
|
15
23
|
# @return [Array<Assets::Base,Assets::TitleCard>]
|
16
24
|
attr_reader :visuals
|
@@ -19,23 +27,31 @@ module Animoto
|
|
19
27
|
# @return [Assets::Song]
|
20
28
|
attr_reader :song
|
21
29
|
|
22
|
-
# The 'style' for this video.
|
30
|
+
# The 'style' for this video. Available styles are listed in {Animoto::Styles}.
|
31
|
+
# Your partner account might have different styles available from those listed.
|
23
32
|
# @return [String]
|
24
|
-
|
33
|
+
attr_accessor :style
|
34
|
+
|
35
|
+
# The 'postroll' for this video. Postrolls are the short video 'outro' segements
|
36
|
+
# that play when the main video is finished.
|
37
|
+
# @return [Animoto::Postroll]
|
38
|
+
attr_reader :postroll
|
25
39
|
|
26
40
|
# Creates a new directing manifest.
|
27
41
|
#
|
28
|
-
# @param [Hash] options
|
42
|
+
# @param [Hash{Symbol=>Object}] options
|
29
43
|
# @option options [String] :title the title of this project
|
30
|
-
# @option options [String] :pacing ('
|
44
|
+
# @option options [String] :pacing ('auto') the pacing for this project
|
45
|
+
# @option options [String,Animoto::Postroll] :postroll the postroll for this project
|
31
46
|
# @option options [String] :http_callback_url a URL to receive a callback when this job is done
|
32
47
|
# @option options [String] :http_callback_format the format of the callback
|
33
48
|
# @return [Manifests::Directing] the manifest
|
34
49
|
def initialize options = {}
|
35
50
|
super
|
36
51
|
@title = options[:title]
|
37
|
-
@pacing = options[:pacing]
|
38
|
-
@style =
|
52
|
+
@pacing = options[:pacing] || 'auto'
|
53
|
+
@style = options[:style] || Animoto::Styles::ORIGINAL
|
54
|
+
@postroll = Animoto::Postroll.new(options[:postroll] || Animoto::Postroll::POWERED_BY_ANIMOTO)
|
39
55
|
@visuals = []
|
40
56
|
@song = nil
|
41
57
|
end
|
@@ -108,6 +124,14 @@ module Animoto
|
|
108
124
|
self
|
109
125
|
end
|
110
126
|
|
127
|
+
# Sets the postroll for this project.
|
128
|
+
#
|
129
|
+
# @param [String,Animoto::Postroll] roll a postroll object or the postroll's template name
|
130
|
+
# @return [Animoto::Postroll]
|
131
|
+
def postroll= roll
|
132
|
+
@postroll = Animoto::Postroll.new(roll)
|
133
|
+
end
|
134
|
+
|
111
135
|
# Returns a representation of this manifest as a Hash.
|
112
136
|
#
|
113
137
|
# @return [Hash{String=>Object}] the manifest as a Hash
|
@@ -116,18 +140,18 @@ module Animoto
|
|
116
140
|
hash = { 'directing_job' => { 'directing_manifest' => {} } }
|
117
141
|
job = hash['directing_job']
|
118
142
|
add_callback_information job
|
119
|
-
manifest
|
120
|
-
manifest['style']
|
121
|
-
manifest['pacing']
|
122
|
-
manifest['
|
123
|
-
manifest['
|
143
|
+
manifest = job['directing_manifest']
|
144
|
+
manifest['style'] = style
|
145
|
+
manifest['pacing'] = pacing if pacing
|
146
|
+
manifest['postroll'] = postroll.to_hash if postroll
|
147
|
+
manifest['title'] = title if title
|
148
|
+
manifest['visuals'] = []
|
124
149
|
visuals.each do |visual|
|
125
150
|
manifest['visuals'] << visual.to_hash
|
126
151
|
end
|
127
152
|
manifest['song'] = song.to_hash if song
|
128
153
|
hash
|
129
154
|
end
|
130
|
-
|
131
155
|
end
|
132
156
|
end
|
133
|
-
end
|
157
|
+
end
|
@@ -18,6 +18,12 @@ module Animoto
|
|
18
18
|
# The storyboard this rendering targets.
|
19
19
|
# @return [Resources::Storyboard]
|
20
20
|
attr_accessor :storyboard
|
21
|
+
|
22
|
+
# If streaming is set to true, a "live" stream will be made available to watch while the
|
23
|
+
# video is rendering via HTTP Live Streaming. This stream URL will be exposed on the
|
24
|
+
# associated {Resources::Jobs::Rendering rendering job}.
|
25
|
+
# @return [Boolean]
|
26
|
+
attr_writer :streaming
|
21
27
|
|
22
28
|
# Creates a new rendering manifest.
|
23
29
|
#
|
@@ -36,8 +42,19 @@ module Animoto
|
|
36
42
|
@resolution = options[:resolution]
|
37
43
|
@framerate = options[:framerate]
|
38
44
|
@format = options[:format]
|
45
|
+
@streaming = options[:streaming]
|
46
|
+
# We may or may not ever support other streaming formats
|
47
|
+
@streaming_format = "http_live_streaming"
|
39
48
|
end
|
40
49
|
|
50
|
+
# Returns true if an HTTP Live Streaming URL will be created for this video while it's
|
51
|
+
# rendering.
|
52
|
+
#
|
53
|
+
# @return [Boolean]
|
54
|
+
def streaming?
|
55
|
+
@streaming
|
56
|
+
end
|
57
|
+
|
41
58
|
# Returns a representation of this manifest as a Hash.
|
42
59
|
#
|
43
60
|
# @return [Hash{String=>Object}] this manifest as a Hash
|
@@ -52,8 +69,12 @@ module Animoto
|
|
52
69
|
params['resolution'] = resolution
|
53
70
|
params['framerate'] = framerate
|
54
71
|
params['format'] = format
|
72
|
+
if streaming?
|
73
|
+
params['streaming_parameters'] = {}
|
74
|
+
params['streaming_parameters']['format'] = @streaming_format
|
75
|
+
end
|
55
76
|
hash
|
56
77
|
end
|
57
78
|
end
|
58
79
|
end
|
59
|
-
end
|
80
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Animoto
|
2
|
+
class Postroll
|
3
|
+
# Constructs a new postroll. If given a Postroll object, returns
|
4
|
+
# it. Otherwise, passes the arguments to the constructor for this
|
5
|
+
# Postroll class.
|
6
|
+
#
|
7
|
+
# @param [Array<Object>] args Postroll objects or constructor params
|
8
|
+
# @return [Animoto::Postroll]
|
9
|
+
def self.new *args
|
10
|
+
args.first.is_a?(self) ? args.first : super
|
11
|
+
end
|
12
|
+
|
13
|
+
# The template name for this postroll.
|
14
|
+
# @return [String]
|
15
|
+
attr_reader :template
|
16
|
+
|
17
|
+
# Creates a new Postroll with the given template name.
|
18
|
+
#
|
19
|
+
# @param [String] template the template name
|
20
|
+
# @return [Animoto::Postroll]
|
21
|
+
def initialize template
|
22
|
+
@template = template
|
23
|
+
end
|
24
|
+
|
25
|
+
# Returns a representation of this postroll as a hash.
|
26
|
+
# @return [Hash{String=>Object}]
|
27
|
+
def to_hash
|
28
|
+
{'template' => @template}
|
29
|
+
end
|
30
|
+
|
31
|
+
POWERED_BY_ANIMOTO = new("powered_by_animoto").freeze
|
32
|
+
WHITE_LABEL = new("white_label").freeze
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'animoto/postroll'
|
2
|
+
|
3
|
+
module Animoto
|
4
|
+
class Postroll
|
5
|
+
class CustomFootage < Animoto::Postroll
|
6
|
+
|
7
|
+
# The URL to a video to insert into this custom footage postroll.
|
8
|
+
# @return [String]
|
9
|
+
attr_accessor :source_url
|
10
|
+
|
11
|
+
# Creates a new postroll with custom footage at the supplied
|
12
|
+
# URL.
|
13
|
+
#
|
14
|
+
# @param [String] source_url a url to a video file to be inserted into
|
15
|
+
# this custom postroll template
|
16
|
+
# @return [Animoto::Postroll::CustomFootage]
|
17
|
+
def initialize source_url
|
18
|
+
super("custom_footage")
|
19
|
+
@source_url = source_url
|
20
|
+
end
|
21
|
+
|
22
|
+
# Returns a representation of this postroll as a hash.
|
23
|
+
#
|
24
|
+
# @return [Hash{String=>Object}]
|
25
|
+
def to_hash
|
26
|
+
super.merge({'source_url' => source_url})
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -9,7 +9,8 @@ module Animoto
|
|
9
9
|
links = unpack_links(body)
|
10
10
|
super.merge({
|
11
11
|
:storyboard_url => links['storyboard'],
|
12
|
-
:video_url => links['video']
|
12
|
+
:video_url => links['video'],
|
13
|
+
:stream_url => links['stream']
|
13
14
|
})
|
14
15
|
end
|
15
16
|
|
@@ -36,6 +37,13 @@ module Animoto
|
|
36
37
|
# @return [Resources::Video]
|
37
38
|
attr_reader :video
|
38
39
|
|
40
|
+
# If available, the URL where the video can be watched 'live' via HTTP Live Streaming.
|
41
|
+
#
|
42
|
+
# @note this attribute may not be available when this job is created. If you poll the
|
43
|
+
# job while it's rendering, the URL will appear when the stream is available to view.
|
44
|
+
# @return [String]
|
45
|
+
attr_reader :stream_url
|
46
|
+
|
39
47
|
# @return [Jobs::DirectingAndRendering]
|
40
48
|
# @see Animoto::Jobs::Base#instantiate
|
41
49
|
def instantiate attributes = {}
|
@@ -43,10 +51,11 @@ module Animoto
|
|
43
51
|
@storyboard = Animoto::Resources::Storyboard.new(:url => @storyboard_url) if @storyboard_url
|
44
52
|
@video_url = attributes[:video_url]
|
45
53
|
@video = Animoto::Resources::Video.new(:url => @video_url) if @video_url
|
54
|
+
@stream_url = attributes[:stream_url]
|
46
55
|
super
|
47
56
|
end
|
48
57
|
|
49
58
|
end
|
50
59
|
end
|
51
60
|
end
|
52
|
-
end
|
61
|
+
end
|
@@ -9,7 +9,8 @@ module Animoto
|
|
9
9
|
links = unpack_links(body)
|
10
10
|
super.merge({
|
11
11
|
:storyboard_url => links['storyboard'],
|
12
|
-
:video_url => links['video']
|
12
|
+
:video_url => links['video'],
|
13
|
+
:stream_url => links['stream']
|
13
14
|
})
|
14
15
|
end
|
15
16
|
|
@@ -30,6 +31,13 @@ module Animoto
|
|
30
31
|
# @note This URL points to the video *resource* and not the actual video *file*.
|
31
32
|
# @return [String]
|
32
33
|
attr_reader :video_url
|
34
|
+
|
35
|
+
# If available, the URL where the video can be watched 'live' via HTTP Live Streaming.
|
36
|
+
#
|
37
|
+
# @note this attribute may not be available when the job is first created. If you poll
|
38
|
+
# the job while it's rendering, the URL will appear when the stream is available to view.
|
39
|
+
# @return [String]
|
40
|
+
attr_reader :stream_url
|
33
41
|
|
34
42
|
# @return [Jobs::Rendering]
|
35
43
|
# @see Animoto::Jobs::Base#instantiate
|
@@ -38,10 +46,11 @@ module Animoto
|
|
38
46
|
@storyboard = Animoto::Resources::Storyboard.new(:url => @storyboard_url) if @storyboard_url
|
39
47
|
@video_url = attributes[:video_url]
|
40
48
|
@video = Animoto::Resources::Video.new(:url => @video_url) if @video_url
|
49
|
+
@stream_url = attributes[:stream_url]
|
41
50
|
super
|
42
51
|
end
|
43
52
|
|
44
53
|
end
|
45
54
|
end
|
46
55
|
end
|
47
|
-
end
|
56
|
+
end
|
@@ -18,6 +18,7 @@ module Animoto
|
|
18
18
|
:download_url => links['file'],
|
19
19
|
:storyboard_url => links['storyboard'],
|
20
20
|
:cover_image_url => links['cover_image'],
|
21
|
+
:stream_url => links['stream'],
|
21
22
|
:format => params['format'],
|
22
23
|
:framerate => params['framerate'],
|
23
24
|
:resolution => params['resolution']
|
@@ -36,10 +37,14 @@ module Animoto
|
|
36
37
|
# @return [Resources::Storyboard]
|
37
38
|
attr_reader :storyboard
|
38
39
|
|
39
|
-
#
|
40
|
+
# If available, the URL to the cover image file.
|
40
41
|
# @return [String]
|
41
42
|
attr_reader :cover_image_url
|
42
43
|
|
44
|
+
# If available, the URL where this video can be watched via HTTP Live Streaming.
|
45
|
+
# @return [String]
|
46
|
+
attr_reader :stream_url
|
47
|
+
|
43
48
|
# The format of the video.
|
44
49
|
# @return [String]
|
45
50
|
attr_reader :format
|
@@ -57,6 +62,7 @@ module Animoto
|
|
57
62
|
# @param [Hash{Symbol=>Object}] attributes
|
58
63
|
# @option attributes [String] :download_url the URL where this video can be downloaded
|
59
64
|
# @option attributes [String] :storyboard_url the URL for this video's storyboard
|
65
|
+
# @option attributes [String] :stream_url the URL for this video's HTTP Live Streaming playlist
|
60
66
|
# @option attributes [String] :format the format of this video
|
61
67
|
# @option attributes [Integer] :framerate the framerate of this video
|
62
68
|
# @option attributes [String] :resolution the vertical resolution of this video
|
@@ -67,6 +73,7 @@ module Animoto
|
|
67
73
|
@storyboard_url = attributes[:storyboard_url]
|
68
74
|
@storyboard = Animoto::Resources::Storyboard.new(:url => @storyboard_url) if @storyboard_url
|
69
75
|
@cover_image_url = attributes[:cover_image_url]
|
76
|
+
@stream_url = attributes[:stream_url]
|
70
77
|
@format = attributes[:format]
|
71
78
|
@framerate = attributes[:framerate]
|
72
79
|
@resolution = attributes[:resolution]
|
@@ -75,4 +82,4 @@ module Animoto
|
|
75
82
|
|
76
83
|
end
|
77
84
|
end
|
78
|
-
end
|
85
|
+
end
|
@@ -11,22 +11,62 @@ describe Animoto::Manifests::Directing do
|
|
11
11
|
manifest(:title => "Funderful Wonderment").title.should == "Funderful Wonderment"
|
12
12
|
end
|
13
13
|
|
14
|
-
it "should default to '
|
15
|
-
manifest.pacing.should == '
|
14
|
+
it "should default to 'auto' pacing" do
|
15
|
+
manifest.pacing.should == 'auto'
|
16
16
|
end
|
17
17
|
|
18
18
|
it "should be able to specify the pacing with a :pacing parameter" do
|
19
|
-
manifest(:pacing => '
|
19
|
+
manifest(:pacing => 'fast').pacing.should == 'fast'
|
20
20
|
end
|
21
21
|
|
22
22
|
it "should default to 'original' style" do
|
23
|
-
manifest.style.should ==
|
23
|
+
manifest.style.should == Animoto::Styles::ORIGINAL
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should be able to specify the style with a :style parameter" do
|
27
|
+
manifest(:style => Animoto::Styles::VINTAGE).style.should == Animoto::Styles::VINTAGE
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should default to having the 'powered by animoto' postroll" do
|
31
|
+
manifest.postroll.should == Animoto::Postroll::POWERED_BY_ANIMOTO
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should be able to specify the postroll with a :postroll parameter" do
|
35
|
+
manifest(:postroll => Animoto::Postroll::WHITE_LABEL).postroll.should == Animoto::Postroll::WHITE_LABEL
|
24
36
|
end
|
25
37
|
|
26
|
-
it "should default to having
|
38
|
+
it "should default to having no visuals" do
|
27
39
|
manifest.visuals.should be_empty
|
28
40
|
end
|
29
41
|
end
|
42
|
+
|
43
|
+
describe "setting the postroll" do
|
44
|
+
before do
|
45
|
+
@manifest = manifest()
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "with a string" do
|
49
|
+
before do
|
50
|
+
@postroll = "fancy"
|
51
|
+
@manifest.postroll = @postroll
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should set the postroll to a new postroll object with the given template" do
|
55
|
+
@manifest.postroll.template.should == @postroll
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "with another Postroll" do
|
60
|
+
before do
|
61
|
+
@postroll = Animoto::Postroll::CustomFootage.new("http://postrollz.com/postroll.mp4")
|
62
|
+
@manifest.postroll = @postroll
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should set the postroll to the given postroll object" do
|
66
|
+
@manifest.postroll.should eql(@postroll)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
30
70
|
|
31
71
|
describe "adding assets" do
|
32
72
|
describe "using the append operator" do
|
@@ -119,6 +159,11 @@ describe Animoto::Manifests::Directing do
|
|
119
159
|
manifest.to_hash['directing_job']['directing_manifest'].should have_key('song')
|
120
160
|
manifest.to_hash['directing_job']['directing_manifest']['song'].should be_a(Hash)
|
121
161
|
end
|
162
|
+
|
163
|
+
it "should have a 'postroll' object in the manifest" do
|
164
|
+
manifest.to_hash['directing_job']['directing_manifest'].should have_key('postroll')
|
165
|
+
manifest.to_hash['directing_job']['directing_manifest']['postroll'].should be_a(Hash)
|
166
|
+
end
|
122
167
|
|
123
168
|
describe "when the callback url is set" do
|
124
169
|
before do
|
@@ -170,4 +215,4 @@ describe Animoto::Manifests::Directing do
|
|
170
215
|
end
|
171
216
|
end
|
172
217
|
end
|
173
|
-
end
|
218
|
+
end
|
@@ -36,6 +36,10 @@ describe Animoto::Manifests::Rendering do
|
|
36
36
|
manifest.http_callback_url.should == "http://website.com/callback"
|
37
37
|
manifest.http_callback_format.should == 'xml'
|
38
38
|
end
|
39
|
+
|
40
|
+
it "should take a :streaming parameter to set streaming" do
|
41
|
+
manifest(:streaming => true).streaming?.should be_true
|
42
|
+
end
|
39
43
|
end
|
40
44
|
|
41
45
|
describe "generating a hash" do
|
@@ -43,7 +47,7 @@ describe Animoto::Manifests::Rendering do
|
|
43
47
|
@storyboard = Animoto::Resources::Storyboard.new
|
44
48
|
@url = "http://platform.animoto.com/storyboards/1"
|
45
49
|
@storyboard.instance_variable_set(:@url, @url)
|
46
|
-
manifest(@storyboard, :resolution => "720p", :framerate => 24, :format => 'flv')
|
50
|
+
manifest(@storyboard, :resolution => "720p", :framerate => 24, :format => 'flv', :streaming => true)
|
47
51
|
end
|
48
52
|
|
49
53
|
it "should have a top-level 'rendering_job' object" do
|
@@ -82,6 +86,21 @@ describe Animoto::Manifests::Rendering do
|
|
82
86
|
it "should have a 'format' key" do
|
83
87
|
@profile['format'].should == manifest.format
|
84
88
|
end
|
89
|
+
|
90
|
+
describe "streaming parameters" do
|
91
|
+
before do
|
92
|
+
@streaming_params = manifest.to_hash['rendering_job']['rendering_manifest']['rendering_parameters']['streaming_parameters']
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should be present if streaming is enabled" do
|
96
|
+
@streaming_params.should_not be_nil
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should have a 'format' key with the streaming format" do
|
100
|
+
@streaming_params.should have_key('format')
|
101
|
+
@streaming_params['format'].should == manifest.instance_variable_get(:@streaming_format)
|
102
|
+
end
|
103
|
+
end
|
85
104
|
end
|
86
105
|
|
87
106
|
describe "when an HTTP callback is set" do
|
@@ -112,4 +131,4 @@ describe Animoto::Manifests::Rendering do
|
|
112
131
|
end
|
113
132
|
end
|
114
133
|
end
|
115
|
-
end
|
134
|
+
end
|
@@ -24,7 +24,8 @@ describe Animoto::Resources::Jobs::DirectingAndRendering do
|
|
24
24
|
'state' => 'completed',
|
25
25
|
'links' => {
|
26
26
|
'self' => 'http://animoto.com/jobs/directing_and_rendering/1',
|
27
|
-
'video' => 'http://animoto.com/videos/1'
|
27
|
+
'video' => 'http://animoto.com/videos/1',
|
28
|
+
'stream' => 'http://animoto.com/streams/1.m3u8'
|
28
29
|
}
|
29
30
|
}
|
30
31
|
}
|
@@ -41,5 +42,9 @@ describe Animoto::Resources::Jobs::DirectingAndRendering do
|
|
41
42
|
@job.video.should be_an_instance_of(Animoto::Resources::Video)
|
42
43
|
@job.video.url.should == @job.video_url
|
43
44
|
end
|
45
|
+
|
46
|
+
it "should set its stream_url from the 'stream' link given" do
|
47
|
+
@job.stream_url.should == 'http://animoto.com/streams/1.m3u8'
|
48
|
+
end
|
44
49
|
end
|
45
|
-
end
|
50
|
+
end
|
@@ -27,7 +27,8 @@ describe Animoto::Resources::Jobs::Rendering do
|
|
27
27
|
'links' => {
|
28
28
|
'self' => 'http://animoto.com/jobs/rendering/1',
|
29
29
|
'storyboard' => 'http://animoto.com/storyboards/1',
|
30
|
-
'video' => 'http://animoto.com/videos/1'
|
30
|
+
'video' => 'http://animoto.com/videos/1',
|
31
|
+
'stream' => 'http://animoto.com/streams/1.m3u8'
|
31
32
|
}
|
32
33
|
}
|
33
34
|
}
|
@@ -53,5 +54,9 @@ describe Animoto::Resources::Jobs::Rendering do
|
|
53
54
|
@job.video.should be_an_instance_of(Animoto::Resources::Video)
|
54
55
|
@job.video.url.should == @job.video_url
|
55
56
|
end
|
57
|
+
|
58
|
+
it "should set its stream url from the 'stream' link given" do
|
59
|
+
@job.stream_url.should == 'http://animoto.com/streams/1.m3u8'
|
60
|
+
end
|
56
61
|
end
|
57
62
|
end
|
@@ -30,7 +30,8 @@ describe Animoto::Resources::Video do
|
|
30
30
|
'self' => 'https://platform.animoto.com/videos/1',
|
31
31
|
'file' => 'http://storage.com/videos/1.mp4',
|
32
32
|
'cover_image' => 'http://storage.com/videos/1/cover_image.jpg',
|
33
|
-
'storyboard' => 'https://platform.animoto.com/storyboards/1'
|
33
|
+
'storyboard' => 'https://platform.animoto.com/storyboards/1',
|
34
|
+
'stream' => 'http://animoto.com/streams/1.m3u8'
|
34
35
|
}
|
35
36
|
}
|
36
37
|
}
|
@@ -51,13 +52,17 @@ describe Animoto::Resources::Video do
|
|
51
52
|
@video.cover_image_url.should == 'http://storage.com/videos/1/cover_image.jpg'
|
52
53
|
end
|
53
54
|
|
54
|
-
it "should set its storyboard url from the '
|
55
|
+
it "should set its storyboard url from the 'storyboard' link given" do
|
55
56
|
@video.storyboard_url.should == 'https://platform.animoto.com/storyboards/1'
|
56
57
|
end
|
57
58
|
|
58
59
|
it "should set its storyboard from its storyboard url" do
|
59
60
|
@video.storyboard.url.should == 'https://platform.animoto.com/storyboards/1'
|
60
61
|
end
|
62
|
+
|
63
|
+
it "should set its stream url from the 'stream' link given" do
|
64
|
+
@video.stream_url.should == 'http://animoto.com/streams/1.m3u8'
|
65
|
+
end
|
61
66
|
|
62
67
|
it "should set its format from the format given" do
|
63
68
|
@video.format.should == 'h264'
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: animoto
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: 3
|
5
|
+
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 1.
|
8
|
+
- 5
|
9
|
+
- 0
|
10
|
+
version: 1.5.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Animoto
|
@@ -15,8 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date:
|
19
|
-
default_executable:
|
18
|
+
date: 2012-01-18 00:00:00 Z
|
20
19
|
dependencies:
|
21
20
|
- !ruby/object:Gem::Dependency
|
22
21
|
name: json
|
@@ -70,6 +69,8 @@ files:
|
|
70
69
|
- ./lib/animoto/manifests/rendering.rb
|
71
70
|
- ./lib/animoto/manifests/storyboard_bundling.rb
|
72
71
|
- ./lib/animoto/manifests/storyboard_unbundling.rb
|
72
|
+
- ./lib/animoto/postroll.rb
|
73
|
+
- ./lib/animoto/postrolls/custom_footage.rb
|
73
74
|
- ./lib/animoto/resources/base.rb
|
74
75
|
- ./lib/animoto/resources/jobs/base.rb
|
75
76
|
- ./lib/animoto/resources/jobs/directing.rb
|
@@ -82,6 +83,7 @@ files:
|
|
82
83
|
- ./lib/animoto/response_parsers/base.rb
|
83
84
|
- ./lib/animoto/response_parsers/json_adapter.rb
|
84
85
|
- ./lib/animoto/response_parsers/yajl_adapter.rb
|
86
|
+
- ./lib/animoto/styles.rb
|
85
87
|
- ./lib/animoto/support/content_type.rb
|
86
88
|
- ./lib/animoto/support/dynamic_class_loader.rb
|
87
89
|
- ./lib/animoto/support/errors.rb
|
@@ -115,7 +117,6 @@ files:
|
|
115
117
|
- ./spec/animoto/support/standard_envelope_spec.rb
|
116
118
|
- ./spec/animoto_spec.rb
|
117
119
|
- ./spec/spec_helper.rb
|
118
|
-
has_rdoc: true
|
119
120
|
homepage: http://animoto.com
|
120
121
|
licenses: []
|
121
122
|
|
@@ -145,7 +146,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
145
146
|
requirements: []
|
146
147
|
|
147
148
|
rubyforge_project:
|
148
|
-
rubygems_version: 1.
|
149
|
+
rubygems_version: 1.8.12
|
149
150
|
signing_key:
|
150
151
|
specification_version: 3
|
151
152
|
summary: Client for working with the Animoto RESTful HTTP API
|