Skip to content

Commit

Permalink
Allow to stream hls files to a http server
Browse files Browse the repository at this point in the history
  • Loading branch information
Noarkhh committed Aug 28, 2024
1 parent 57d07cb commit 00f898d
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 3 deletions.
5 changes: 3 additions & 2 deletions lib/boombox/hls.ex
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ defmodule Boombox.HLS do
{:ok, status, _headers, _ref} when status in 200..299 ->
:ok

{:ok, status, _headers, _ref} ->
{:error, "POST failed with status code #{status}"}
{:ok, status, _headers, ref} ->
{:ok, body} = :hackney.body(ref)
{:error, "POST failed with status code #{status}: #{body}"}

error ->
error
Expand Down
4 changes: 3 additions & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,16 @@ defmodule Boombox.Mixfile do
{:membrane_mp4_plugin, "~> 0.35.2"},
{:membrane_realtimer_plugin, "~> 0.9.0"},
{:membrane_http_adaptive_stream_plugin,
github: "membraneframework/membrane_http_adaptive_stream_plugin", branch: "fix-linking"},
github: "membraneframework/membrane_http_adaptive_stream_plugin",
branch: "fix-genserver-storage"},
{:membrane_rtmp_plugin, "~> 0.25.0"},
{:membrane_rtsp_plugin,
github: "membraneframework-labs/membrane_rtsp_plugin", branch: "allow-for-eos"},
{:membrane_udp_plugin, "~> 0.14.0"},
{:membrane_rtp_plugin, "~> 0.29.0"},
{:membrane_ffmpeg_swresample_plugin, "~> 0.20.0"},
{:membrane_hackney_plugin, "~> 0.11.0"},
{:bandit, "~> 1.5"},
{:burrito, "~> 1.0", runtime: burrito?()},
{:ex_doc, ">= 0.0.0", only: :dev, runtime: false},
{:dialyxir, ">= 0.0.0", only: :dev, runtime: false},
Expand Down
19 changes: 19 additions & 0 deletions test/boombox_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,25 @@ defmodule BoomboxTest do
end)
end

@tag :file_hls_http
async_test "mp4 file -> http hls", %{tmp_dir: tmp} do
port = 9090
Bandit.start_link(plug: {HTTPServer.Router, %{directory: tmp}}, port: port)
url = "http://localhost:#{port}/hls_output/index.m3u8"

Boombox.run(input: @bbb_mp4, output: url)
ref_path = "test/fixtures/ref_bun10s_aac_hls"
Compare.compare(tmp, ref_path, format: :hls)

Enum.zip(
Path.join(tmp, "*.mp4") |> Path.wildcard(),
Path.join(ref_path, "*.mp4") |> Path.wildcard()
)
|> Enum.each(fn {output_file, ref_file} ->
assert File.read!(output_file) == File.read!(ref_file)
end)
end

@tag :rtmp_hls
async_test "rtmp -> hls", %{tmp_dir: tmp} do
manifest_filename = Path.join(tmp, "index.m3u8")
Expand Down
51 changes: 51 additions & 0 deletions test/support/http_server/router.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
defmodule HTTPServer.Router do
use Plug.Router

require Logger

# plug(:opts)
plug(:match)
plug(:dispatch)

@impl true
def call(conn, opts) do
assign(conn, :directory, opts.directory)
|> super(opts)
end

post "/hls_output/:filename" do
hls_dir = conn.assigns.directory

file_path = Path.join(hls_dir, filename)
conn = write_body_to_file(conn, file_path)
send_resp(conn, 200, "File successfully written")
end

delete "/hls_output/:filename" do
hls_dir = conn.assigns.directory

case Path.join(hls_dir, filename) |> File.rm() do
:ok ->
send_resp(conn, 200, "File deleted successfully")

{:error, error} ->
send_resp(conn, 409, "Error deleting file: #{inspect(error)}")
end
end

match _ do
send_resp(conn, 404, "Not found")
end

defp write_body_to_file(conn, file_path) do
case read_body(conn) do
{:ok, body, conn} ->
File.write(file_path, body)
conn

{:more, partial_body, conn} ->
File.write(file_path, partial_body)
write_body_to_file(conn, file_path)
end
end
end
File renamed without changes.
File renamed without changes.

0 comments on commit 00f898d

Please sign in to comment.