现在,我已经成功地将MKV支持编译到JavaFX中,并且在本机层上确实需要一些但不是很大的努力。
请参阅此处的相关讨论,并查看以修补程序/ JIRA票证提交的结果。
我写的过程中更加全面的指南 在这里可能会感兴趣的其他任何人希望沿着这条路走下去。
接下来是我的简短调查,然后我才认真考虑将其他媒体支持纳入其中,尽管在此我将留作参考。
既然JFX8已经发布并且是完全开源的,我已经花了一些时间来研究如何完成此工作以及是否可以在不修补JFX源代码的情况下完成。不幸的是,对后一点的答案几乎是肯定的,至少在没有可怕的字节码操纵黑客的情况下。稍后我可能会更实际地对此进行研究,但是我将记录到目前为止我已经从可用资源中得出的结论。
魔术始于Media构造函数,最终是
MediaException从那里弹出(
MEDIA_UNSUPPORTED如果您尝试播放不受支持的格式,则带有标志)。从那里开始,它创建Locator,其构造函数确保URL受支持。
init()然后在一个单独的线程中调用该方法,该线程对URL字符串执行完整性检查,读取文件,然后继续尝试确定格式是什么。
因此,该方法的这一部分的相关代码为:
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标志弹出。
如果正确识别了类型,则还需要克服另一个障碍-
当前平台必须支持它。某些平台根据环境动态加载,但是
GSTPlatform始终存在,因此我们需要在此处放置任何其他(通用)格式。这是相对简单的,
CONTENT_TYPES存在一个仅包含受支持格式的数组的数组。
不幸的是,目前克隆JavaFX存储库似乎对我来说是失败的,否则我会尝试将其中的一部分付诸实践。但是代替上述内容,添加对其他格式的支持实际上需要发生什么呢?实际上,这似乎并不困难。
在MediaUtils中,需要向该
filenameToContentType()
方法添加支持以处理新的文件扩展名。这是微不足道的。在同一类中,需要向该
fileSignatureToContentType()
方法添加支持以根据其签名确定文件类型。这有点复杂,但还算不错。这甚至可能是可选的,因为如果无法从文件扩展名中正确(或完全)识别格式,则当前代码似乎仅将其用作备用。可以在此处找到不同格式的文件签名的完整列表,这对完成此任务很有帮助。在GSTPlatform中,需要将新的内容类型添加到受支持的内容类型列表中。
在Java方面,这似乎是使它接受内容类型并至少尝试将其传递给本机Gstreamer层所需的全部操作。
但是,我不是GStreamer的专家,因此尽管我知道JavaFX当前拒绝了它可以处理和播放的更多格式,但是我不确定它们究竟 如何
删除了此功能。他们肯定已经在上面的Java层中完成了此操作,但他们也可能已经在本地GStreamer级别上完成了–目前我不确定。
我认为他们已经对GStreamer for JFX8进行了一些更改-
但目前它们尚未在相关的项目页面上列出,因此很难确切地了解他们对该版本所做的更改。
下一步将是获取JFX8源,使用上述提议的更改构建新的内容类型,然后查看在本机级别发生了什么错误(如果有),然后从那里获取错误。



