File size: 1,765 Bytes
4553650 9f13621 3748deb 9f13621 bdffcf8 99149d9 60bcf8d 99149d9 3748deb 99149d9 96c379c 60bcf8d 3748deb bdffcf8 dd55ec1 9f13621 a227b91 9f13621 dd55ec1 bae3e66 3748deb bae3e66 9f13621 3748deb bae3e66 3748deb bae3e66 60bcf8d 9f13621 96d4a31 bdffcf8 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
defmodule MedicalTranscription.Transcription do
@moduledoc """
Takes a path to an audio file and transcribes it to text.
"""
# Ideas for future exploration:
# - Instead of storing the long description vectors in a binary file on disk, we could store them within a vector DB
# (such as pgvector or Pinecone.io)
# - A potential improvement would be to not code each chunk of transcribed audio separately, but to instead gather
# complete sentences based on punctuation. We may want to suggest codes for the entire audio as a single piece as
# well
def stream_transcription_and_search(live_view_pid, audio_file_path) do
# audio transcription + semantic search
summary_text =
audio_file_path
|> stream_transcription()
|> Enum.reduce("", fn {chunk, index}, acc ->
send_result(chunk, index + 1, live_view_pid)
acc <> chunk.text
end)
summary_chunk = %{
text: summary_text,
start_timestamp_seconds: nil,
end_timestamp_seconds: nil
}
send_result(summary_chunk, 0, live_view_pid)
end
defp stream_transcription(audio_file_path) do
MedicalTranscription.TranscriptionServing
|> Nx.Serving.batched_run({:file, audio_file_path})
|> Stream.with_index()
end
defp send_result(chunk, index, live_view_pid) do
result = %{
id: index,
start_mark: format_timestamp(chunk.start_timestamp_seconds),
end_mark: format_timestamp(chunk.end_timestamp_seconds),
text: chunk.text
}
send(live_view_pid, {:transcription_row, result})
end
defp format_timestamp(seconds) when is_nil(seconds), do: nil
defp format_timestamp(seconds) do
seconds |> round() |> Time.from_seconds_after_midnight() |> Time.to_string()
end
end
|