【问题标题】:Playing mp3 files in JavaFx from input stream从输入流中播放 JavaFx 中的 mp3 文件
【发布时间】:2012-11-12 10:50:59
【问题描述】:

我正在使用 JavaFX 媒体播放器使用以下代码播放 mp3 文件

 new MediaPlayer(new Media(FileObject.toURI().toString())).play();

但是,现在我需要在内存中保存 mp3 字节数据,而不是文件对象。原因是 mp3 文件被加密,然后随程序一起提供。因此我需要解密内存或输入流中的 mp3 文件。

我可以将 mp3 文件解密为 temp 目录中的临时文件,但这会产生性能开销并且音频内容不安全。

【问题讨论】:

    标签: java streaming mp3 javafx-2 javafx


    【解决方案1】:

    不幸的是,作为 Media 构造函数,我认为除了临时文件方法之外没有其他简单的方法可以做到这一点。请注意,虽然我同意性能会有开销,但如果文件不是太大(大多数 mp3 文件通常不是),那么从这个意义上说开销应该是最小的。而且从技术上讲,将内容解码到内存也会使其不安全(尽管公认更难提取。)

    我确实想到的一个有点疯狂的方法是使用套接字。您可以设置应用程序的单独部分来解密未加密的内容,然后通过本地主机上的某个端口流式传输原始 mp3 字节。然后,您可以将其作为 HTTP URI 提供给 Media 构造函数。

    【讨论】:

    • 将内容解码到内存是指硬盘上的临时文件吗?
    【解决方案2】:

    来自Media Javadoc

    仅支持 HTTP、FILE 和 JAR URL。如果提供的 URL 无效,则会引发异常。如果发生异步错误,将设置 error 属性。收听此属性以收到任何此类错误的通知。

    我个人对 JavaFX 并不熟悉,但这会告诉我,如果不使用讨厌的 hack,您将无法直接从内存中读取媒体。通常对于这种仅 URI 的接口,我建议注册一个自定义 UrlStreamHandler 和一个从内存读取的自定义协议。但是假设 JavaDoc 是正确的,JavaFX 会使用它自己的分辨率,所以这可能不起作用。

    鉴于此,我怀疑使这项工作的唯一方法是通过 HTTP 提供对内存中 MP3 的访问。您可以使用Jetty 或任何类似的可嵌入servlet 容器来执行此操作。大致如下:

    1) 按照Quick Start Guide启动码头

    2) 注册一个如下所示的 servlet。这个 servlet 会暴露你的内存数据:

    public class MagicAccessServlet extends HttpServlet {
        private static final Map<String, byte[]> mediaMap = new ConcurrentHashMap();
    
        public static String registerMedia(byte[] media) {
            String key = UUID.randomUUID().toString();
            mediaMap.put(key, media);
            return key;
        }
    
        public static deregisterMedia(String key) {
            mediaMap.remove(key);
        }
    
        public void doGet(HttpServletRequest req, HttpServletResponse resp) {
            String key = req.get("key");
            byte[] media = mediaMap.get(key);
            resp.setContentLength(media.length);
            resp.getOutputStream().write(media);
        }
    }
    

    然后您可以使用 http url 从您的应用程序中访问。例如。像

    MagicAccessServlet.registerMedia(decodedMp3);
    new MediaPlayer(new Media("http://localhost:<port>/<context>/<servlet>?key=" + key)).play();    
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-12
    • 1970-01-01
    • 2015-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多