Skip to content

AI Integrace OpenAI Whisper do VENFT

Štefan Prokop edited this page Mar 29, 2023 · 3 revisions

V tomto článku je popsáno, jak proběhla základní integrace OpenAI Whisper do VENFT.

obrazek

Pokud jste ještě neslyšeli o integraci OpenAI do VEFrameworku, doporučuji projít si následující články:

Knihovna Betalgo/OpenAI, která je použitá v balíčku VEDriversLite.AI.OpenAI, již obsahuje wrap na API příkaz Whisperu. Díky tomu stačilo přidat jen abstrakci tohoto wrapu do třídy VirtualAssistant.cs. Zde je přidaná funkce:

public async Task<(bool, string)> GetTranscriptionOfAudio(byte[] bytes, string fileName = "")
{
    try
    {
        if (string.IsNullOrEmpty(fileName))
            fileName = $"audio-recording-{DateTime.UtcNow.ToString("yyyy_MM_ddThh-mm-ss")}.mp3";

        var audioResult = await AIService.Audio.CreateTranscription(new AudioCreateTranscriptionRequest
        {
            FileName = fileName,
            File = bytes,
            Model = Models.WhisperV1,
            ResponseFormat = StaticValues.AudioStatics.ResponseFormat.VerboseJson
        });

        if (audioResult.Successful)
        {
            Console.WriteLine(string.Join("\n", audioResult.Text));
            return (true, audioResult.Text);
        }
        else
        {
            if (audioResult.Error == null)
                throw new Exception("Unknown Error");
            
            Console.WriteLine($"{audioResult.Error.Code}: {audioResult.Error.Message}");
        }
    }
    catch (Exception e)
    {
        Console.WriteLine(e);
        throw;
    }
    return (false, string.Empty);
}

Pokud v zadání není uvedený název souboru, automaticky se vytvoří. Při volání tedy není nutné, aby byl název vyplněn. Vstupem by měl být audio soubor ve formě pole bajtů. Zatím se vyzkoušelo posílat na API jen mp3.

Ukázka použití této funkce je k dispozici díky integraci do VENFT App. To proběhlo ve dvou krocích:

  • Přidání Audio nahrávání
  • Přidání propojení kvůli poslání nahrávky do VirtualAssistant

Součástí tohoto repozitáře je návod, jak lze v Blazor aplikaci nahrávat zvuk. Na základě tohoto návodu vznikla komponenta AudioRecorder.razor. Pro správnou funkčnost bylo potřeba přidat i AudioRecorder.js file, který je umístěný zde. Je tedy automaticky součástí VEBlazor knihovny. Nicméně pokud jej chci použít v aplikaci, je potřeba jej přidat do index.html, jako je tomu například zde.

Části komponenty nejsou nijak složité. Vesměs se volají funkce ze skriptu AudioRecorder.js. To jediné, co bylo přidáno, jsou eventy:

[Parameter] public EventCallback<(string, byte[])> OnTranscriptCreated { get; set; }
[Parameter] public EventCallback<VEDriversLite.NFT.Dto.NFTDataItem> OnAudioSaved { get; set; }
[Parameter] public EventCallback<string> OnAudioRecordingStopped { get; set; }
[Parameter] public EventCallback<string> OnAudioRecordingStarted { get; set; }

Jejich pojmenování by mělo být dostatečně popisné. Co může být matoucí, je ukládání nahrávky. Nahrávku je totiž možné nechat automaticky uploadnout na IPFS a získat zpět již jen NFTDataItem. Upload zajišťuje tato funkce.

Transkript/přepis nahrávky do textu se děje ve funkci OnAudioUrl, která je zavolána z js skriptu po obdržení odkazu na nahrávku (odkaz je jen v rámci browser API). V tu chvíli je možné stáhnout nahrávku jako pole bajtů pomocí HttpClient a zažádat AI o přepis:

Jen pro připomenutí - HttpClient je injeknutý na začátku komponenty:

@inject HttpClient http

Zde je funkce pro přepis audia:

[JSInvokable]
public async Task OnAudioUrl(string vUrl)
{
    mUrl = vUrl;

    var bytes = await http.GetByteArrayAsync(mUrl);
    if (bytes != null && bytes.Length > 0)
    {
        lastRecordingBytes = bytes;
        Console.WriteLine("Sending request for transcript of audio...");
        var transcript = await AppData.Assistant.GetTranscriptionOfAudio(bytes);
        Console.WriteLine("Transcript request done.");
        if (transcript.Item1)
        {
            transcriptOfAudio = transcript.Item2;
            await OnTranscriptCreated.InvokeAsync((transcriptOfAudio, bytes));
        }
    }

    if (loadingIndicatorRef != null)
        await loadingIndicatorRef.Hide();

    await InvokeAsync(() => StateHasChanged());
}

Komponenta nyní vypadá následovně:

obrazek

Základní ovládací prvky jsou:

  • Zahájit nahrávání
  • Pozastavit nahrávání
  • Pokračovat v nahrávání
  • Zastavit nahrávání
  • Stáhnout nahrávku jako mp3

Integrace této komponenty proběhla v rámci dvou formulářů, které jsou dost podobné CreateTextByAIButton.razor a CreateMermaidByAIButton.razor.

obrazek

Přidání komponenty je zde. Komponenta má několik eventů (jak již bylo napsáno výše). Je vhodné doplnit referenci, aby bylo možné případně zažádat o uložení souboru na IPFS. To je vidět v event handleru pro OnTranscriptCreated:

async Task OnTranscriptCreatedHandler((string, byte[]) e)
{
    if (!string.IsNullOrEmpty(e.Item1))
    {
        BaseText = e.Item1;
        await InvokeAsync(StateHasChanged);

        if (StoreRecordingAsNFTDataItem)
        {
            if (audioRecorderRef != null)
                await audioRecorderRef.UploadRecordingToIPFS(null);
        }
    }
}

Již nyní je tato nová funkce k dispozici ve VENFT App. Pokud máte OpenAI API klíč, můžete ji zkusit otestovat.

Clone this wiki locally