Ruby CGI 流音频

发布于 2024-08-08 15:21:29 字数 690 浏览 1 评论 0原文

我想做的是使用 CGI 脚本(用 Ruby 编写)从文件系统(特别是音频)读取二进制文件并将其流式传输到浏览器。

到目前为止,这就是我所做的,

require 'config'

ENV['REQUEST_URI'] =~ /\?(.*)$/
f= $config[:mdir] + '/' + $1.url_decode
f = File.open f, 'rb'

print "Content-Type: audio/mpeg\r\n"#TODO: Make it guess mime type
print "\r\n"

#Outputs file
while blk = f.read(4096)
    $stdout.puts blk
    $stdout.flush
end

f.close

它并不完美,存在安全漏洞(暴露了整个文件系统..),但它只是无法正常工作。它正在读取正确的文件,据我所知,它按照应有的方式以 4k 块的形式输出。使用 Safari,如果我转到 URL,它将在音频播放器上显示一个问号。如果我使用 wget 下载它,它似乎可以工作并且大小合适,但已损坏。它开始播放得很好,然后发出噼啪声,然后停止。

我该怎么做呢?我是否需要进行 Base-64 编码,是否可以在不一次性将整个文件加载到内存中的情况下进行编码?

顺便说一句,这只会在局域网上使用,而且我想要简单的设置,所以我对专用的流媒体服务器不感兴趣。

What I want to do is use a CGI script (written in Ruby) to read a binary file off of the filesystem (audio, specifically) and stream it to the browser.

This is how I am doing that so far,

require 'config'

ENV['REQUEST_URI'] =~ /\?(.*)$/
f= $config[:mdir] + '/' + $1.url_decode
f = File.open f, 'rb'

print "Content-Type: audio/mpeg\r\n"#TODO: Make it guess mime type
print "\r\n"

#Outputs file
while blk = f.read(4096)
    $stdout.puts blk
    $stdout.flush
end

f.close

It's not perfect, there are security holes (exposing the whole filesystem..), but it just isn't working right. It's reading the right file, and as far as I can tell, outputting it in 4k blocks like it should. Using Safari, if I go to the URL, it will show a question mark on the audio player. If I use wget to download it, it appears to work and is about the right size, but is corrupted. It begins playing fine, then crackles, and then stops.

How should I go about doing this? Do I need to Base-64 encode, if can I do that without loading the whole file into memory in one go?

Btw, this is only going to be used over local area network, and I want easy setup, so I'm not interested in a dedicated streaming server.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

余生再见 2024-08-15 15:21:29

您可以只使用 IO#print 代替 IO#puts ,但这有一些缺点。

不要在 ruby​​ 中进行文件处理

Ruby 不擅长快速执行愚蠢的任务。使用此代码,您可能无法填满您的带宽。

没有 CGI

您想要做的就是通过 http 公开文件系统的一部分,这里有一些关于如何执行此操作的选项

  • 将文档根目录设置为您要公开的文件夹。
  • 创建指向您要公开的文件夹的符号链接。
  • 在您的网络服务器配置中编写某种规则,将某些 url 映射到文件夹

使用其中任何一个,http 服务器都会为您做您想要的事情。

X-Sendfile

一些 http 服务器遵循称为 X-Sendfile 的特殊标头。如果这样做,

print "X-Sendfile: #{file}"

服务器将使用指定的文件作为正文。在lighty中,这只能通过fastcgi起作用,因此您需要一个fastcgi包装器,例如: http:// cgit.stbuehler.de/gitosis/fcgi-cgi/ 。我不知道apache和其他的。

使用 ac 扩展

C 扩展擅长快速完成愚蠢的任务。我写了一个 ac 扩展,它什么也不做,只是从一个 IO 读取并将其写入另一个 IO。使用这个 c 扩展,你可以通过 ruby​​ 填充一个 GIGABIT Lan:git://johannes.krude.de/io2io

像这样使用它:

IO2IO.do(file, STDOUT)

You could just use IO#print instead of IO#puts but this has some disadvantages.

Don't do the file handling in ruby

Ruby is not good in doing stupid tasks very fast. With this code, you will probably not be able to fill your bandwith.

No CGI

All you want to do is expose a part of the filestystem via http, here are some options on how to do it

  • Set your document root to the folder you want to expose.
  • Make a symlink to the folder you want to expose.
  • Write some kind of rule in your webserver config to map certain url's to a folder

Use any of these and the http server will do for you what you want.

X-Sendfile

Some http servers honor a special header called X-Sendfile. If you do

print "X-Sendfile: #{file}"

the server will use the specified file as body. In lighty this works only through fastcgi, so you would need a fastcgi wrapper like: http://cgit.stbuehler.de/gitosis/fcgi-cgi/ . I don't know about apache and others.

Use a c extension

C extensions are good at doing stupid tasks fast. I wrote a c extension which does nothing, but reading from one IO and writing it to another IO. With this c extension you can fill a GIGABIT Lan through ruby: git://johannes.krude.de/io2io

Use it like this:

IO2IO.do(file, STDOUT)
烟柳画桥 2024-08-15 15:21:29

puts 用于编写“行” “文本”,因此附加换行符到您提供的任何内容它(把你的 mpeg 变成垃圾)。您需要 syswrite

puts is for writing "lines" of "text", and therefore appends a newline to whatever you give it (turning your mpegs into garbage). You want syswrite.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文