1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.opencastproject.transcription.workflowoperation;
22
23 import org.opencastproject.caption.api.CaptionService;
24 import org.opencastproject.job.api.Job;
25 import org.opencastproject.job.api.JobContext;
26 import org.opencastproject.mediapackage.Attachment;
27 import org.opencastproject.mediapackage.MediaPackage;
28 import org.opencastproject.mediapackage.MediaPackageElement;
29 import org.opencastproject.mediapackage.MediaPackageElementFlavor;
30 import org.opencastproject.mediapackage.MediaPackageElementParser;
31 import org.opencastproject.mediapackage.Track;
32 import org.opencastproject.serviceregistry.api.ServiceRegistry;
33 import org.opencastproject.transcription.api.TranscriptionService;
34 import org.opencastproject.workflow.api.AbstractWorkflowOperationHandler;
35 import org.opencastproject.workflow.api.ConfiguredTagsAndFlavors;
36 import org.opencastproject.workflow.api.WorkflowInstance;
37 import org.opencastproject.workflow.api.WorkflowOperationException;
38 import org.opencastproject.workflow.api.WorkflowOperationHandler;
39 import org.opencastproject.workflow.api.WorkflowOperationInstance;
40 import org.opencastproject.workflow.api.WorkflowOperationResult;
41 import org.opencastproject.workflow.api.WorkflowOperationResult.Action;
42 import org.opencastproject.workspace.api.Workspace;
43
44 import org.apache.commons.lang3.StringUtils;
45 import org.osgi.service.component.ComponentContext;
46 import org.osgi.service.component.annotations.Activate;
47 import org.osgi.service.component.annotations.Component;
48 import org.osgi.service.component.annotations.Reference;
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
51
52 @Component(
53 immediate = true,
54 service = WorkflowOperationHandler.class,
55 property = {
56 "service.description=Attach Transcription Workflow Operation Handler",
57 "workflow.operation=attach-watson-transcription"
58 }
59 )
60 public class AttachTranscriptionOperationHandler extends AbstractWorkflowOperationHandler {
61
62
63 private static final Logger logger = LoggerFactory.getLogger(AttachTranscriptionOperationHandler.class);
64
65
66 static final String TRANSCRIPTION_JOB_ID = "transcription-job-id";
67 static final String TARGET_CAPTION_FORMAT = "target-caption-format";
68 static final String TARGET_TYPE = "target-element-type";
69
70
71 private TranscriptionService service = null;
72 private Workspace workspace;
73 private CaptionService captionService;
74
75 @Override
76 @Activate
77 protected void activate(ComponentContext cc) {
78 super.activate(cc);
79 }
80
81 @Override
82 public WorkflowOperationResult start(final WorkflowInstance workflowInstance, JobContext context)
83 throws WorkflowOperationException {
84 MediaPackage mediaPackage = workflowInstance.getMediaPackage();
85 WorkflowOperationInstance operation = workflowInstance.getCurrentOperation();
86
87 logger.debug("Attach transcription for mediapackage {} started", mediaPackage);
88
89
90 String jobId = StringUtils.trimToNull(operation.getConfiguration(TRANSCRIPTION_JOB_ID));
91 if (jobId == null) {
92 throw new WorkflowOperationException(TRANSCRIPTION_JOB_ID + " missing");
93 }
94
95
96 ConfiguredTagsAndFlavors tagsAndFlavors = getTagsAndFlavors(
97 workflowInstance, Configuration.none, Configuration.none, Configuration.many, Configuration.one);
98 ConfiguredTagsAndFlavors.TargetTags targetTagOption = tagsAndFlavors.getTargetTags();
99 MediaPackageElementFlavor targetFlavor = tagsAndFlavors.getSingleTargetFlavor();
100 String captionFormatOption = StringUtils.trimToNull(operation.getConfiguration(TARGET_CAPTION_FORMAT));
101 String typeUnparsed = StringUtils.trimToEmpty(operation.getConfiguration(TARGET_TYPE));
102 MediaPackageElement.Type type = null;
103 if (!typeUnparsed.isEmpty()) {
104
105 for (MediaPackageElement.Type t : MediaPackageElement.Type.values()) {
106 if (t.name().equalsIgnoreCase(typeUnparsed)) {
107 type = t;
108 }
109 }
110 if (type == null || (type != Track.TYPE && type != Attachment.TYPE)) {
111 throw new IllegalArgumentException(String.format("The given type '%s' for mediapackage %s was illegal. Please"
112 + "check the operations' configuration keys.", type, mediaPackage.getIdentifier()));
113 }
114 } else {
115 type = Track.TYPE;
116 }
117
118 try {
119
120 MediaPackageElement original = service.getGeneratedTranscription(mediaPackage.getIdentifier().toString(), jobId,
121 type);
122 MediaPackageElement transcription = original;
123
124
125 if (captionFormatOption != null) {
126 Job job = captionService.convert(transcription, "ibm-watson", captionFormatOption, service.getLanguage());
127 if (!waitForStatus(job).isSuccess()) {
128 throw new WorkflowOperationException("Transcription format conversion job did not complete successfully");
129 }
130 transcription = MediaPackageElementParser.getFromXml(job.getPayload());
131 }
132
133
134 transcription.setFlavor(targetFlavor);
135
136
137 applyTargetTagsToElement(targetTagOption, transcription);
138
139
140 mediaPackage.add(transcription);
141
142 String uri = transcription.getURI().toString();
143 String ext = uri.substring(uri.lastIndexOf("."));
144 transcription.setURI(workspace.moveTo(transcription.getURI(), mediaPackage.getIdentifier().toString(),
145 transcription.getIdentifier(), "captions." + ext));
146 } catch (Exception e) {
147 throw new WorkflowOperationException(e);
148 }
149
150 return createResult(mediaPackage, Action.CONTINUE);
151 }
152
153 @Reference(target = "(provider=ibm.watson)")
154 public void setTranscriptionService(TranscriptionService service) {
155 this.service = service;
156 }
157
158 @Reference
159 public void setWorkspace(Workspace service) {
160 this.workspace = service;
161 }
162
163 @Reference
164 public void setCaptionService(CaptionService service) {
165 this.captionService = service;
166 }
167
168 @Reference
169 @Override
170 public void setServiceRegistry(ServiceRegistry serviceRegistry) {
171 super.setServiceRegistry(serviceRegistry);
172 }
173
174 }
175