active_encode 0.0.2

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 (54) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +1 -0
  3. data/.gitignore +16 -0
  4. data/.rubocop.yml +76 -0
  5. data/.travis.yml +10 -0
  6. data/Gemfile +11 -0
  7. data/LICENSE +202 -0
  8. data/README.md +106 -0
  9. data/Rakefile +38 -0
  10. data/active_encode.gemspec +28 -0
  11. data/lib/active_encode.rb +2 -0
  12. data/lib/active_encode/base.rb +16 -0
  13. data/lib/active_encode/callbacks.rb +69 -0
  14. data/lib/active_encode/core.rb +79 -0
  15. data/lib/active_encode/engine_adapter.rb +51 -0
  16. data/lib/active_encode/engine_adapters.rb +27 -0
  17. data/lib/active_encode/engine_adapters/active_job_adapter.rb +23 -0
  18. data/lib/active_encode/engine_adapters/inline_adapter.rb +42 -0
  19. data/lib/active_encode/engine_adapters/matterhorn_adapter.rb +312 -0
  20. data/lib/active_encode/engine_adapters/shingoncoder_adapter.rb +56 -0
  21. data/lib/active_encode/engine_adapters/test_adapter.rb +38 -0
  22. data/lib/active_encode/engine_adapters/zencoder_adapter.rb +143 -0
  23. data/lib/active_encode/status.rb +38 -0
  24. data/lib/active_encode/technical_metadata.rb +11 -0
  25. data/lib/active_encode/version.rb +3 -0
  26. data/spec/fixtures/Bars_512kb.mp4 +0 -0
  27. data/spec/fixtures/matterhorn/cancelled_response.xml +323 -0
  28. data/spec/fixtures/matterhorn/completed_response.xml +4 -0
  29. data/spec/fixtures/matterhorn/create_response.xml +300 -0
  30. data/spec/fixtures/matterhorn/delete_track_response.xml +2 -0
  31. data/spec/fixtures/matterhorn/failed_response.xml +4 -0
  32. data/spec/fixtures/matterhorn/purged_response.xml +342 -0
  33. data/spec/fixtures/matterhorn/running_response.xml +1 -0
  34. data/spec/fixtures/matterhorn/stop_completed_response.xml +228 -0
  35. data/spec/fixtures/matterhorn/stop_running_response.xml +339 -0
  36. data/spec/fixtures/zencoder/job_create.json +1 -0
  37. data/spec/fixtures/zencoder/job_details_cancelled.json +1 -0
  38. data/spec/fixtures/zencoder/job_details_completed.json +1 -0
  39. data/spec/fixtures/zencoder/job_details_create.json +1 -0
  40. data/spec/fixtures/zencoder/job_details_failed.json +73 -0
  41. data/spec/fixtures/zencoder/job_details_running.json +1 -0
  42. data/spec/fixtures/zencoder/job_progress_cancelled.json +13 -0
  43. data/spec/fixtures/zencoder/job_progress_completed.json +13 -0
  44. data/spec/fixtures/zencoder/job_progress_create.json +1 -0
  45. data/spec/fixtures/zencoder/job_progress_failed.json +13 -0
  46. data/spec/fixtures/zencoder/job_progress_running.json +1 -0
  47. data/spec/integration/matterhorn_adapter_spec.rb +186 -0
  48. data/spec/integration/shingoncoder_adapter_spec.rb +152 -0
  49. data/spec/integration/zencoder_adapter_spec.rb +152 -0
  50. data/spec/spec_helper.rb +12 -0
  51. data/spec/units/callbacks_spec.rb +66 -0
  52. data/spec/units/engine_adapter_spec.rb +78 -0
  53. data/spec/units/status_spec.rb +62 -0
  54. metadata +210 -0
@@ -0,0 +1,56 @@
1
+ require 'active_support'
2
+ require 'active_support/core_ext'
3
+
4
+ module ActiveEncode
5
+ module EngineAdapters
6
+ class ShingoncoderAdapter < ZencoderAdapter
7
+ # @param [ActiveEncode::Base] encode
8
+ def create(encode)
9
+ response = Shingoncoder::Job.create(input: encode.input)
10
+ build_encode(job_details(response.body["id"]), encode.class)
11
+ end
12
+
13
+ # @param [Fixnum] id
14
+ # @param [Hash] opts
15
+ # @option opts :cast the class to cast the encoding job to.
16
+ def find(id, opts = {})
17
+ build_encode(job_details(id), opts[:cast])
18
+ end
19
+
20
+ # @param [ActiveEncode::Base] encode
21
+ def cancel(encode)
22
+ response = Shingoncoder::Job.cancel(encode.id)
23
+ build_encode(job_details(encode.id), encode.class) if response.success?
24
+ end
25
+
26
+ private
27
+
28
+ # @param [Fixnum] job_id the identifier for the job
29
+ # @return [Shingoncoder::Response] the response from Shingoncoder
30
+ def job_details(job_id)
31
+ Shingoncoder::Job.details(job_id)
32
+ end
33
+
34
+ # @return [Shingoncoder::Response] the response from Shingoncoder
35
+ def job_progress(job_id)
36
+ Shingoncoder::Job.progress(job_id)
37
+ end
38
+
39
+ # @param [Shingoncoder::Response] job_details
40
+ # @param [Class] cast the class of object to instantiate and return
41
+ def build_encode(job_details, cast)
42
+ return nil if job_details.nil?
43
+ encode = cast.new(convert_input(job_details), convert_options(job_details))
44
+ encode.id = job_details.body["job"]["id"].to_s
45
+ encode.state = convert_state(job_details)
46
+ progress = job_progress(encode.id)
47
+ encode.current_operations = convert_current_operations(progress)
48
+ encode.percent_complete = convert_percent_complete(progress, job_details)
49
+ encode.output = convert_output(job_details)
50
+ encode.errors = convert_errors(job_details)
51
+ encode.tech_metadata = convert_tech_metadata(job_details.body["job"]["input_media_file"])
52
+ encode
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,38 @@
1
+ module ActiveEncode
2
+ module EngineAdapters
3
+ class TestAdapter
4
+ def initialize
5
+ @encodes = {}
6
+ end
7
+
8
+ def create(encode)
9
+ encode.id = SecureRandom.uuid
10
+ @encodes[encode.id] = encode
11
+ encode.state = :running
12
+ encode
13
+ end
14
+
15
+ def find(id, _opts = {})
16
+ @encodes[id]
17
+ end
18
+
19
+ def list(*_filters)
20
+ fail NotImplementedError
21
+ end
22
+
23
+ def cancel(encode)
24
+ e = @encodes[encode.id]
25
+ e.state = :cancelled
26
+ e
27
+ end
28
+
29
+ def purge(encode)
30
+ @encodes.delete(encode.id)
31
+ end
32
+
33
+ def remove_output(_encode, _output_id)
34
+ fail NotImplementedError
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,143 @@
1
+ module ActiveEncode
2
+ module EngineAdapters
3
+ class ZencoderAdapter
4
+ # TODO: add a stub for an input helper (supplied by an initializer) that transforms encode.input into a zencoder accepted url
5
+ def create(encode)
6
+ response = Zencoder::Job.create(input: "#{encode.input}")
7
+ build_encode(get_job_details(response.body["id"]), encode.class)
8
+ end
9
+
10
+ def find(id, opts = {})
11
+ build_encode(get_job_details(id), opts[:cast])
12
+ end
13
+
14
+ def list(*_filters)
15
+ fail NotImplementedError
16
+ end
17
+
18
+ def cancel(encode)
19
+ response = Zencoder::Job.cancel(encode.id)
20
+ build_encode(get_job_details(encode.id), encode.class) if response.success?
21
+ end
22
+
23
+ def purge(_encode)
24
+ fail NotImplementedError
25
+ end
26
+
27
+ def remove_output(_encode, _output_id)
28
+ fail NotImplementedError
29
+ end
30
+
31
+ private
32
+
33
+ def get_job_details(job_id)
34
+ Zencoder::Job.details(job_id)
35
+ end
36
+
37
+ def get_job_progress(job_id)
38
+ Zencoder::Job.progress(job_id)
39
+ end
40
+
41
+ def build_encode(job_details, cast)
42
+ return nil if job_details.nil?
43
+ encode = cast.new(convert_input(job_details), convert_options(job_details))
44
+ encode.id = job_details.body["job"]["id"].to_s
45
+ encode.state = convert_state(job_details)
46
+ job_progress = get_job_progress(encode.id)
47
+ encode.current_operations = convert_current_operations(job_progress)
48
+ encode.percent_complete = convert_percent_complete(job_progress, job_details)
49
+ encode.output = convert_output(job_details)
50
+ encode.errors = convert_errors(job_details)
51
+ encode.tech_metadata = convert_tech_metadata(job_details.body["job"]["input_media_file"])
52
+ encode
53
+ end
54
+
55
+ def convert_state(job_details)
56
+ case job_details.body["job"]["state"]
57
+ when "pending", "waiting", "processing" # Should there be a queued state?
58
+ :running
59
+ when "cancelled"
60
+ :cancelled
61
+ when "failed"
62
+ :failed
63
+ when "finished"
64
+ :completed
65
+ end
66
+ end
67
+
68
+ def convert_current_operations(job_progress)
69
+ current_ops = []
70
+ job_progress.body["outputs"].each { |output| current_ops << output["current_event"] unless output["current_event"].nil? }
71
+ current_ops
72
+ end
73
+
74
+ def convert_percent_complete(job_progress, job_details)
75
+ percent = job_progress.body["progress"]
76
+ percent ||= 100 if convert_state(job_details) == :completed
77
+ percent ||= 0
78
+ percent
79
+ end
80
+
81
+ def convert_input(job_details)
82
+ job_details.body["job"]["input_media_file"]["url"]
83
+ end
84
+
85
+ def convert_options(_job_details)
86
+ {}
87
+ end
88
+
89
+ def convert_output(job_details)
90
+ output = []
91
+ job_details.body["job"]["output_media_files"].each do |o|
92
+ track_id = o["id"].to_s
93
+ label = o["label"]
94
+ url = o["url"]
95
+ output << convert_tech_metadata(o).merge(id: track_id, url: url, label: label)
96
+ end
97
+ output
98
+ end
99
+
100
+ def convert_errors(job_details)
101
+ errors = []
102
+ input_error = job_details.body["job"]["input_media_file"]["error_message"]
103
+ errors << input_error unless input_error.blank?
104
+ job_details.body["job"]["output_media_files"].each { |o| errors << o["error_message"] unless o["error_message"].blank? }
105
+ errors
106
+ end
107
+
108
+ def convert_tech_metadata(media_file)
109
+ return {} if media_file.nil?
110
+
111
+ metadata = {}
112
+ media_file.each_pair do |key, value|
113
+ next if value.blank?
114
+ case key
115
+ when "md5_checksum"
116
+ metadata[:checksum] = value
117
+ when "format"
118
+ metadata[:mime_type] = value
119
+ when "duration_in_ms"
120
+ metadata[:duration] = value.to_s
121
+ when "audio_codec"
122
+ metadata[:audio_codec] = value.to_s
123
+ when "channels"
124
+ metadata[:audio_channels] = value.to_s
125
+ when "audio_bitrate_in_kbps"
126
+ metadata[:audio_bitrate] = value.to_s
127
+ when "video_codec"
128
+ metadata[:video_codec] = value
129
+ when "frame_rate"
130
+ metadata[:video_framerate] = value.to_s
131
+ when "video_bitrate_in_kbps"
132
+ metadata[:video_bitrate] = value.to_s
133
+ when "width"
134
+ metadata[:width] = value.to_s
135
+ when "height"
136
+ metadata[:height] = value.to_s
137
+ end
138
+ end
139
+ metadata
140
+ end
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,38 @@
1
+ require 'active_support'
2
+
3
+ module ActiveEncode
4
+ module Status
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ # Current state of the encoding process
9
+ attr_accessor :state
10
+
11
+ attr_accessor :current_operations
12
+
13
+ attr_accessor :percent_complete
14
+
15
+ attr_accessor :errors
16
+ end
17
+
18
+ def created?
19
+ !id.nil?
20
+ end
21
+
22
+ def cancelled?
23
+ state == :cancelled
24
+ end
25
+
26
+ def completed?
27
+ state == :completed
28
+ end
29
+
30
+ def running?
31
+ state == :running
32
+ end
33
+
34
+ def failed?
35
+ state == :failed
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,11 @@
1
+ require 'active_support'
2
+
3
+ module ActiveEncode
4
+ module TechnicalMetadata
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ attr_accessor :tech_metadata
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ module ActiveEncode
2
+ VERSION = '0.0.2'
3
+ end
Binary file
@@ -0,0 +1,323 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2
+ <workflow xmlns="http://workflow.opencastproject.org" xmlns:ns2="http://org.opencastproject.security" xmlns:ns3="http://mediapackage.opencastproject.org" state="STOPPED" id="cancelled-id">
3
+ <template>full</template>
4
+ <description>A workflow that puts mediapackages on hold</description>
5
+ <parent xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
6
+ <ns2:creator>
7
+ <ns2:userName>matterhorn_system_account</ns2:userName>
8
+ <ns2:roles>MATTERHORN_ADMINISTRATOR</ns2:roles>
9
+ <ns2:roles>ROLE_ADMIN</ns2:roles>
10
+ <ns2:roles>ROLE_ANONYMOUS</ns2:roles>
11
+ <ns2:roles>ROLE_OAUTH_USER</ns2:roles>
12
+ <ns2:roles>ROLE_USER</ns2:roles>
13
+ <ns2:organization>mh_default_org</ns2:organization>
14
+ </ns2:creator>
15
+ <ns2:organization id="mh_default_org">
16
+ <ns2:name>Opencast Project</ns2:name>
17
+ <ns2:servers>
18
+ <ns2:server port="8080" name="localhost"/>
19
+ </ns2:servers>
20
+ <ns2:adminRole>ROLE_ADMIN</ns2:adminRole>
21
+ <ns2:anonymousRole>ROLE_ANONYMOUS</ns2:anonymousRole>
22
+ <ns2:properties>
23
+ <ns2:property key="engageui.link_mobile_redirect.description">For more information have a look at the official site.</ns2:property>
24
+ <ns2:property key="engageui.link_mobile_redirect.url">http://opencast.org/matterhorn/</ns2:property>
25
+ <ns2:property key="engageui.annotations.enable">true</ns2:property>
26
+ <ns2:property key="adminui.series_prepopulate.enable">false</ns2:property>
27
+ <ns2:property key="adminui.i18n_tab_episode.enable">true</ns2:property>
28
+ <ns2:property key="avalon.stream_base">file:///home/cjcolvar/Code/avalon/avalon/red5/webapps/avalon/streams</ns2:property>
29
+ <ns2:property key="engageui.link_download.enable">false</ns2:property>
30
+ <ns2:property key="adminui.chunksize">2024</ns2:property>
31
+ <ns2:property key="logo_large">/engage/ui/img/mh_logos/MatterhornLogo_large.png</ns2:property>
32
+ <ns2:property key="adminui.i18n_tab_users.enable">false</ns2:property>
33
+ <ns2:property key="engageui.link_mobile_redirect.enable">false</ns2:property>
34
+ <ns2:property key="engageui.links_media_module.enable">true</ns2:property>
35
+ <ns2:property key="logo_small">/engage/ui/img/mh_logos/OpencastLogo.png</ns2:property>
36
+ </ns2:properties>
37
+ </ns2:organization>
38
+ <ns3:mediapackage start="2015-04-20T18:01:57Z" id="609312d8-e41b-436f-9499-aedb05125510">
39
+ <ns3:title>Bars_512kb.mp4</ns3:title>
40
+ <ns3:media>
41
+ <ns3:track type="presenter/source" id="de77d14b-d002-465d-8012-838ecf289960">
42
+ <ns3:tags>
43
+ <ns3:tag>archive</ns3:tag>
44
+ </ns3:tags>
45
+ <ns3:url>http://localhost:8080/files/mediapackage/609312d8-e41b-436f-9499-aedb05125510/de77d14b-d002-465d-8012-838ecf289960/Bars_512kb.mp4</ns3:url>
46
+ </ns3:track>
47
+ </ns3:media>
48
+ <ns3:metadata>
49
+ <ns3:catalog type="dublincore/episode" id="9075b60e-b4ce-490b-8c04-7a18bb890db1">
50
+ <ns3:mimetype>text/xml</ns3:mimetype>
51
+ <ns3:tags>
52
+ <ns3:tag>archive</ns3:tag>
53
+ <ns3:tag>engage</ns3:tag>
54
+ </ns3:tags>
55
+ <ns3:url>http://localhost:8080/files/mediapackage/609312d8-e41b-436f-9499-aedb05125510/9075b60e-b4ce-490b-8c04-7a18bb890db1/dublincore.xml</ns3:url>
56
+ </ns3:catalog>
57
+ </ns3:metadata>
58
+ <ns3:attachments/>
59
+ </ns3:mediapackage>
60
+ <operations>
61
+ <operation retry-strategy="none" execution-host="http://localhost:8080" failed-attempts="0" max-attempts="1" continuable="true" abortable="true" fail-on-error="true" description="Hold for workflow selection" state="SUCCEEDED" job="6972" id="append">
62
+ <configurations/>
63
+ <holdurl>/workflow/hold/org.opencastproject.workflow.handler.appendworkflowoperationhandler</holdurl>
64
+ <hold-action-title>Action</hold-action-title>
65
+ <started>1429641937935</started>
66
+ <completed>1429641938521</completed>
67
+ <time-in-queue>0</time-in-queue>
68
+ <execution-history/>
69
+ </operation>
70
+ <operation retry-strategy="none" execution-host="http://localhost:8080" failed-attempts="0" max-attempts="1" exception-handler-workflow="error" fail-on-error="true" description="Applying access control rules" state="SUCCEEDED" job="7341" id="apply-acl">
71
+ <configurations/>
72
+ <started>1429641946745</started>
73
+ <completed>1429641947473</completed>
74
+ <time-in-queue>0</time-in-queue>
75
+ <execution-history/>
76
+ </operation>
77
+ <operation retry-strategy="none" execution-host="http://localhost:8080" failed-attempts="0" max-attempts="1" fail-on-error="true" description="Tagging source material for archival" state="SUCCEEDED" job="7342" id="tag">
78
+ <configurations>
79
+ <configuration key="source-flavors">*/source,dublincore/*,security/*</configuration>
80
+ <configuration key="target-tags">+archive</configuration>
81
+ </configurations>
82
+ <started>1429641955975</started>
83
+ <completed>1429641956685</completed>
84
+ <time-in-queue>0</time-in-queue>
85
+ <execution-history/>
86
+ </operation>
87
+ <operation retry-strategy="none" execution-host="http://localhost:8080" failed-attempts="0" max-attempts="1" fail-on-error="true" description="Tagging dublin core catalogs for publishing" state="SUCCEEDED" job="7343" id="tag">
88
+ <configurations>
89
+ <configuration key="source-flavors">dublincore/*</configuration>
90
+ <configuration key="target-tags">+engage</configuration>
91
+ </configurations>
92
+ <started>1429641965321</started>
93
+ <completed>1429641965842</completed>
94
+ <time-in-queue>0</time-in-queue>
95
+ <execution-history/>
96
+ </operation>
97
+ <operation retry-strategy="none" failed-attempts="0" max-attempts="1" exception-handler-workflow="error" fail-on-error="true" description="Inspecting the media package" state="INSTANTIATED" job="7344" id="inspect">
98
+ <configurations/>
99
+ <execution-history/>
100
+ </operation>
101
+ <operation retry-strategy="none" failed-attempts="0" max-attempts="1" exception-handler-workflow="error" fail-on-error="true" description="Preparing presenter audio and video work versions" state="INSTANTIATED" id="prepare-av">
102
+ <configurations>
103
+ <configuration key="target-flavor">presenter/work</configuration>
104
+ <configuration key="rewrite">false</configuration>
105
+ <configuration key="promiscuous-audio-muxing">true</configuration>
106
+ <configuration key="source-flavor">presenter/source</configuration>
107
+ </configurations>
108
+ <execution-history/>
109
+ </operation>
110
+ <operation retry-strategy="none" failed-attempts="0" max-attempts="1" exception-handler-workflow="error" fail-on-error="true" description="Preparing presentation audio and video work version" state="INSTANTIATED" id="prepare-av">
111
+ <configurations>
112
+ <configuration key="target-flavor">presentation/work</configuration>
113
+ <configuration key="rewrite">false</configuration>
114
+ <configuration key="promiscuous-audio-muxing">true</configuration>
115
+ <configuration key="source-flavor">presentation/source</configuration>
116
+ </configurations>
117
+ <execution-history/>
118
+ </operation>
119
+ <operation retry-strategy="none" failed-attempts="0" max-attempts="1" exception-handler-workflow="error" if="${videoPreview}" fail-on-error="true" description="Encoding presenter (camera) video for preview" state="INSTANTIATED" id="compose">
120
+ <configurations>
121
+ <configuration key="target-flavor">*/preview</configuration>
122
+ <configuration key="encoding-profile">flash-preview.http</configuration>
123
+ <configuration key="source-flavor">*/work</configuration>
124
+ </configurations>
125
+ <execution-history/>
126
+ </operation>
127
+ <operation retry-strategy="none" failed-attempts="0" max-attempts="1" exception-handler-workflow="error" if="${trimHold}" fail-on-error="true" description="Waiting for user to review / trim recording" state="INSTANTIATED" id="trim">
128
+ <configurations>
129
+ <configuration key="encoding-profile">trim.work</configuration>
130
+ <configuration key="target-flavor-subtype">trimmed</configuration>
131
+ <configuration key="source-flavor">*/work</configuration>
132
+ </configurations>
133
+ <execution-history/>
134
+ </operation>
135
+ <operation retry-strategy="none" failed-attempts="0" max-attempts="1" fail-on-error="true" description="Tagging trimmed media for archive" state="INSTANTIATED" id="tag">
136
+ <configurations>
137
+ <configuration key="source-flavors">*/trimmed</configuration>
138
+ <configuration key="target-tags">+archive</configuration>
139
+ </configurations>
140
+ <execution-history/>
141
+ </operation>
142
+ <operation retry-strategy="none" failed-attempts="0" max-attempts="1" exception-handler-workflow="error" if="${captionHold}" fail-on-error="true" description="Waiting for user to upload captions" state="INSTANTIATED" id="caption">
143
+ <configurations>
144
+ <configuration key="target-tags">engage,archive</configuration>
145
+ </configurations>
146
+ <execution-history/>
147
+ </operation>
148
+ <operation retry-strategy="none" failed-attempts="0" max-attempts="1" exception-handler-workflow="error" fail-on-error="true" description="Encoding presenter (camera) to player preview image" state="INSTANTIATED" id="image">
149
+ <configurations>
150
+ <configuration key="source-tags"/>
151
+ <configuration key="target-flavor">presenter/player+preview</configuration>
152
+ <configuration key="time">1</configuration>
153
+ <configuration key="encoding-profile">player-preview.http</configuration>
154
+ <configuration key="target-tags">engage</configuration>
155
+ <configuration key="source-flavor">presenter/trimmed</configuration>
156
+ </configurations>
157
+ <execution-history/>
158
+ </operation>
159
+ <operation retry-strategy="none" failed-attempts="0" max-attempts="1" exception-handler-workflow="error" fail-on-error="true" description="Encoding presentation (screen) to player preview image" state="INSTANTIATED" id="image">
160
+ <configurations>
161
+ <configuration key="source-tags"/>
162
+ <configuration key="target-flavor">presentation/player+preview</configuration>
163
+ <configuration key="time">1</configuration>
164
+ <configuration key="encoding-profile">player-preview.http</configuration>
165
+ <configuration key="target-tags">engage</configuration>
166
+ <configuration key="source-flavor">presentation/trimmed</configuration>
167
+ </configurations>
168
+ <execution-history/>
169
+ </operation>
170
+ <operation retry-strategy="none" failed-attempts="0" max-attempts="1" exception-handler-workflow="error" fail-on-error="true" description="Encoding presenter (camera) video to Flash download" state="INSTANTIATED" id="compose">
171
+ <configurations>
172
+ <configuration key="target-flavor">presenter/delivery</configuration>
173
+ <configuration key="encoding-profile">flash.http</configuration>
174
+ <configuration key="target-tags">engage</configuration>
175
+ <configuration key="source-flavor">presenter/trimmed</configuration>
176
+ </configurations>
177
+ <execution-history/>
178
+ </operation>
179
+ <operation retry-strategy="none" failed-attempts="0" max-attempts="1" exception-handler-workflow="error" fail-on-error="true" description="Encoding presentation (screen) to Flash download" state="INSTANTIATED" id="compose">
180
+ <configurations>
181
+ <configuration key="target-flavor">presentation/delivery</configuration>
182
+ <configuration key="encoding-profile">flash-vga.http</configuration>
183
+ <configuration key="target-tags">engage</configuration>
184
+ <configuration key="source-flavor">presentation/trimmed</configuration>
185
+ </configurations>
186
+ <execution-history/>
187
+ </operation>
188
+ <operation retry-strategy="none" failed-attempts="0" max-attempts="1" exception-handler-workflow="error" fail-on-error="false" description="Encoding presenter (screen) to flash audio download" state="INSTANTIATED" id="compose">
189
+ <configurations>
190
+ <configuration key="target-flavor">presenter/delivery</configuration>
191
+ <configuration key="encoding-profile">flash-audio.http</configuration>
192
+ <configuration key="target-tags">engage</configuration>
193
+ <configuration key="source-flavor">presenter/trimmed</configuration>
194
+ </configurations>
195
+ <execution-history/>
196
+ </operation>
197
+ <operation retry-strategy="none" failed-attempts="0" max-attempts="1" exception-handler-workflow="error" fail-on-error="false" description="Extracting segments from presentation" state="INSTANTIATED" id="segment-video">
198
+ <configurations>
199
+ <configuration key="source-flavor">presentation/trimmed</configuration>
200
+ </configurations>
201
+ <execution-history/>
202
+ </operation>
203
+ <operation retry-strategy="none" failed-attempts="0" max-attempts="1" exception-handler-workflow="error" fail-on-error="true" description="Encoding presenter (camera) to search result preview image" state="INSTANTIATED" id="image">
204
+ <configurations>
205
+ <configuration key="source-tags"/>
206
+ <configuration key="target-flavor">presenter/search+preview</configuration>
207
+ <configuration key="time">1</configuration>
208
+ <configuration key="encoding-profile">search-cover.http</configuration>
209
+ <configuration key="target-tags">engage</configuration>
210
+ <configuration key="source-flavor">presenter/trimmed</configuration>
211
+ </configurations>
212
+ <execution-history/>
213
+ </operation>
214
+ <operation retry-strategy="none" failed-attempts="0" max-attempts="1" exception-handler-workflow="error" fail-on-error="true" description="Encoding presentation (screen) to search result preview image" state="INSTANTIATED" id="image">
215
+ <configurations>
216
+ <configuration key="source-tags"/>
217
+ <configuration key="target-flavor">presentation/search+preview</configuration>
218
+ <configuration key="time">1</configuration>
219
+ <configuration key="encoding-profile">search-cover.http</configuration>
220
+ <configuration key="target-tags">engage</configuration>
221
+ <configuration key="source-flavor">presentation/trimmed</configuration>
222
+ </configurations>
223
+ <execution-history/>
224
+ </operation>
225
+ <operation retry-strategy="none" failed-attempts="0" max-attempts="1" exception-handler-workflow="error" fail-on-error="true" description="Encoding to feed download formats" state="INSTANTIATED" id="compose">
226
+ <configurations>
227
+ <configuration key="target-flavor">*/delivery</configuration>
228
+ <configuration key="encoding-profiles">feed-m4a.http, feed-avi.http</configuration>
229
+ <configuration key="target-tags">rss, atom</configuration>
230
+ <configuration key="source-flavor">*/trimmed</configuration>
231
+ </configurations>
232
+ <execution-history/>
233
+ </operation>
234
+ <operation retry-strategy="none" failed-attempts="0" max-attempts="1" exception-handler-workflow="error" fail-on-error="true" description="Encoding presenter (camera) to feed preview image" state="INSTANTIATED" id="image">
235
+ <configurations>
236
+ <configuration key="source-tags"/>
237
+ <configuration key="target-flavor">presenter/feed+preview</configuration>
238
+ <configuration key="time">1</configuration>
239
+ <configuration key="encoding-profile">feed-cover.http</configuration>
240
+ <configuration key="target-tags">rss, atom</configuration>
241
+ <configuration key="source-flavor">presenter/trimmed</configuration>
242
+ </configurations>
243
+ <execution-history/>
244
+ </operation>
245
+ <operation retry-strategy="none" failed-attempts="0" max-attempts="1" exception-handler-workflow="error" fail-on-error="true" description="Encoding presentation (screen) to feed preview image" state="INSTANTIATED" id="image">
246
+ <configurations>
247
+ <configuration key="source-tags"/>
248
+ <configuration key="target-flavor">presentation/feed+preview</configuration>
249
+ <configuration key="time">1</configuration>
250
+ <configuration key="encoding-profile">feed-cover.http</configuration>
251
+ <configuration key="target-tags">rss, atom</configuration>
252
+ <configuration key="source-flavor">presentation/trimmed</configuration>
253
+ </configurations>
254
+ <execution-history/>
255
+ </operation>
256
+ <operation retry-strategy="none" failed-attempts="0" max-attempts="1" exception-handler-workflow="error" fail-on-error="false" description="Encoding presentation (screen) to segment preview image" state="INSTANTIATED" id="segmentpreviews">
257
+ <configurations>
258
+ <configuration key="source-tags"/>
259
+ <configuration key="target-flavor">presentation/segment+preview</configuration>
260
+ <configuration key="encoding-profile">player-slides.http</configuration>
261
+ <configuration key="reference-flavor">presentation/delivery</configuration>
262
+ <configuration key="target-tags">engage</configuration>
263
+ <configuration key="reference-tags">engage</configuration>
264
+ <configuration key="source-flavor">presentation/trimmed</configuration>
265
+ </configurations>
266
+ <execution-history/>
267
+ </operation>
268
+ <operation retry-strategy="none" failed-attempts="0" max-attempts="1" exception-handler-workflow="error" fail-on-error="false" description="Extracting text from presentation segments" state="INSTANTIATED" id="extract-text">
269
+ <configurations>
270
+ <configuration key="source-tags"/>
271
+ <configuration key="target-tags">engage,archive</configuration>
272
+ <configuration key="source-flavor">presentation/trimmed</configuration>
273
+ </configurations>
274
+ <execution-history/>
275
+ </operation>
276
+ <operation retry-strategy="none" failed-attempts="0" max-attempts="2" exception-handler-workflow="error" fail-on-error="true" description="Distributing to progressive downloads" state="INSTANTIATED" id="distribute-download">
277
+ <configurations>
278
+ <configuration key="source-tags">engage,atom,rss,-publish</configuration>
279
+ <configuration key="target-tags">publish</configuration>
280
+ <configuration key="check-availability">true</configuration>
281
+ </configurations>
282
+ <execution-history/>
283
+ </operation>
284
+ <operation retry-strategy="none" failed-attempts="0" max-attempts="2" exception-handler-workflow="error" if="rtmp://localhost/vod" fail-on-error="true" description="Distributing to streaming server" state="INSTANTIATED" id="distribute-streaming">
285
+ <configurations>
286
+ <configuration key="source-tags">engage,-publish</configuration>
287
+ <configuration key="target-tags">publish</configuration>
288
+ </configurations>
289
+ <execution-history/>
290
+ </operation>
291
+ <operation retry-strategy="none" failed-attempts="0" max-attempts="1" fail-on-error="true" description="Removing archive tag from distributed material" state="INSTANTIATED" id="tag">
292
+ <configurations>
293
+ <configuration key="source-tags">publish</configuration>
294
+ <configuration key="target-tags">-archive</configuration>
295
+ </configurations>
296
+ <execution-history/>
297
+ </operation>
298
+ <operation retry-strategy="none" failed-attempts="0" max-attempts="1" exception-handler-workflow="error" if="${archiveOp}" fail-on-error="true" description="Archiving" state="INSTANTIATED" id="archive">
299
+ <configurations>
300
+ <configuration key="source-tags">archive</configuration>
301
+ </configurations>
302
+ <execution-history/>
303
+ </operation>
304
+ <operation retry-strategy="none" failed-attempts="0" max-attempts="1" exception-handler-workflow="error" fail-on-error="true" description="Publishing" state="INSTANTIATED" id="publish">
305
+ <configurations>
306
+ <configuration key="source-tags">publish</configuration>
307
+ </configurations>
308
+ <execution-history/>
309
+ </operation>
310
+ <operation retry-strategy="none" failed-attempts="0" max-attempts="1" fail-on-error="false" description="Cleaning up" state="INSTANTIATED" id="cleanup">
311
+ <configurations>
312
+ <configuration key="preserve-flavors"/>
313
+ </configurations>
314
+ <execution-history/>
315
+ </operation>
316
+ </operations>
317
+ <configurations>
318
+ <configuration key="workflowSelector">full</configuration>
319
+ <configuration key="distribution">Matterhorn Media Module</configuration>
320
+ <configuration key="archiveOp">true</configuration>
321
+ </configurations>
322
+ <errors/>
323
+ </workflow>