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 (Amberscript)",
59 "workflow.operation=amberscript-start-transcription"
60 }
61 )
62 public class AmberscriptStartTranscriptionOperationHandler extends AbstractWorkflowOperationHandler {
63
64 private static final Logger logger = LoggerFactory.getLogger(AmberscriptStartTranscriptionOperationHandler.class);
65
66
67 static final String LANGUAGE = "language";
68 static final String JOBTYPE = "jobtype";
69 static final String SPEAKER = "speaker";
70 static final String TRANSCRIPTIONTYPE = "transcriptiontype";
71 static final String GLOSSARY = "glossary";
72 static final String TRANSCRIPTIONSTYLE = "transcriptionstyle";
73 static final String TARGETLANGUAGE = "targetlanguage";
74 static final String SKIP_IF_FLAVOR_EXISTS = "skip-if-flavor-exists";
75
76
77 private TranscriptionService service = null;
78
79 @Override
80 @Activate
81 protected void activate(ComponentContext cc) {
82 super.activate(cc);
83 }
84
85 @Override
86 public WorkflowOperationResult start(final WorkflowInstance workflowInstance, JobContext context)
87 throws WorkflowOperationException {
88 MediaPackage mediaPackage = workflowInstance.getMediaPackage();
89 WorkflowOperationInstance operation = workflowInstance.getCurrentOperation();
90
91 String skipOption = StringUtils.trimToNull(operation.getConfiguration(SKIP_IF_FLAVOR_EXISTS));
92 if (skipOption != null) {
93 MediaPackageElement[] mpes = mediaPackage.getElementsByFlavor(MediaPackageElementFlavor.parseFlavor(skipOption));
94 if (mpes != null && mpes.length > 0) {
95 logger.info(
96 "Start transcription operation will be skipped because flavor '{}' already exists in the media package.",
97 skipOption);
98 return createResult(Action.SKIP);
99 }
100 }
101
102 logger.debug("Start transcription for mediapackage '{}'.", mediaPackage);
103
104
105 ConfiguredTagsAndFlavors tagsAndFlavors = getTagsAndFlavors(
106 workflowInstance, Configuration.many, Configuration.many, Configuration.none, Configuration.none);
107 List<String> sourceTagOption = tagsAndFlavors.getSrcTags();
108 List<MediaPackageElementFlavor> sourceFlavorOption = tagsAndFlavors.getSrcFlavors();
109 String language = StringUtils.trimToEmpty(operation.getConfiguration(LANGUAGE));
110 String jobType = StringUtils.trimToEmpty(operation.getConfiguration(JOBTYPE));
111 String speaker = StringUtils.trimToEmpty(operation.getConfiguration(SPEAKER));
112 String transcriptionType = StringUtils.trimToEmpty(operation.getConfiguration(TRANSCRIPTIONTYPE));
113
114
115
116 String glossary = StringUtils.trim(operation.getConfiguration(GLOSSARY));
117 String transcriptionStyle = StringUtils.trimToEmpty(operation.getConfiguration(TRANSCRIPTIONSTYLE));
118
119 String targetLanguage = StringUtils.trim(operation.getConfiguration(TARGETLANGUAGE));
120
121 AbstractMediaPackageElementSelector<Track> elementSelector = new TrackSelector();
122
123
124 if (sourceTagOption.isEmpty() && sourceFlavorOption.isEmpty()) {
125 throw new WorkflowOperationException("No source tag or flavor have been specified!");
126 }
127
128 if (!sourceFlavorOption.isEmpty()) {
129 elementSelector.addFlavor(sourceFlavorOption.get(0));
130 }
131 if (!sourceTagOption.isEmpty()) {
132 elementSelector.addTag(sourceTagOption.get(0));
133 }
134
135 Collection<Track> elements = elementSelector.select(mediaPackage, false);
136 Job job = null;
137 for (Track track : elements) {
138 if (!track.hasAudio()) {
139 logger.info("Track {} from media package {} doesn't contain audio stream. Skip subtitle generation.",
140 track.getFlavor(), mediaPackage.getIdentifier());
141 continue;
142 }
143 try {
144 job = service.startTranscription(mediaPackage.getIdentifier().toString(), track, language, jobType, speaker,
145 transcriptionType, glossary, transcriptionStyle, targetLanguage);
146
147 break;
148 } catch (TranscriptionServiceException e) {
149 throw new WorkflowOperationException(e);
150 }
151 }
152
153 if (job == null) {
154 logger.info("No matching tracks found.");
155 return createResult(mediaPackage, Action.CONTINUE);
156 }
157
158
159 if (!waitForStatus(job).isSuccess()) {
160 throw new WorkflowOperationException("Transcription job did not complete successfully.");
161 }
162
163
164 logger.debug("External transcription job for mediapackage '{}' was created.", mediaPackage);
165
166
167 return createResult(Action.CONTINUE);
168 }
169
170 @Reference(target = "(provider=amberscript)")
171 public void setTranscriptionService(TranscriptionService service) {
172 this.service = service;
173 }
174
175 @Reference
176 @Override
177 public void setServiceRegistry(ServiceRegistry serviceRegistry) {
178 super.setServiceRegistry(serviceRegistry);
179 }
180
181 }