向 JavaFX 2.2 添加其他视频编解码器/DVD 支持 [英] Adding other video codecs / DVD support to JavaFX 2.2

查看:20
本文介绍了向 JavaFX 2.2 添加其他视频编解码器/DVD 支持的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于 JFX 的媒体端已经开源,我自己研究了一下,确实可以,但是需要更改和重建 JFX 源代码(Java 和 C 部分).过程描述这里 任何想要拥有go - 我在那个例子中添加了 MKV 支持,但对于其他插件应该非常相似.

Since the media side of JFX has been open sourced, I've looked into this myself and it is indeed possible, but requires changing and rebuilding the JFX source (both Java and C parts.) The process is described here for anyone that wants to have a go - I add MKV support in that example, but it should be very similar for other plugins.

因此问题的其余部分主要是历史性的,但我将其留在这里以供参考.

The remainder of the question is thus mainly historical, but I'll leave it here for reference.

到目前为止,我一直在使用 VLCJ 在我的应用程序中播放视频.它可以工作,但如果可能的话,我想看看我是否可以通过迁移到 JavaFX 来实现对常见编解码器的类似支持,并为自己省去多个虚拟机的麻烦,例如 VLCJ 需要可靠地播放多个视频.我不会在这里讨论它,但请参阅我对这个 问题,如果您对细节感兴趣.还有跨平台兼容性的问题,它可以在 Mac 和 Linux 上运行,但我还没有想出如何让它在 Mac 上显示(我相信有一些安全措施可以防止一个进程访问另一个进程的本机组件,但这又超出了本问题的范围.)

I've been using VLCJ thus far for playing video in my application. It works, but if possible I'd like to see if I can achieve a similar level of support for common codecs by migrating to JavaFX and saving myself a lot of hassle with multiple VMs and suchlike that VLCJ needs to play multiple videos reliably. I won't go into it here but see my answer to this question if you're interested in the details. There's also the issue of cross-platform compatibility, it works on Mac and Linux ok but I haven't worked out how to get it to show on Mac yet (I believe there's some security in place to prevent one process gaining access to another's native components, but again that's beyond the scope of this question.)

归结为这样一个事实:虽然它可以工作,但如果有另一种更简单的解决方案,则需要大量的维护工作,并且与多个 VM 一起工作并稳定地桥接它们会很麻烦.VLC 确实对玩几乎任何东西都有相当传奇的支持,这就是为什么我到目前为止一直使用它,我很想看看我是否可以在 JavaFX 中获得类似的结果 - 或者至少如果可以的话提供以跨平台方式执行此操作的方法.

It boils down to the fact that while it works, it's a lot of maintenance and hassle working with multiple VMs and bridging them stably if there's another solution that would be easier. VLC does have a pretty legendary level of support for playing pretty much anything which is why I've gone with it thus far, and I'd be interested to see if I can get a similar result in JavaFX - or at least if it can provide the means for doing so in a cross platform manner.

JavaFX 2.0 支持视频 - 太棒了!但目前官方的说法是它支持包含 VP6 视频和 MP3 音频的 FLV".有没有办法扩展它以添加对更多编解码器的支持?没有我想支持的硬编解码器,它更多是我可以支持的情况,所以我正在寻找一种可扩展的方法来解决上述问题.

JavaFX 2.0 supports video - great! But at the moment the official line is it supports "FLV containing VP6 video and MP3 audio". Is there a way to extend this to add in support for more codecs? There's no hard codec that I'd like to support, it's more a case of as many as I can so I'm looking for an extensible method to go about the above.

我想知道它是否会为机器上本地安装的编解码器播放视频,并且它不会这样宣传自己(因为该功能显然依赖于机器而不是跨平台.)但是没有骰子,我已经尝试了多种常见格式,但它确实拒绝播放除其声明之外的任何内容.

I wondered if it would play video for codecs installed natively on the machine and that it just doesn't advertise itself as such (because that functionality obviously is machine dependant and not cross-platform.) But no dice, I've tried a number of common formats and it really does refuse to play anything other than what it states.

从 JavaFX 1.3 来看,它还支持其他平台相关的编解码器取决于它的安装位置.有没有办法用 JavaFX 2 获得这种行为?或者它是否计划用于后续版本?我在路线图上找不到任何相关信息,也没有找到 Oracle 对此的任何评论.

From looking at JavaFX 1.3 it also supports other platform dependant codecs depending on where it's installed. Is there a way to get this behaviour with JavaFX 2? Or is it planned at all for a subsequent release? I haven't been able to find any information on it on the roadmap or any comment from Oracle about it.

我从广泛搜索中唯一能找到的是这里暗示这可能是可能的,但似乎没有人知道如何.我也很想知道它是否基于 GStreamer,为什么默认情况下也不包含 GStreamer 支持的所有格式?

Only thing I could find from searching extensively is here which implies that it may be possible but no-one seems to know how. I'd also be interested to know if it's based on GStreamer why all the formats supported by GStreamer aren't included by default either?

就使用 JavaFX 播放 DVD 而言,我完全无处可去,所以我假设目前这只是一个行不通的地方.如果有人确实有任何想法或信息,我会全神贯注.

In terms of playing DVDs with JavaFX I've got absolutely nowhere, so I'm assuming that's just a no-go at the moment. If anyone does have any ideas or information though, I'm all ears.

我有点想不通的一种方法是将 JMC jar 从旧的 JavaFX 中撬出来,如这里 并试图让它与 JavaFX 2 一起工作.我认为没有人对这种方法或类似的方法有任何运气吗?

One approach which I was half wondering may be possible is crowbarring the JMC jar out of the old JavaFX as described here and trying to get that working alongside JavaFX 2. I don't suppose anyone has had any luck with that approach or something similar?

所有事情都失败了,如果有人有关于是否/何时支持开箱即用的其他编解码器的任何信息或链接,那么我也有兴趣听到.或者,如果有人有 Oracle 人员的任何联系方式,我可以询问,也将不胜感激!一段时间以来,我一直渴望在 Java 中获得体面的视频支持,我想这归结为试图弄清楚 JavaFX 是否是这个问题的答案,或者只是另一个三心二意的尝试,永远不会超过它现在呢!我希望不是后者,但我还没有看到很多证据表明情况确实如此.

All things failing, if anyone has any information or links on if / when support for additional codecs will be supported out of the box, then I'd be interested to hear that also. Or if anyone has any contact details for someone at Oracle I could ask that would also be appreciated! I've been longing for decent video support in Java for some time, and I guess what this boils down to is trying to figure out if JavaFX is the answer to this, or just another half hearted attempt that will never play more than what it does at the moment! I'm hoping it's not the latter, but I've yet to see much to show that's the case.

推荐答案

我现在已经成功地将 MKV 支持编译到 JavaFX 中,它确实需要一些,但在本机层上并没有太多的努力还.请参阅此处了解有关它的讨论,以及此处 以补丁/JIRA 票证形式提交的结果.

I've now managed to compile MKV support into JavaFX successfully, and it does take some, but not a great deal of effort on the native layer also. See here for the discussion surrounding it, and here for the result submitted as a patch / JIRA ticket.

我写了一份关于这个过程的更全面的指南在这里,其他人可能会对此感兴趣.

I've written a much more comprehensive guide on the process here which may be of interest to anyone else looking to go down this route.

以下是我在认真考虑编译其他媒体支持之前的简短调查,不过我会留在这里以供参考.

现在 JFX8 已经发布并且是完全开源的,我花了一些时间研究如何做到这一点,以及是否可以在不修补 JFX 源代码的情况下做到这一点.不幸的是,后一点的答案几乎是肯定的,至少在没有可怕的字节码操作黑客的情况下.稍后我可能会更实际地研究这个问题,但我会记录到目前为止我从可用来源中得出的结论.

Now that JFX8 has been released and is completely open source, I've spent a bit of time looking at how this could be done, and whether it could be done without patching the JFX source. Unfortunately the answer to that latter point is an almost definite no, at least not without horrible bytecode manipulation hacks. I may look into this more practically at a later date, but I'll document what I've worked out so far from the source available.

魔法从媒体构造函数,它最终是 MediaException 弹出的地方(如果您尝试播放不受支持的格式.)从那里它创建 Locator,其构造函数确保 URL 是受支持的 URL.然后在单独的线程中调用 init() 方法,该线程对 URL 字符串执行一些完整性检查,读取文件,然后继续尝试确定格式是什么.

The magic starts from the Media constructor, which is ultimately where the MediaException pops out from (with the MEDIA_UNSUPPORTED flag if you try to play an unsupported format.) From there it creates the Locator, whose constructor ensures that the URL is one that's supported. It's init() method is then called in a separate thread, which performs some sanity checking on the URL string, reads the file, then proceeds to try to work out what the format is.

这部分方法的相关代码是这样的:

The relevant code for this part of the method is thus:

if (scheme.equals("file") || scheme.equals("jar")) {
    InputStream stream = getInputStream(uri);
    stream.close();
    isConnected = true;
    contentType = MediaUtils.filenameToContentType(uriString); // We need to provide at least something
}

if (isConnected) {
    // Check whether content may be played.
    // For WAV use file signature, since it can detect audio format
    // and we can fail sooner, then doing it at runtime.
    // This is important for AudioClip.
    if (MediaUtils.CONTENT_TYPE_WAV.equals(contentType)) {
        contentType = getContentTypeFromFileSignature(uri);
        if (!MediaManager.canPlayContentType(contentType)) {
            isMediaSupported = false;
        }
    } else {
        if (contentType == null || !MediaManager.canPlayContentType(contentType)) {
            // Try content based on file name.
            contentType = MediaUtils.filenameToContentType(uriString);

            if (Locator.DEFAULT_CONTENT_TYPE.equals(contentType)) {
                // Try content based on file signature.
                contentType = getContentTypeFromFileSignature(uri);
            }

            if (!MediaManager.canPlayContentType(contentType)) {
                isMediaSupported = false;
            }
        }
    }

    // Break as connection has been made and media type checked.
    break;
}

由此我们可以看到第一次愚蠢"尝试根据文件名抓取文件内容(这就是 MediaUtils.filenameToContentType() 所做的.)然后有一些特殊情况检查不同类型的 wav 文件,但如果失败,那么我们将退回到更聪明的检查,该检查查看实际的文件签名.这两项检查都在 MediaUtils.后一种检查要广泛得多,它会查看文件的前几个字节,看看它是否可以以这种方式计算出格式.如果它不能,那么它就会退出并抛出异常,然后作为我们可怕的 MEDIA_UNSUPPORTED 标志弹出.

From this we can see a first "dumb" attempt is made to grab the file content based on its name (this is what MediaUtils.filenameToContentType() does.) There's then some special cases for checking for different types of wav file, but if that fails then we fall back on a cleverer check which looks at the actual file signature. Both these checks are in MediaUtils. This latter check is much more extensive, and looks at the first few bytes of the file to see if it can work out a format that way. If it can't, then it bails out and throws the exception that then pops out as our dreaded MEDIA_UNSUPPORTED flag.

如果类型被正确识别,还有另一个障碍需要克服——它必须得到当前平台的支持.某些平台根据环境动态加载,但是 GSTPlatform 始终存在,因此我们需要在此处放置任何其他(通用)格式.这相对简单,存在一个 CONTENT_TYPES 数组,它只保存支持格式的数组.

If the type is identified correctly though, there's still another hurdle to go through - it has to be supported by the current platform. Some platforms are loaded dynamically depending on the environment, however the GSTPlatform always exists, thus we would need to put any additional (universal) formats here. This is relatively simple, a CONTENT_TYPES array exists which just holds the array of supported formats.

不幸的是,克隆 JavaFX 存储库目前对我来说似乎失败了,否则我会尝试将其中的一些付诸实践.但是代替上述内容,实际上需要发生什么来添加对更多格式的支持?其实看起来并不难.

Unfortunately cloning the JavaFX repo seems to be failing for me at the moment, otherwise I'd attempt to put some of this in practice. But in lieu of the above, what actually needs to happen to add support for further formats? It actually doesn't seem hugely difficult.

  1. MediaUtils,需要在filenameToContentType()方法中添加支持来处理新的文件扩展名.这是微不足道的.

  1. In MediaUtils, support needs to be added to the filenameToContentType() method to handle the new file extension. This is trivial.

在同一个类中,需要添加对fileSignatureToContentType()方法的支持,以根据其签名计算文件类型.这有点复杂,但还不错.这甚至可能是可选的,因为当前代码似乎仅在文件扩展名中未正确(或根本)识别格式时才将此用作后备.可以在此处找到不同格式的文件签名的完整列表,这有助于完成此任务.

In the same class, support needs to be added to the fileSignatureToContentType() method to work out the file type based on its signature. This is a tad more complex, but still not too bad. This may even be optional, since the current code only seems to use this as a fallback if the format isn't identified correctly (or at all) from the file extension. A comprehensive list of file signatures for different formats can be found here which should help with this task.

在 GSTPlatform 中,新的内容类型 需要添加到支持的内容类型列表中.

In GSTPlatform, the new content type needs to be added to the list of supported content types.

在 Java 方面,这似乎是让它接受内容类型并至少尝试将其传递给本机 Gstreamer 层.

On the Java side of things, this appears to be all that's necessary to get it to accept the content type and at least attempt to pass it down to the native Gstreamer layer.

但是,我不是 GStreamer 方面的专家,所以虽然我知道它可以处理和播放 JavaFX 目前拒绝的更多格式,但我不确定如何已经删除了这个容量.他们肯定已经在上面的 Java 层完成了,但他们也可能在本机 GStreamer 级别完成了 - 在这一点上我不确定.

However, I'm no expert in GStreamer, so while I'm aware there's many more formats that it can handle and play that JavaFX currently refuses, I'm unsure as to how exactly they've removed this capacity. They've definitely done it in the Java layer above, but they may have also done it on the native GStreamer level - at this point I'm unsure.

我假设他们已经对 JFX8 的 GStreamer 进行了一些更改 - 但目前它们没有列在 相关项目页面,因此很难确定他们为此版本所做的更改.

I assume they've made some changes to GStreamer for JFX8 - but at the present time they're not listed on the relevant project page, so it's quite hard to work out exactly what they've changed for this version.

下一步是获取 JFX8 源代码,使用上述针对新内容类型提出的更改进行构建,然后查看本机级别发生了什么错误(如果有),然后从那里获取.

The next step would be to grab the JFX8 source, build with the above proposed changes for a new content type, and then see what errors (if any) occur on the native level, then take it from there.

这篇关于向 JavaFX 2.2 添加其他视频编解码器/DVD 支持的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆