Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Elixir stream audio to users

The following code streams a file to a process. I want to stream audio/mp3 to many users who will hear it via html5 audio tag. How can it be done via File.stream!?

defmodule Test do

    def start do
        p = spawn(Test, :say, [])
        send p, {self, "a message"}
    end

    def say do
        receive do
          {from, msg} ->
            IO.puts "Process #{inspect self} says: #{msg}"
            stream_bytes = 128
            File.stream!("./song.mp3", [], stream_bytes)
            |> Enum.each(fn chunk ->
                IO.inspect chunk
            end)
            say
        end
    end
end

$: iex test.ex

iex(1)> Test.start

output:

<<171, 46, 254, 26, 163, 32, 178, 27, 0, 75, 17, 35, 4, 236, 51, 57, 5, 144, 154, 198, 166, 47, 62, 4, 61, 85, 67, 135, 16, 34, 82, 49, 57, 176, 131, 96, 116, 152, 232, 24, 32, 140, 220, 67, 73, 128, 165, 178, 230, 202, ...>> <<100, 220, 156, 191, 38, 0, 161, 117, 80, 16, 102, 91, 22, 5, 8, 66, 26, 7, 193, 155, 193, 66, 198, 28, 157, 244, 65, 131, 204, 240, 5, 172, 143, 44, 173, 85, 144, 2, 157, 144, 145, 97, 200, 236, 16, 49, 149, 150, 133, 67, ...>> <<150, 54, 37, 254, 192, 218, 218, 26, 69, 231, 88, 124, 33, 129, 169, 66, 117, 52, 214, 134, 130, 103, 85, 130, 48, 6, 144, 221, 153, 132, 8, 181, 26, 27, 83, 140, 54, 117, 149, 7, 60, 144, 237, 248, 132, 12, 210, 51, 103, 116, ...>> <<57, 2, 143, 220, 198, 182, 22, 177, 231, 126, 187, 147, 33, 9, 1, 5, 164, 2, 36, 105, 47, 255, 255, 255, 255, 255, 245, 54, 51, 225, 104, 98, 1, 184, 148, 206, 50, 135, 230, 28, 50, 47, 144, 134, 53, 16, 64, 130, 192, 198, ...>> ..............

how can I use JavaScript to read this binary data and hear it via audio tag ?

like image 646
whoopdedoo Avatar asked May 31 '16 11:05

whoopdedoo


People also ask

What is a stream in Elixir?

Any enumerable that generates elements one by one during enumeration is called a stream. For example, Elixir's Range is a stream: In the example above, as we mapped over the range, the elements being enumerated were created one by one, during enumeration. The Stream module allows us to map the range, without triggering its enumeration:

Why elixir essential for immersive audio?

With Immersive Audio being the new driving force in the entertainment industry a new era in audio production is taking shape. Elixir Essential supports up to 16 channels of processing making it the indispensable tool for Immersive Audio production, including Dolby Atmos® workflows.

What makes elixir V3 unique?

Elixir v3 is carefully designed to accomplish a true natural sounding result preserving the natural timbre of the audio material, meeting the broadcast, post-production and mastering industry norms with real True Peak output in accordance with the ITU-R BS.1770 and EBU R128 norms, with up to eight channels for multichannel/surround.

How many channels does elixir essential support for Dolby Atmos?

Elixir Essential supports up to 16 channels of processing making it the indispensable tool for Immersive Audio production, including Dolby Atmos® workflows. You can either control the dynamic of the multiple 7.1.2 beds you are sending to the Dolby Atmos® renderer, or, limit your monitoring level.


1 Answers

If you're using a plug based web framework it should be reasonably straight forward. This is possible if you're using plug directly or if you're using it from within phoenix (which is based on plug).

Maybe a plug like this would do the trick

defmodule Audio do
  @chunk_size 128

  def init(opts), do: opts

  def song(conn, _opts) do
    conn = conn
    |> send_chunked(200)
    |> put_resp_header("content-type", "audio/mpeg")

    File.stream!("/some/song/somewhere.mp3", [], @chunk_size)
    |> Enum.into(conn)
  end 
end

Maybe you want to hook up your plug to a phoenix router like this

defmodule MyApp.Router do
  use MyApp.Web, :router

  get "/the_song", Audio, :song
end

Then in your page

<audio src="/the_song">
    Your browser does not support the <code>audio</code> element.
</audio>
like image 159
rozap Avatar answered Sep 18 '22 13:09

rozap