defmodule ExshomePlayer.Services.MpvServer do @moduledoc """ Starts MPV server. """ use Exshome.Dependency.GenServerDependency, name: "mpv_server" @player_folder "player" @music_folder Path.join(@player_folder, "music") def restart do call(:restart) end @impl GenServerDependency def on_init(%DependencyState{} = state) do start_mpv_server(state) end @impl GenServerDependency def handle_call(:restart, _from, %DependencyState{} = state) do {:reply, :exec.kill(state.data.server_pid, 9), state} end @impl GenServerDependency def handle_info( {:EXIT, server_pid, _reason}, %DependencyState{data: %{server_pid: server_pid}} = state ) do state = state |> update_value(Dependency.NotReady) |> start_mpv_server() {:noreply, state} end @spec start_mpv_server(DependencyState.t()) :: DependencyState.t() defp start_mpv_server(%DependencyState{} = state) do {:ok, pid, _ospid} = :exec.run_link( mpv_server_command(), [ {:group, 0}, :kill_group, :stdout, :stderr ] ) state |> update_data(fn _ -> %{server_pid: pid} end) |> update_value(:started) end def socket_path do Exshome.FileUtils.get_of_create_folder!(@player_folder) |> Path.join("mpv_socket") end def music_folder do Exshome.FileUtils.get_of_create_folder!(@music_folder) end defp mpv_server_command do [ System.find_executable("mpv") |> String.to_charlist(), '--no-video', '--idle', '--no-cache', '--no-terminal', '--input-ipc-server=#{socket_path()}' ] end @hook_module Application.compile_env(:exshome, :mpv_server_hook_module) if @hook_module do defoverridable(mpv_server_command: 0) defdelegate mpv_server_command(), to: @hook_module end end