Auto advance to next song via client

This commit is contained in:
Chris McCord 2021-11-10 14:29:53 -05:00
parent 635a2c9d21
commit 7708779b9f
3 changed files with 42 additions and 0 deletions

View file

@ -78,6 +78,11 @@ Hooks.AudioPlayer = {
updateProgress(){
if(isNaN(this.player.duration)){ return false }
if(this.player.currentTime >= this.player.duration){
this.pushEvent("next-song-auto")
clearInterval(this.progressTimer)
return
}
this.progress.style.width = `${(this.player.currentTime / (this.player.duration) * 100)}%`
this.duration.innerText = this.formatTime(this.player.duration)
this.currentTime.innerText = this.formatTime(this.player.currentTime)

View file

@ -10,6 +10,7 @@ defmodule LiveBeats.MediaLibrary do
alias Ecto.{Multi, Changeset}
@pubsub LiveBeats.PubSub
@auto_next_threshold_seconds 5
defdelegate stopped?(song), to: Song
defdelegate playing?(song), to: Song
@ -81,6 +82,16 @@ defmodule LiveBeats.MediaLibrary do
Phoenix.PubSub.broadcast!(@pubsub, topic(song.user_id), {:pause, song})
end
def play_next_song_auto(user_id) do
song = get_current_active_song(user_id) || get_first_song(user_id)
if song && elapsed_playback(song) >= song.duration - @auto_next_threshold_seconds do
song
|> get_next_song()
|> play_song()
end
end
defp topic(user_id), do: "room:#{user_id}"
def store_mp3(%Song{} = song, tmp_path) do
@ -90,6 +101,7 @@ defmodule LiveBeats.MediaLibrary do
def put_stats(%Ecto.Changeset{} = changeset, %MP3Stat{} = stat) do
chset = Song.put_duration(changeset, stat.duration)
if error = chset.errors[:duration] do
{:error, %{duration: error}}
else
@ -166,6 +178,24 @@ defmodule LiveBeats.MediaLibrary do
def get_song!(id), do: Repo.get!(Song, id)
def get_first_song(user_id) do
Repo.one(
from s in Song,
where: s.user_id == ^user_id,
order_by: [asc: s.inserted_at, asc: s.id],
limit: 1
)
end
def get_next_song(%Song{} = song) do
Repo.one(
from s in Song,
where: s.user_id == ^song.user_id and s.id > ^song.id,
order_by: [asc: s.inserted_at, asc: s.id],
limit: 1
) || get_first_song(song.user_id)
end
def create_song(attrs \\ %{}) do
%Song{}
|> Song.changeset(attrs)

View file

@ -135,6 +135,13 @@ defmodule LiveBeatsWeb.PlayerLive do
end
end
def handle_event("next-song-auto", _, socket) do
if socket.assigns.song do
MediaLibrary.play_next_song_auto(socket.assigns.song.user_id)
end
{:noreply, socket}
end
def handle_info(:play_current, socket) do
# we raced a pubsub, noop
if socket.assigns.song do