【问题标题】:How to achieve mp3 stream using java Servlet如何使用java Servlet实现mp3流
【发布时间】:2012-02-27 05:16:46
【问题描述】:

目标:构建一个servlet,当我在浏览器中输入http://xxx.com/servpage?a.mp3时,我可以立即开始播放这个mp3文件。以前如果我将文件作为静态文件放在 goDaddy 上,我可以这样做。我的软件可以立即播放。

使用 Servlet,我可以忽略 ? 之后的内容,只希望此页面动态返回 mp3(因为将来我可能会返回任何其他文件)。我得到的是漫长的等待(>20 秒),然后让玩家播放它。

我遵循了一些示例,并注意到示例中的“附件”。但是,如果我将其删除,则 mp3 将无法播放。我虽然使用 Google App Engine,但只使用输入/输出流来返回 http 请求。有人可以帮忙吗?

public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException ,IOException {
    res.setContentType("audio/mpeg3");
    OutputStream os = res.getOutputStream();
    res.setHeader("Content-Disposition", "attachment; filename="" + "a.mp3";");
    res.setContentLength(1000000);
    FileService fileService = FileServiceFactory.getFileService();
    boolean lockForRead = false;
    String filename =  "/gs/" + BUCKETNAME + "/" + FILENAME;
    AppEngineFile readableFile = new AppEngineFile(filename);

    try{
        FileReadChannel readChannel = fileService.openReadChannel(readableFile, lockForRead);
        InputStream is = Channels.newInputStream(readChannel);

        int BUFF_SIZE = 1024;
        byte[] buffer = new byte[BUFF_SIZE];
        try {
            do {
                int byteCount = is.read(buffer);
                if (byteCount == -1)
                    break;
                os.write(buffer, 0, byteCount);
                os.flush();
            } while (true);
        } catch (Exception excp) {
        } finally {
            os.close();
            is.close();
        }
        readChannel.close();
    } catch(Exception e){
    }
}

【问题讨论】:

    标签: google-app-engine servlets mp3


    【解决方案1】:

    几点说明:

    1. 你不是在做“流媒体”。只是一个简单的文件下载。

    2. 要进行 blob(文件)服务,您不需要像使用 AppEngineFile 那样从 BlobStore 读取 blob。只需直接使用blobstoreService.serve(blobKey) 即可。示例见Serving a Blob

    3. 您可以通过fileService.getBlobKey(readableFile)获取2.中需要的BlobKey

    更新:

    刚刚意识到您使用的是 Google Cloud Storage,而不是 BlobStore。

    在 GS 中,如果正确设置了 ACL,文件将通过以下方式公开可见:http://commondatastorage.googleapis.com/BUCKETNAME/FILENAME

    由于您没有进行任何身份验证,您可以在 GS 上公开共享文件,然后在您的 servlet 中执行 301 重定向到文件的公共 URL。

    【讨论】:

    • 谢谢,彼得。我试图让一个 java webstart 应用程序秘密地访问我的文件,这样服务器就不会被以任何方式滥用。为此,我将记录用户的 IP 地址并启动会话。我不认为只是重定向到谷歌云存储可以做到这一点。另外,我不希望用户被 ​​java 弹出窗口所困扰,说 JavaWS 正在尝试访问不是来自原始 Web 服务器的文件。我意识到 GAE 在 doGet 返回之前不发送任何内容,只允许 1 分钟或处理。所以我可能需要将文件分解为范围或使用 blob。
    • 好建议,彼得,刚刚尝试了 blob。看起来 blob 可以提供文件,就好像服务器在文件完全加载之前推送一样。而且我很可能会告诉您,看起来 Web 服务器正在使用另一个线程推送数据,因此我的客户端可以在下载的同时立即播放音乐。所以你基本上拯救了我的一天。赞赏!
    猜你喜欢
    • 1970-01-01
    • 2010-10-14
    • 2016-09-25
    • 1970-01-01
    • 1970-01-01
    • 2013-01-03
    • 2016-04-10
    相关资源
    最近更新 更多