From e787a69943fc7e32acbedadc0fbab16b34218727 Mon Sep 17 00:00:00 2001 From: Stefan Breunig <307954+breunigs@users.noreply.github.com> Date: Mon, 2 Dec 2024 11:30:08 +0100 Subject: [PATCH] preload video poster upon page load --- lib/veloroute_web/endpoint.ex | 3 ++- lib/veloroute_web/live/frame_live.ex | 1 + lib/veloroute_web/live/video_state.ex | 29 +++++++++++++++++++++++++++ lib/warmup.ex | 2 +- 4 files changed, 33 insertions(+), 2 deletions(-) diff --git a/lib/veloroute_web/endpoint.ex b/lib/veloroute_web/endpoint.ex index 8920c189..a46706ec 100644 --- a/lib/veloroute_web/endpoint.ex +++ b/lib/veloroute_web/endpoint.ex @@ -16,7 +16,8 @@ defmodule VelorouteWeb.Endpoint do websocket: true, longpoll: false - socket "/live", Phoenix.LiveView.Socket, websocket: [connect_info: [session: @session_options]] + socket "/live", Phoenix.LiveView.Socket, + websocket: [connect_info: [:user_agent, session: @session_options]] plug Video.ServePlug plug Esri.Tiles diff --git a/lib/veloroute_web/live/frame_live.ex b/lib/veloroute_web/live/frame_live.ex index 38eff2aa..d0d969d2 100644 --- a/lib/veloroute_web/live/frame_live.ex +++ b/lib/veloroute_web/live/frame_live.ex @@ -249,6 +249,7 @@ defmodule VelorouteWeb.FrameLive do socket |> update_map_bounds(params) |> VelorouteWeb.Live.VideoState.maybe_update_video(article, params) + |> VelorouteWeb.Live.VideoState.maybe_preload_video_poster() |> maybe_autoplay(params["autoplay"] == "true") socket = diff --git a/lib/veloroute_web/live/video_state.ex b/lib/veloroute_web/live/video_state.ex index 6513270b..f245dea8 100644 --- a/lib/veloroute_web/live/video_state.ex +++ b/lib/veloroute_web/live/video_state.ex @@ -266,6 +266,35 @@ defmodule VelorouteWeb.Live.VideoState do end end + def maybe_preload_video_poster(%{assigns: %{video_hash: hash, video_start: start_ms}} = socket) do + if !test_env?() && !Phoenix.LiveView.connected?(socket) && valid_hash(hash) && + start_ms != nil && !probably_robot?(socket) do + Logger.debug("video poster async load start #{hash} #{start_ms}") + + Task.start(VelorouteWeb.ImageExtractController, :extract, [ + hash, + start_ms, + start_ms, + :webp + ]) + end + + socket + end + + def maybe_preload_video_poster(socket), do: socket + + defp test_env?() do + Application.get_env(:veloroute, :env) == :test + end + + defp probably_robot?(socket) do + ua = Phoenix.LiveView.get_connect_info(socket, :user_agent) |> String.downcase() + + ["http://", "https://", "bot", "ows.eu/owler", "python-requests", "okhttp"] + |> Enum.any?(&String.contains?(ua, &1)) + end + @spec position_from_time(Phoenix.LiveView.Socket.t(), %{binary() => binary()}) :: Video.Rendered.indicator() | nil defp position_from_time(%{assigns: %{video: state}}, params) do diff --git a/lib/warmup.ex b/lib/warmup.ex index f5968797..efa05fbd 100644 --- a/lib/warmup.ex +++ b/lib/warmup.ex @@ -44,7 +44,7 @@ defmodule Warmup do end defp initial_video_poster() do - Task.start_link(fn -> + Task.start(fn -> with {hash, ts} <- VelorouteWeb.Live.VideoState.default_video_poster() do VelorouteWeb.ImageExtractController.extract(hash, ts, ts, :webp) end