public async Task ExecuteAsync(WorkerJobHelper <AIJob> jobHelper) { S3Locator inputFile; if (!jobHelper.JobInput.TryGet <S3Locator>(nameof(inputFile), out inputFile)) { throw new Exception("Invalid or missing input file."); } var randomBytes = new byte[16]; new Random().NextBytes(randomBytes); var clientToken = randomBytes.HexEncode(); var base64JobId = Encoding.UTF8.GetBytes(jobHelper.JobAssignmentId).HexEncode(); var rekoParams = new StartCelebrityRecognitionRequest { Video = new Video { S3Object = new Amazon.Rekognition.Model.S3Object { Bucket = inputFile.AwsS3Bucket, Name = inputFile.AwsS3Key } }, ClientRequestToken = clientToken, JobTag = base64JobId, NotificationChannel = new NotificationChannel { RoleArn = Environment.GetEnvironmentVariable("REKO_SNS_ROLE_ARN"), SNSTopicArn = Environment.GetEnvironmentVariable("SNS_TOPIC_ARN") } }; using (var rekognitionClient = new AmazonRekognitionClient()) await rekognitionClient.StartCelebrityRecognitionAsync(rekoParams); }
internal static async Task ProcessJobAssignmentAsync(AwsAiServiceWorkerRequest @event) { var resourceManager = @event.GetAwsV4ResourceManager(); var table = new DynamoDbTable(@event.StageVariables["TableName"]); var jobAssignmentId = @event.JobAssignmentId; try { // 1. Setting job assignment status to RUNNING await UpdateJobAssignmentStatusAsync(resourceManager, table, jobAssignmentId, "RUNNING", null); // 2. Retrieving WorkflowJob var job = await RetrieveJobAsync(resourceManager, table, jobAssignmentId); // 3. Retrieve JobProfile var jobProfile = await RetrieveJobProfileAsync(resourceManager, job); // 4. Retrieve job inputParameters var jobInput = job.JobInput; // 5. Check if we support jobProfile and if we have required parameters in jobInput ValidateJobProfile(jobProfile, jobInput); S3Locator inputFile; if (!jobInput.TryGet <S3Locator>(nameof(inputFile), out inputFile)) { throw new Exception("Invalid or missing input file."); } S3Locator outputLocation; if (!jobInput.TryGet <S3Locator>(nameof(outputLocation), out outputLocation)) { throw new Exception("Invalid or missing output location."); } switch (jobProfile.Name) { case JOB_PROFILE_TRANSCRIBE_AUDIO: string mediaFileUrl; if (!string.IsNullOrWhiteSpace(inputFile.HttpEndpoint)) { mediaFileUrl = inputFile.HttpEndpoint; } else { var bucketLocation = await inputFile.GetBucketLocationAsync(); var s3SubDomain = !string.IsNullOrWhiteSpace(bucketLocation) ? $"s3-{bucketLocation}" : "s3"; mediaFileUrl = $"https://{s3SubDomain}.amazonaws.com/{inputFile.AwsS3Bucket}/{inputFile.AwsS3Key}"; } string mediaFormat; if (mediaFileUrl.EndsWith("mp3", StringComparison.OrdinalIgnoreCase)) { mediaFormat = "mp3"; } else if (mediaFileUrl.EndsWith("mp4", StringComparison.OrdinalIgnoreCase)) { mediaFormat = "mp4"; } else if (mediaFileUrl.EndsWith("wav", StringComparison.OrdinalIgnoreCase)) { mediaFormat = "wav"; } else if (mediaFileUrl.EndsWith("flac", StringComparison.OrdinalIgnoreCase)) { mediaFormat = "flac"; } else { throw new Exception($"Unable to determine media format from input file '{mediaFileUrl}'"); } var transcribeParameters = new StartTranscriptionJobRequest { TranscriptionJobName = "TranscriptionJob-" + jobAssignmentId.Substring(jobAssignmentId.LastIndexOf("/") + 1), LanguageCode = "en-US", Media = new Media { MediaFileUri = mediaFileUrl }, MediaFormat = mediaFormat, OutputBucketName = @event.StageVariables["ServiceOutputBucket"] }; var transcribeService = new AmazonTranscribeServiceClient(); var startJobResponse = await transcribeService.StartTranscriptionJobAsync(transcribeParameters); Logger.Debug(startJobResponse.ToMcmaJson().ToString()); break; case JOB_PROFILE_TRANSLATE_TEXT: var s3Bucket = inputFile.AwsS3Bucket; var s3Key = inputFile.AwsS3Key; GetObjectResponse s3Object; try { s3Object = await inputFile.GetAsync(); } catch (Exception error) { throw new Exception($"Unable to read file in bucket '{s3Bucket}' with key '{s3Key}'.", error); } var inputText = await new StreamReader(s3Object.ResponseStream).ReadToEndAsync(); var translateParameters = new TranslateTextRequest { SourceLanguageCode = jobInput.TryGet("sourceLanguageCode", out string srcLanguageCode) ? srcLanguageCode : "auto", TargetLanguageCode = jobInput.Get <string>("targetLanguageCode"), Text = inputText }; var translateService = new AmazonTranslateClient(); var translateResponse = await translateService.TranslateTextAsync(translateParameters); var s3Params = new PutObjectRequest { BucketName = outputLocation.AwsS3Bucket, Key = (!string.IsNullOrWhiteSpace(outputLocation.AwsS3KeyPrefix) ? outputLocation.AwsS3Key : string.Empty) + Guid.NewGuid() + ".txt", ContentBody = translateResponse.TranslatedText }; var outputS3 = await outputLocation.GetClientAsync(); await outputS3.PutObjectAsync(s3Params); var jobOutput = new JobParameterBag(); jobOutput["outputFile"] = new S3Locator { AwsS3Bucket = s3Params.BucketName, AwsS3Key = s3Params.Key }; Logger.Debug("Updating job assignment"); await UpdateJobAssignmentWithOutputAsync(table, jobAssignmentId, jobOutput); await UpdateJobAssignmentStatusAsync(resourceManager, table, jobAssignmentId, "COMPLETED"); break; case JOB_PROFILE_DETECT_CELEBRITIES: var randomBytes = new byte[16]; new Random().NextBytes(randomBytes); var clientToken = randomBytes.HexEncode(); var base64JobId = Encoding.UTF8.GetBytes(jobAssignmentId).HexEncode(); var rekoParams = new StartCelebrityRecognitionRequest { Video = new Video { S3Object = new Amazon.Rekognition.Model.S3Object { Bucket = inputFile.AwsS3Bucket, Name = inputFile.AwsS3Key } }, ClientRequestToken = clientToken, JobTag = base64JobId, NotificationChannel = new NotificationChannel { RoleArn = REKO_SNS_ROLE_ARN, SNSTopicArn = SNS_TOPIC_ARN } }; var rekognitionClient = new AmazonRekognitionClient(); var startCelebRecognitionResponse = await rekognitionClient.StartCelebrityRecognitionAsync(rekoParams); Logger.Debug(startCelebRecognitionResponse.ToMcmaJson().ToString()); break; } } catch (Exception ex) { Logger.Exception(ex); try { await UpdateJobAssignmentStatusAsync(resourceManager, table, jobAssignmentId, "FAILED", ex.ToString()); } catch (Exception innerEx) { Logger.Exception(innerEx); } } }