100 lines
3.1 KiB
Elixir
100 lines
3.1 KiB
Elixir
defmodule WhisperWeb.VadLive do
|
|
use WhisperWeb, :live_view
|
|
alias Phoenix.PubSub
|
|
require Logger
|
|
|
|
def mount(_, _, socket) do
|
|
PubSub.subscribe(Whisper.PubSub, "transcription")
|
|
|
|
socket =
|
|
socket
|
|
|> assign(:started, false)
|
|
|> assign(:transcription_chunks, %{})
|
|
|
|
{:ok, socket}
|
|
end
|
|
|
|
def handle_event("start_vad", _params, socket) do
|
|
push_event(socket, "init-vad", %{})
|
|
{:noreply,
|
|
socket
|
|
|> assign(:started, true)
|
|
|> assign(:transcription_chunks, %{})}
|
|
end
|
|
|
|
|
|
def handle_info({:transcription_tiny, raw_json}, socket) do
|
|
case Jason.decode!(raw_json) do
|
|
%{"chunks" => [%{"text" => text, "id" => id}]} ->
|
|
new_chunks =
|
|
Map.update(
|
|
socket.assigns.transcription_chunks,
|
|
id,
|
|
%{text: text, type: :tiny},
|
|
fn existing -> existing end
|
|
)
|
|
|
|
{:noreply, assign(socket, :transcription_chunks, new_chunks)}
|
|
|
|
other ->
|
|
Logger.error("⚠️ Formato inesperado tiny: #{inspect(other)}")
|
|
{:noreply, socket}
|
|
end
|
|
end
|
|
|
|
def handle_info({:transcription_large, raw_json}, socket) do
|
|
case Jason.decode!(raw_json) do
|
|
%{"chunks" => [%{"text" => text, "id" => id}]} ->
|
|
new_chunks =
|
|
Map.put(
|
|
socket.assigns.transcription_chunks,
|
|
id,
|
|
%{text: text, type: :large}
|
|
)
|
|
|
|
{:noreply, assign(socket, :transcription_chunks, new_chunks)}
|
|
|
|
other ->
|
|
Logger.error("⚠️ Formato inesperado large: #{inspect(other)}")
|
|
{:noreply, socket}
|
|
end
|
|
end
|
|
|
|
def render(assigns) do
|
|
~H"""
|
|
<%= if !@started do %>
|
|
<div id="vad-container" phx-hook="VadHook">
|
|
<button phx-click="start_vad" class="btn btn-primary">🎙 Iniciar VAD</button>
|
|
</div>
|
|
<% end %>
|
|
<div id="vad-status" class="mt-4 text-sm text-gray-700"></div>
|
|
|
|
<div id="transcriptionContainer" class="w-full max-w-2xl space-y-4">
|
|
<%= if map_size(@transcription_chunks) > 0 do %>
|
|
<div class="p-4 bg-white rounded shadow-md">
|
|
<h2 class="text-sm font-semibold text-gray-700 mb-2">
|
|
📝 Transcripción corregida en tiempo real
|
|
</h2>
|
|
<p class="text-sm font-medium leading-relaxed break-words">
|
|
<%= for {_id, %{text: text, type: type}} <- Enum.sort_by(@transcription_chunks, fn {id, _} ->
|
|
id |> String.split("_") |> List.last() |> String.to_integer()
|
|
end) do %>
|
|
<span class={
|
|
case type do
|
|
:tiny -> "text-orange-600"
|
|
:large -> "text-green-600"
|
|
end
|
|
}>
|
|
<%= String.replace(text, "\n", " ") %>
|
|
</span>
|
|
<% end %>
|
|
</p>
|
|
</div>
|
|
<% end %>
|
|
</div>
|
|
"""
|
|
end
|
|
|
|
|
|
end
|