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.job.api.Job;
24 import org.opencastproject.job.api.JobContext;
25 import org.opencastproject.mediapackage.MediaPackage;
26 import org.opencastproject.mediapackage.MediaPackageElement;
27 import org.opencastproject.mediapackage.MediaPackageElementFlavor;
28 import org.opencastproject.mediapackage.Track;
29 import org.opencastproject.mediapackage.selector.AbstractMediaPackageElementSelector;
30 import org.opencastproject.mediapackage.selector.TrackSelector;
31 import org.opencastproject.serviceregistry.api.ServiceRegistry;
32 import org.opencastproject.transcription.api.TranscriptionService;
33 import org.opencastproject.transcription.api.TranscriptionServiceException;
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
43 import org.apache.commons.lang3.StringUtils;
44 import org.osgi.service.component.ComponentContext;
45 import org.osgi.service.component.annotations.Activate;
46 import org.osgi.service.component.annotations.Component;
47 import org.osgi.service.component.annotations.Reference;
48 import org.slf4j.Logger;
49 import org.slf4j.LoggerFactory;
50
51 import java.util.Collection;
52 import java.util.List;
53
54 @Component(
55 immediate = true,
56 service = WorkflowOperationHandler.class,
57 property = {
58 "service.description=Start Transcription Workflow Operation Handler",
59 "workflow.operation=start-watson-transcription"
60 }
61 )
62 public class StartTranscriptionOperationHandler extends AbstractWorkflowOperationHandler {
63
64
65 private static final Logger logger = LoggerFactory.getLogger(StartTranscriptionOperationHandler.class);
66
67
68 static final String SKIP_IF_FLAVOR_EXISTS = "skip-if-flavor-exists";
69
70
71 private TranscriptionService service = null;
72
73 @Override
74 @Activate
75 protected void activate(ComponentContext cc) {
76 super.activate(cc);
77 }
78
79 @Override
80 public WorkflowOperationResult start(final WorkflowInstance workflowInstance, JobContext context)
81 throws WorkflowOperationException {
82 MediaPackage mediaPackage = workflowInstance.getMediaPackage();
83 WorkflowOperationInstance operation = workflowInstance.getCurrentOperation();
84
85 String skipOption = StringUtils.trimToNull(operation.getConfiguration(SKIP_IF_FLAVOR_EXISTS));
86 if (skipOption != null) {
87 MediaPackageElement[] mpes = mediaPackage.getElementsByFlavor(MediaPackageElementFlavor.parseFlavor(skipOption));
88 if (mpes != null && mpes.length > 0) {
89 logger.info(
90 "Start transcription operation will be skipped because flavor {} already exists in the media package",
91 skipOption);
92 return createResult(Action.SKIP);
93 }
94 }
95
96 logger.debug("Start transcription for mediapackage {} started", mediaPackage);
97
98
99 ConfiguredTagsAndFlavors tagsAndFlavors = getTagsAndFlavors(
100 workflowInstance, Configuration.many, Configuration.many, Configuration.none, Configuration.none);
101 List<String> sourceTagOption = tagsAndFlavors.getSrcTags();
102 List<MediaPackageElementFlavor> sourceFlavorOption = tagsAndFlavors.getSrcFlavors();
103
104 AbstractMediaPackageElementSelector<Track> elementSelector = new TrackSelector();
105
106
107 if (sourceTagOption.isEmpty() && sourceFlavorOption.isEmpty()) {
108 throw new WorkflowOperationException("No source tag or flavor have been specified!");
109 }
110
111 if (!sourceFlavorOption.isEmpty()) {
112 MediaPackageElementFlavor flavor = sourceFlavorOption.get(0);
113 elementSelector.addFlavor(flavor);
114 }
115 if (!sourceTagOption.isEmpty()) {
116 elementSelector.addTag(sourceTagOption.get(0));
117 }
118
119 Collection<Track> elements = elementSelector.select(mediaPackage, false);
120 Job job = null;
121 for (Track track : elements) {
122 if (track.hasVideo()) {
123 logger.info("Skipping track {} since it contains a video stream", track);
124 continue;
125 }
126 if (!track.hasAudio()) {
127 logger.info("Track {} from media package {} doesn't contain audio stream. Skip subtitle generation.",
128 track.getFlavor(), mediaPackage.getIdentifier());
129 continue;
130 }
131 try {
132 job = service.startTranscription(mediaPackage.getIdentifier().toString(), track);
133
134 break;
135 } catch (TranscriptionServiceException e) {
136 throw new WorkflowOperationException(e);
137 }
138 }
139
140 if (job == null) {
141 logger.info("No matching tracks found");
142 return createResult(mediaPackage, Action.CONTINUE);
143 }
144
145
146 if (!waitForStatus(job).isSuccess()) {
147 throw new WorkflowOperationException("Transcription job did not complete successfully");
148 }
149
150
151 logger.debug("External transcription job for mediapackage {} was created", mediaPackage);
152
153
154 return createResult(Action.CONTINUE);
155 }
156
157 @Reference(target = "(provider=ibm.watson)")
158 public void setTranscriptionService(TranscriptionService service) {
159 this.service = service;
160 }
161
162 @Reference
163 @Override
164 public void setServiceRegistry(ServiceRegistry serviceRegistry) {
165 super.setServiceRegistry(serviceRegistry);
166 }
167
168 }