diff --git a/.gitignore b/.gitignore index 92938cf..05db607 100644 --- a/.gitignore +++ b/.gitignore @@ -407,3 +407,4 @@ FodyWeavers.xsd # JetBrains Rider *.sln.iml +src/AIHub/appsettings.Development.json \ No newline at end of file diff --git a/src/AIHub/Controllers/AudioTranscriptionController.cs b/src/AIHub/Controllers/AudioTranscriptionController.cs new file mode 100644 index 0000000..ee8ff40 --- /dev/null +++ b/src/AIHub/Controllers/AudioTranscriptionController.cs @@ -0,0 +1,210 @@ +namespace MVCWeb.Controllers; +using System; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Threading.Tasks; +using Newtonsoft.Json; +using Microsoft.AspNetCore.Mvc; +using System.Net; +using Newtonsoft.Json.Linq; +using Microsoft.VisualBasic; + +public class AudioTranscriptionController : Controller +{ + private readonly ILogger _logger; + private readonly IConfiguration _config; + private string SpeechRegion; + private string SpeechSubscriptionKey; + private string storageconnstring; + private readonly BlobServiceClient blobServiceClient; + private readonly BlobContainerClient containerClient; + private readonly IEnumerable blobs; + private Uri sasUri; + + + //Results + string result_message_front; + + + + private AudioTranscriptionModel model; + + + public AudioTranscriptionController(IConfiguration config) + { + _config = config; + SpeechRegion = _config.GetValue("AudioTranscription:SpeechLocation"); + SpeechSubscriptionKey = _config.GetValue("AudioTranscription:SpeechSubscriptionKey"); + storageconnstring = _config.GetValue("Storage:ConnectionString"); + BlobServiceClient blobServiceClient = new BlobServiceClient(storageconnstring); + containerClient = blobServiceClient.GetBlobContainerClient(_config.GetValue("AudioTranscription:ContainerName")); + sasUri = containerClient.GenerateSasUri(Azure.Storage.Sas.BlobContainerSasPermissions.Read, DateTimeOffset.UtcNow.AddHours(1)); + // Obtiene una lista de blobs en el contenedor + blobs = containerClient.GetBlobs(); + model = new AudioTranscriptionModel(); + } + + public IActionResult AudioTranscription() + { + return View(); + } + + [HttpPost] + public async Task TranscribeAudio(string audio_url, IFormFile imageFile) + { + + string audio = audio_url + sasUri.Query; + + // CALL 1: STT 3.1 + + var client = new HttpClient(); + var request = new HttpRequestMessage(HttpMethod.Post, "https://"+SpeechRegion+".api.cognitive.microsoft.com/speechtotext/v3.1/transcriptions"); + request.Headers.Add("Ocp-Apim-Subscription-Key", SpeechSubscriptionKey); + var content = new StringContent("{\r\n\"contentUrls\": [\r\n \"" + audio + "\"\r\n ],\r\n \"locale\": \"es-es\",\r\n \"displayName\": \"My Transcription\",\r\n \"model\": null,\r\n \"properties\": {\r\n \"wordLevelTimestampsEnabled\": true,\r\n \"languageIdentification\": {\r\n \"candidateLocales\": [\r\n \"en-US\", \"de-DE\", \"es-ES\"\r\n ]\r\n }\r\n }\r\n}", null, "application/json"); + request.Content = content; + var response = await client.SendAsync(request); + response.EnsureSuccessStatusCode(); + //Console.WriteLine(await response.Content.ReadAsStringAsync()); + var responsejson = JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync()); + Console.WriteLine(responsejson); + var output_result = responsejson.self.ToString(); + Console.WriteLine("SELF: "+output_result); + + client.Dispose(); + + // CALL 2: CHECK FOR FINISH + var client2 = new HttpClient(); + var request2 = new HttpRequestMessage(HttpMethod.Get, output_result); + client2.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", SpeechSubscriptionKey); + var content2 = new StringContent(string.Empty); + content2.Headers.ContentType = new MediaTypeHeaderValue("application/json"); + request2.Content = content2; + var response2 = await client2.SendAsync(request2); + response2.EnsureSuccessStatusCode(); + //Console.WriteLine(await response2.Content.ReadAsStringAsync()); + var responsejson2 = JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync()); + Console.WriteLine(responsejson2); + while (responsejson2.status != "Succeeded") + { + Thread.Sleep(10000); + response2 = await client2.GetAsync(output_result); + responsejson2 = JsonConvert.DeserializeObject(await response2.Content.ReadAsStringAsync()); + Console.WriteLine(responsejson2.status); + } + client2.Dispose(); + + + // CALL 3: GET RESULTS URL + + var client3 = new HttpClient(); + var request3 = new HttpRequestMessage(HttpMethod.Get, output_result+"/files/"); + request3.Headers.Add("Ocp-Apim-Subscription-Key", SpeechSubscriptionKey); + var content3 = new StringContent(string.Empty); + content3.Headers.ContentType = new MediaTypeHeaderValue("application/json"); + request3.Content = content3; + var response3 = await client3.SendAsync(request3); + response3.EnsureSuccessStatusCode(); + var responsejson3 = JsonConvert.DeserializeObject(await response3.Content.ReadAsStringAsync()); + Console.WriteLine(responsejson3); + // Extract contentUrl field + string output_result3 = (string)responsejson3["values"][0]["links"]["contentUrl"]; + Console.WriteLine(output_result3); + client3.Dispose(); + + // CALL 4: GET RESULTS (TRANSCRIPTION) + + var client4 = new HttpClient(); + var request4 = new HttpRequestMessage(HttpMethod.Get, output_result3); + request4.Headers.Add("Ocp-Apim-Subscription-Key", SpeechSubscriptionKey); + var content4 = new StringContent(string.Empty); + content4.Headers.ContentType = new MediaTypeHeaderValue("application/json"); + request4.Content = content4; + var response4 = await client4.SendAsync(request4); + response4.EnsureSuccessStatusCode(); + Console.WriteLine(await response4.Content.ReadAsStringAsync()); + var jsonObject4 = JsonConvert.DeserializeObject(await response4.Content.ReadAsStringAsync()); + string output_result4 = (string)jsonObject4["combinedRecognizedPhrases"][0]["lexical"]; + Console.WriteLine(output_result4); + client4.Dispose(); + + + //Show transcript results + ViewBag.Message = "TRANSCRIPTION RESULTS: \n\n"+output_result4; + + + return View("AudioTranscription", model); + } + public class SpeechToTextResponse + { + [JsonProperty("text")] + public string Text { get; set; } + } + + //Upload a file to my azure storage account + [HttpPost] + public async Task UploadFile(IFormFile imageFile, string prompt) + { + //Check no image + + if (CheckNullValues(imageFile)) + { + ViewBag.Message = "You must upload an mp3 audio file"; + return View("AudioTranscription"); + } + + //Upload file to azure storage account + string url = imageFile.FileName.ToString(); + //Console.WriteLine(url); + url = url.Replace(" ", ""); + //Console.WriteLine(url); + BlobClient blobClient = containerClient.GetBlobClient(url); + var httpHeaders = new BlobHttpHeaders + { + ContentType = "audio/mpeg", + }; + await blobClient.UploadAsync(imageFile.OpenReadStream(), new BlobUploadOptions { HttpHeaders = httpHeaders }); + + //Get the url of the file + Uri blobUrl = blobClient.Uri; + + if (CheckImageExtension(blobUrl.ToString())) + { + ViewBag.Message = "You must upload an audio file with .mp3 extension"; + return View("AudioTranscription", model); + } + + + //Call EvaluateImage with the url + await TranscribeAudio(blobUrl.ToString(), imageFile); + ViewBag.Waiting = null; + + return View("AudioTranscription", model); + } + + + + [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] + public IActionResult Error() + { + return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier }); + } + + private bool CheckNullValues(IFormFile imageFile) + { + if (imageFile == null) + { + return true; + } + return false; + } + + private bool CheckImageExtension(string blobUri) + { + string uri_lower = blobUri; + if (uri_lower.Contains(".mp3", StringComparison.OrdinalIgnoreCase)) + { + return false; + } + return true; + } +} \ No newline at end of file diff --git a/src/AIHub/Models/AudioTranscriptionModel.cs b/src/AIHub/Models/AudioTranscriptionModel.cs new file mode 100644 index 0000000..ce999ce --- /dev/null +++ b/src/AIHub/Models/AudioTranscriptionModel.cs @@ -0,0 +1,14 @@ +namespace MVCWeb.Models; + +public class AudioTranscriptionModel +{ + + public int? Severity { get; set; } + public int? Violence { get; set; } + public int? SelfHarm { get; set; } + public int? Hate { get; set; } + public string? Prompt { get; set; } + public string? Image { get; set; } + public string? Message { get; set; } + +} \ No newline at end of file diff --git a/src/AIHub/Views/AudioTranscription/AudioTranscription.cshtml b/src/AIHub/Views/AudioTranscription/AudioTranscription.cshtml new file mode 100644 index 0000000..d610a85 --- /dev/null +++ b/src/AIHub/Views/AudioTranscription/AudioTranscription.cshtml @@ -0,0 +1,72 @@ +@{ + ViewData["Title"] = "Audio Trancription"; +} + +
+ + + +

Audio Transcription

+

Analiza tus audios usando Azure AI Speech

+

Sólo necesitas subir un audio (.mp3).

+ +
+ +@if (ViewBag.Message != null) +{ +
+
+ +
+
+} +
+ @*
+ +
+ + +
+ + *@ + +
+ +
+
+ +
+
+ + + +
+ +
diff --git a/src/AIHub/Views/Home/Index.cshtml b/src/AIHub/Views/Home/Index.cshtml index b05a692..36dfcb1 100644 --- a/src/AIHub/Views/Home/Index.cshtml +++ b/src/AIHub/Views/Home/Index.cshtml @@ -22,6 +22,18 @@ +
  • + +
    + + + +

    Audio Transcription

    +

    Transcribe audio files

    +
    +
    +
  • @@ -48,6 +60,8 @@
  • + + -
      +
    • diff --git a/src/AIHub/Views/Shared/_Layout.cshtml b/src/AIHub/Views/Shared/_Layout.cshtml index 2b3cac6..6200f39 100644 --- a/src/AIHub/Views/Shared/_Layout.cshtml +++ b/src/AIHub/Views/Shared/_Layout.cshtml @@ -30,6 +30,10 @@ Chat on your data
    • + @@ -86,7 +90,7 @@
      - © 2023 - Customer Success Unit Spain - Authors: Roberto Arocha, Hector Blasco, Monica Calleja, Ane Iturzaeta - Privacy + © 2024 - Customer Success Unit Spain - Authors: Roberto Arocha, Hector Blasco, Monica Calleja, Ane Iturzaeta - Privacy
      diff --git a/src/AIHub/appsettings.Development.json b/src/AIHub/appsettings.Development.json index 0c208ae..1b2d3ba 100644 --- a/src/AIHub/appsettings.Development.json +++ b/src/AIHub/appsettings.Development.json @@ -5,4 +5,4 @@ "Microsoft.AspNetCore": "Warning" } } -} +} \ No newline at end of file diff --git a/src/AIHub/appsettings.template.json b/src/AIHub/appsettings.template.json index 0204b61..1563ad8 100644 --- a/src/AIHub/appsettings.template.json +++ b/src/AIHub/appsettings.template.json @@ -19,6 +19,11 @@ "OpenAIEndpoint": "", "OpenAISubscriptionKey": "" }, + "AudioTranscription": { + "SpeechLocation": "westeurope", + "SpeechSubscriptionKey": "", + "ContainerName": "audio-files" + }, "ImageAnalyzer": { "VisionEndpoint": "", "OCREndpoint": "", diff --git a/src/AIHub/wwwroot/images/icon1.svg b/src/AIHub/wwwroot/images/icon1.svg deleted file mode 100644 index 2dfb953..0000000 --- a/src/AIHub/wwwroot/images/icon1.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/AIHub/wwwroot/images/icon2.svg b/src/AIHub/wwwroot/images/icon2.svg deleted file mode 100644 index bda7e97..0000000 --- a/src/AIHub/wwwroot/images/icon2.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/AIHub/wwwroot/images/icon3.svg b/src/AIHub/wwwroot/images/icon3.svg deleted file mode 100644 index 8a87a13..0000000 --- a/src/AIHub/wwwroot/images/icon3.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/AIHub/wwwroot/images/icon4.svg b/src/AIHub/wwwroot/images/icon4.svg deleted file mode 100644 index 068af1b..0000000 --- a/src/AIHub/wwwroot/images/icon4.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/AIHub/wwwroot/images/icon5.svg b/src/AIHub/wwwroot/images/icon5.svg deleted file mode 100644 index d1be82e..0000000 --- a/src/AIHub/wwwroot/images/icon5.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/AIHub/wwwroot/images/icon6.svg b/src/AIHub/wwwroot/images/icon6.svg deleted file mode 100644 index 0692e0a..0000000 --- a/src/AIHub/wwwroot/images/icon6.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/AIHub/wwwroot/images/icon8.svg b/src/AIHub/wwwroot/images/icon8.svg deleted file mode 100644 index a94a78b..0000000 --- a/src/AIHub/wwwroot/images/icon8.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/AIHub/wwwroot/images/icon9.svg b/src/AIHub/wwwroot/images/icon9.svg deleted file mode 100644 index e27f62e..0000000 --- a/src/AIHub/wwwroot/images/icon9.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file