2016-05-31 46 views
5

以下代码将文件传输到流程。 我想流音频/ MP3 许多用户谁会听到它通过HTML5音频标签。 如何通过File.stream!完成?Elixir将流式音频传输给用户

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

输出:

< < 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 ,19 1,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,215,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, 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, 16,64,130,192,198,... >> ..............

如何使用JavaScript读取此二进制数据并通过音频标签收听?

回答

2

如果你使用基于插件的web框架,它应该是相当简单的。如果您直接使用插件,或者您使用phoenix(基于插件),则可以使用此功能。

也许这样的插件会做

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 

也许你想给你的插件挂钩到菲尼克斯路由器这样

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

    get "/the_song", Audio, :song 
end 

然后在你的页面的伎俩

<audio src="/the_song"> 
    Your browser does not support the <code>audio</code> element. 
</audio> 
+0

谢谢!它的工作原理,但抛出一个期望“[错误]牧场监听器Plugtest.HTTP有连接过程开始:cowboy_protocol:start_link/4在#PID <0.261.0>退出原因:{{%File.Error {action:”stream“,path: “./song.mp3”,reason::enoent} ..“&&我怎样才能像收音机那样流式传输,所有连接的用户都会听到同样的声音?对于此测试,我可以循环播放歌曲,但我想继续播放列表中的下一首歌 – IddoE

+0

该错误表示该文件不存在。你需要解决路径 - 我建议不使用相对路径。 至于你的实际目标,这是朝它了一步,但你需要更多。现在你正在谈论一个pubsub体系结构。在Elixir中这应该是非常容易的。您需要一个正在运行并持有文件流的进程,并跟踪打开的连接。 GenServer将运行良好。当它从流中读取块时,它应该写入它知道的每个连接。 – rozap

+0

再次感谢@rozap,请检查相关问题http://stackoverflow.com/questions/38551798 – IddoE