Initial Commit
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
defmodule RiverConnectWeb.AudioChannel do
|
||||
use RiverConnectWeb, :channel
|
||||
alias RiverConnect.Audio
|
||||
|
||||
@impl true
|
||||
def join("audio:lobby", _payload, socket) do
|
||||
{:ok, socket}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_in("audio_start", %{"id" => id}, socket) do
|
||||
# Ensure upload directory exists
|
||||
upload_path = Application.app_dir(:river_connect, "priv/static/uploads")
|
||||
File.mkdir_p!(upload_path)
|
||||
|
||||
user_id = socket.assigns[:user_id] || "guest"
|
||||
|
||||
# Create DB record immediately with "recording" status
|
||||
{:ok, message} =
|
||||
Audio.create_message(%{
|
||||
user_id: user_id,
|
||||
file_path: "/uploads/#{id}.webm",
|
||||
status: "recording"
|
||||
})
|
||||
|
||||
# Store temporary file path and message_id in socket assigns
|
||||
temp_file_path = Path.join(upload_path, "#{id}.webm")
|
||||
|
||||
# Broadcast start and new message to other listeners
|
||||
broadcast_from!(socket, "audio_start", %{id: id})
|
||||
broadcast!(socket, "audio_message_created", %{message: message})
|
||||
|
||||
{:noreply,
|
||||
assign(socket, :current_recording, %{id: id, path: temp_file_path, message_id: message.id})}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_in("audio_chunk", {:binary, payload}, socket) do
|
||||
case socket.assigns[:current_recording] do
|
||||
%{path: path} ->
|
||||
# Append binary chunk to file
|
||||
File.write!(path, payload, [:append])
|
||||
# Broadcast chunk to other listeners for live playback
|
||||
broadcast_from!(socket, "audio_chunk", %{data: Base.encode64(payload)})
|
||||
{:noreply, socket}
|
||||
|
||||
_ ->
|
||||
{:noreply, socket}
|
||||
end
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_in("audio_end", %{"duration_ms" => duration_ms}, socket) do
|
||||
case socket.assigns[:current_recording] do
|
||||
%{message_id: message_id} ->
|
||||
message = Audio.get_message!(message_id)
|
||||
|
||||
# Update DB record to "processing" status
|
||||
{:ok, message} =
|
||||
Audio.update_message(message, %{
|
||||
duration_ms: duration_ms,
|
||||
status: "processing"
|
||||
})
|
||||
|
||||
# Queue Oban job for processing
|
||||
%{id: message.id}
|
||||
|> RiverConnect.Workers.ProcessRecording.new()
|
||||
|> Oban.insert!()
|
||||
|
||||
# Notify UI that message status changed
|
||||
broadcast!(socket, "audio_message_ready", %{id: message.id})
|
||||
|
||||
{:noreply, assign(socket, :current_recording, nil)}
|
||||
|
||||
_ ->
|
||||
{:noreply, socket}
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user