Beispiel #1
0
        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);
        }
Beispiel #2
0
        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);
                }
            }
        }