Skip to content

Instantly share code, notes, and snippets.

@ilmsg
Forked from avdi/gist:7990684
Created June 28, 2022 07:54
Show Gist options
  • Save ilmsg/d80d5d503cac9c369b63bb2ba28d8c91 to your computer and use it in GitHub Desktop.
Save ilmsg/d80d5d503cac9c369b63bb2ba28d8c91 to your computer and use it in GitHub Desktop.
Streaming a URL to a file in Elixir
def download_video(Episode[filename: filename] = episode) do
Stream.resource(fn -> begin_download(episode) end,
&continue_download/1,
&finish_download/1)
|> File.stream_to!(filename)
|> Stream.run
end
def begin_download(Episode[video_url: video_url,
account: Account[login: login,
password: password]]) do
IO.puts "Downloading #{video_url}"
{:ok, _status, headers, client} =
:hackney.get(video_url, [], "", basic_auth: {login, password})
total_size = headers["Content-Length"] |> binary_to_integer
{client, total_size, 0}
end
def continue_download({client, total_size, size}) do
case :hackney.stream_body(client) do
{:ok, data, client} ->
new_size = size + size(data)
IO.puts "Downloaded #{new_size} of #{total_size}"
{data, {client, total_size, new_size}}
{:done, client} ->
IO.puts "No more data"
nil
{:error, reason} ->
raise reason
end
end
def finish_download({client, total_size, size}) do
IO.puts "Finished downloading #{size} bytes"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment