GoogleSpeechTranscriptionService extends AbstractJobProducer implements TranscriptionService { void createRecognitionsJob(String mpId, Track track, String languageCode) throws TranscriptionServiceException, IOException { if (StringUtils.isBlank(languageCode)) { languageCode = defaultLanguage; } String audioUrl; audioUrl = uploadAudioFileToGoogleStorage(mpId, track); CloseableHttpClient httpClient = makeHttpClient(); CloseableHttpResponse response = null; String token = getRefreshAccessToken(); if (token.equals(INVALID_TOKEN) || audioUrl == null) { throw new TranscriptionServiceException("Could not create recognition job. Audio file or access token invalid"); } JSONObject configValues = new JSONObject(); JSONObject audioValues = new JSONObject(); JSONObject container = new JSONObject(); configValues.put("languageCode", languageCode); configValues.put("enableWordTimeOffsets", true); configValues.put("profanityFilter", profanityFilter); audioValues.put("uri", audioUrl); container.put("config", configValues); container.put("audio", audioValues); try { HttpPost httpPost = new HttpPost(UrlSupport.concat(GOOGLE_SPEECH_URL, REQUEST_METHOD)); logger.debug("Url to invoke Google speech service: {}", httpPost.getURI().toString()); StringEntity params = new StringEntity(container.toJSONString()); httpPost.addHeader("Authorization", "Bearer " + token); httpPost.addHeader(HttpHeaders.CONTENT_TYPE, "application/json; charset=utf-8"); httpPost.setEntity(params); response = httpClient.execute(httpPost); int code = response.getStatusLine().getStatusCode(); HttpEntity entity = response.getEntity(); String jsonString = EntityUtils.toString(response.getEntity()); JSONParser jsonParser = new JSONParser(); JSONObject jsonObject = (JSONObject) jsonParser.parse(jsonString); switch (code) { case HttpStatus.SC_OK: logger.info("Recognitions job has been successfully created"); String jobId = (String) jsonObject.get("name"); logger.info( "Transcription for mp {} has been submitted. Job id: {}", mpId, jobId); database.storeJobControl(mpId, track.getIdentifier(), jobId, TranscriptionJobControl.Status.InProgress.name(), track.getDuration() == null ? 0 : track.getDuration().longValue(), null, PROVIDER); EntityUtils.consume(entity); return; default: JSONObject errorObj = (JSONObject) jsonObject.get("error"); logger.warn("Invalid argument returned, status: {} with message: {}", code, (String) errorObj.get("message")); break; } throw new TranscriptionServiceException("Could not create recognition job. Status returned: " + code); } catch (Exception e) { logger.warn("Exception when calling the recognitions endpoint", e); throw new TranscriptionServiceException("Exception when calling the recognitions endpoint", e); } finally { try { httpClient.close(); if (response != null) { response.close(); } } catch (IOException e) { } } } GoogleSpeechTranscriptionService(); void activate(ComponentContext cc); @Override Job startTranscription(String mpId, Track track, String language); @Override Job startTranscription(String mpId, Track track); @Override void transcriptionDone(String mpId, Object obj); @Override String getLanguage(); @Override void transcriptionError(String mpId, Object obj); String getTranscriptionResults(String jobId); @Override MediaPackageElement getGeneratedTranscription(String mpId, String jobId); String getTranscriptionStatus(String mpId); void setServiceRegistry(ServiceRegistry serviceRegistry); void setSecurityService(SecurityService securityService); void setUserDirectoryService(UserDirectoryService userDirectoryService); void setOrganizationDirectoryService(OrganizationDirectoryService organizationDirectoryService); void setSmtpService(SmtpService service); void setWorkspace(Workspace ws); void setWorkingFileRepository(WorkingFileRepository wfr); void setDatabase(TranscriptionDatabase service); void setAssetManager(AssetManager service); void setWorkflowService(WorkflowService service); static final String DEFAULT_WF_DEF; static final String ENABLED_CONFIG; static final String GOOGLE_SPEECH_LANGUAGE; static final String PROFANITY_FILTER; static final String WORKFLOW_CONFIG; static final String DISPATCH_WORKFLOW_INTERVAL_CONFIG; static final String COMPLETION_CHECK_BUFFER_CONFIG; static final String MAX_PROCESSING_TIME_CONFIG; static final String NOTIFICATION_EMAIL_CONFIG; static final String CLEANUP_RESULTS_DAYS_CONFIG; static final String GOOGLE_CLOUD_CLIENT_ID; static final String GOOGLE_CLOUD_CLIENT_SECRET; static final String GOOGLE_CLOUD_REFRESH_TOKEN; static final String GOOGLE_CLOUD_BUCKET; static final String GOOGLE_CLOUD_TOKEN_ENDPOINT_URL; static final String ENCODING_EXTENSION; }
@Test public void testCreateRecognitionsJob() throws Exception { InputStream stream = GoogleSpeechTranscriptionServiceTest.class.getResourceAsStream("/" + IN_PROGRESS_JOB); Capture<String> capturedCollection = Capture.newInstance(); Capture<String> capturedFileName = Capture.newInstance(); EasyMock.expect(workspace.putInCollection(EasyMock.capture(capturedCollection), EasyMock.capture(capturedFileName), EasyMock.anyObject(InputStream.class))).andReturn(new URI("http: EasyMock.replay(workspace); HttpEntity httpEntity = EasyMock.createNiceMock(HttpEntity.class); EasyMock.expect(httpEntity.getContent()).andReturn(stream); CloseableHttpResponse response = EasyMock.createNiceMock(CloseableHttpResponse.class); StatusLine status1 = EasyMock.createNiceMock(StatusLine.class); EasyMock.expect(response.getStatusLine()).andReturn(status1).anyTimes(); EasyMock.expect(response.getEntity()).andReturn(httpEntity).anyTimes(); EasyMock.expect(status1.getStatusCode()).andReturn(HttpStatus.SC_OK).anyTimes(); EasyMock.replay(httpEntity, response, status1); Capture<HttpPost> capturedPost = Capture.newInstance(); EasyMock.expect(httpClient.execute(EasyMock.capture(capturedPost))).andReturn(response).anyTimes(); EasyMock.replay(httpClient); service.createRecognitionsJob(MP_ID, mediaPackage.getTrack("audioTrack1"), LANGUAGE_CODE); Assert.assertEquals("https: capturedPost.getValue().getURI().toString()); TranscriptionJobControl j = database.findByJob(JOB_ID); Assert.assertNotNull(j); Assert.assertEquals(MP_ID, j.getMediaPackageId()); Assert.assertEquals(TRACK_ID, j.getTrackId()); Assert.assertEquals(TranscriptionJobControl.Status.InProgress.name(), j.getStatus()); }
@Test(expected = TranscriptionServiceException.class) public void testCreateRecognitionsJobErrors() throws Exception { EasyMock.expect(workspace.get(EasyMock.anyObject(URI.class))).andReturn(audioFile); EasyMock.replay(workspace); CloseableHttpResponse response = EasyMock.createNiceMock(CloseableHttpResponse.class); StatusLine status = EasyMock.createNiceMock(StatusLine.class); EasyMock.expect(response.getStatusLine()).andReturn(status).anyTimes(); EasyMock.replay(response, status); Capture<HttpPost> capturedPost = Capture.newInstance(); EasyMock.expect(httpClient.execute(EasyMock.capture(capturedPost))).andReturn(response).anyTimes(); EasyMock.replay(httpClient); service.createRecognitionsJob(MP_ID, mediaPackage.getTrack("audioTrack1"), LANGUAGE_CODE); }