Skip to content

Commit

Permalink
Add programmatic play and pause to Kino.Audio (#458)
Browse files Browse the repository at this point in the history
Co-authored-by: Jonatan Kłosko <[email protected]>
  • Loading branch information
relardev and jonatanklosko committed Jul 18, 2024
1 parent 50bb6ab commit 34addbb
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 0 deletions.
10 changes: 10 additions & 0 deletions lib/assets/audio/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@ export function init(ctx, [{ type, opts }, content]) {
<audio ${opts} src="${createDataUrl(content, type)}" style="height: 150px"/>
</div>
`;

const audioEl = ctx.root.querySelector("audio");

ctx.handleEvent("play", () => {
audioEl.play();
});

ctx.handleEvent("pause", () => {
audioEl.pause();
});
}

function bufferToBase64(buffer) {
Expand Down
29 changes: 29 additions & 0 deletions lib/kino/audio.ex
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,24 @@ defmodule Kino.Audio do
})
end

@doc """
Makes a given kino play the audio.
Play has no effect if the audio is already playing.
"""
@spec play(t()) :: :ok
def play(kino) do
Kino.JS.Live.cast(kino, :play)
end

@doc """
Makes a given kino stop playing the audio.
"""
@spec pause(t()) :: :ok
def pause(kino) do
Kino.JS.Live.cast(kino, :pause)
end

@impl true
def init(assigns, ctx) do
{:ok, assign(ctx, assigns)}
Expand All @@ -69,6 +87,17 @@ defmodule Kino.Audio do
{:ok, payload, ctx}
end

@impl true
def handle_cast(:play, ctx) do
broadcast_event(ctx, "play", %{})
{:noreply, ctx}
end

def handle_cast(:pause, ctx) do
broadcast_event(ctx, "pause", %{})
{:noreply, ctx}
end

defp mime_type!(:wav), do: "audio/wav"
defp mime_type!(:mp3), do: "audio/mpeg"
defp mime_type!(:mpeg), do: "audio/mpeg"
Expand Down
12 changes: 12 additions & 0 deletions test/kino/audio_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,17 @@ defmodule Kino.AudioTest do
kino = Kino.Audio.new(<<>>, "audio/mp2", loop: true)
assert {:binary, %{type: "audio/mp2", opts: "controls loop"}, <<>>} == connect(kino)
end

test "supports playing" do
kino = Kino.Audio.new(<<>>, :wav)
Kino.Audio.play(kino)
assert_broadcast_event(kino, "play", %{})
end

test "supports pausing" do
kino = Kino.Audio.new(<<>>, :wav)
Kino.Audio.pause(kino)
assert_broadcast_event(kino, "pause", %{})
end
end
end

0 comments on commit 34addbb

Please sign in to comment.