Добавление поддержки других видеокодеков / DVD в JavaFX 2.2 - PullRequest
16 голосов
/ 16 ноября 2011

Обновление:

Поскольку медиа-сторона JFX была с открытым исходным кодом, я сам изучил это, и это действительно возможно, но требует изменения и перестройкиИсточник JFX (как Java, так и C). Процесс описан здесь для всех, кто хочет попробовать - я добавляю поддержку MKV в этом примере, но она должна быть очень похожа для других плагинов.

Остальная часть вопроса, таким образом, в основном историческая, но я оставлю это здесь для справки.

Справочная информация

До сих пор я использовал VLCJ для игрывидео в моем приложении.Это работает, но, если возможно, я хотел бы посмотреть, смогу ли я достичь аналогичного уровня поддержки распространенных кодеков, мигрировав на JavaFX и избавив себя от хлопот с несколькими виртуальными машинами и так, что VLCJ необходимо надежно воспроизводить несколько видео.Я не буду вдаваться в подробности, но увижу мой ответ на этот вопрос, если вас интересуют подробности.Существует также проблема кросс-платформенной совместимости, она хорошо работает на Mac и Linux, но я еще не выяснил, как заставить ее показывать на Mac (я полагаю, что существует некоторая защита, предотвращающая доступ одного процесса к нативному другому процессу).компонентов, но опять же, это выходит за рамки этого вопроса.)

Это сводится к тому факту, что, хотя он работает, он требует много обслуживания и хлопот, работая с несколькими виртуальными машинами и обеспечивая их стабильное соединение, если есть другое решение, котороебыло бы проще.VLC имеет довольно легендарный уровень поддержки для воспроизведения практически всего, поэтому я до сих пор с этим справился, и мне было бы интересно узнать, смогу ли я получить аналогичный результат в JavaFX - или, по крайней мере, смогу ли онобеспечить средства для кроссплатформенной работы.

Исследования

JavaFX 2.0 поддерживает видео - отлично!Но на данный момент официальной линией является поддержка «FLV, содержащего видео VP6 и аудио MP3».Есть ли способ расширить это, чтобы добавить поддержку большего количества кодеков?Нет жесткого кодека, который я бы хотел поддерживать, это скорее всего столько, сколько я могу, поэтому я ищу расширяемый метод для решения вышеизложенного.

Мне было интересно, будет ли он воспроизводить видеодля кодеков, установленных изначально на машине, и что он просто не рекламирует себя как таковой (потому что эта функциональность, очевидно, зависит от машины, а не кроссплатформенна.) Но без излишеств, я попробовал несколько распространенных форматов, и это действительно такОтказаться от воспроизведения чего-либо, кроме того, о чем говорится.

Посмотрев на JavaFX 1.3, он также поддерживает другие зависимые от платформы кодеки, в зависимости от того, где он установлен .Есть ли способ получить такое поведение с JavaFX 2?Или это вообще планируется для последующего релиза?Мне не удалось найти какую-либо информацию об этом в «дорожной карте» или какой-либо комментарий от Oracle по этому поводу.

Единственное, что я мог найти при интенсивном поиске, это здесь , что подразумевает, что это можетвозможно, но никто, кажется, не знает как.Мне также было бы интересно узнать, основано ли это на GStreamer, почему все форматы, поддерживаемые GStreamer, также не включены по умолчанию?

С точки зрения воспроизведения DVD с JavaFX у меня нет абсолютно ничего, поэтому яЯ предполагаю, что это просто не ходят в данный момент.Если у кого-то есть какие-либо идеи или информация, я все уши.

Другие подходы

Один из подходов, который мне наполовину интересен, может быть возможен - ломать банку JMC из старого JavaFXкак описано здесь и пытается заставить это работать вместе с JavaFX 2. Не думаю, что кому-то повезло с таким подходом или чем-то подобным?

Все вещи терпят неудачу, если у кого-то есть какая-либо информация или ссылки о том, если / когда поддержка дополнительных кодеков будет поддерживаться из коробки, то мне было бы интересно услышать это также.Или, если у кого-то есть контактные данные для кого-то в Oracle, я мог бы спросить, что также будет оценено!Я давно мечтал о достойной поддержке видео в Java, и я думаю, что все сводится к тому, чтобы попытаться выяснить, является ли JavaFX ответом на это, или просто еще одной нерешительной попыткой, которая никогда не сыграет больше, чем онав данный моментЯ надеюсь, что это не последнее, но мне еще многое предстоит увидеть, чтобы показать, что это так.

Ответы [ 5 ]

10 голосов
/ 27 ноября 2011

Поверьте мне, я чувствую и знаю ваше разочарование.Некоторое время я размышлял над этим, но мне пришлось использовать непростые способы решения своих проблем.

Есть много способов обойти это, каждый с ограничениями, но зависит от того, что работает для вас:

  1. В документах говорится, что WebView работает с HTML5, который воспроизводит видео, поддерживаемые на платформе (хотя, к сожалению, не Flash).Если использование веб-просмотра для воспроизведения видео работает для вас, вы можете попробовать это.Вы даже можете рисовать поверх других узлов.

  2. Портативный VLC Player!Если, возможно, вы разрабатываете какое-то приложение для проектора / режиссера и хотите полноэкранное видео, вы можете иметь портативный проигрыватель VLC для воспроизведения видео в полноэкранном режиме на одном экране, а его элементы управления - на другом.Использовал это решение, и оно работает довольно хорошо для Mac и Windows.:) Единственное, что вы не можете рисовать узлы на видео, так как это внешнее приложение, только иллюзия полноэкранного видео вашего приложения.

  3. Если вам когда-либо понадобится использоватьСила вспышки в вашем приложении javafx 2.0, затем используйте браузер на основе SWT (или что-то вроде DJ Project , если вы Swinger), поскольку они поддерживают все функции вашего родного браузера.

9 голосов
/ 21 марта 2014

Теперь мне удалось успешно скомпилировать поддержку MKV в JavaFX, и это потребует некоторых, но не больших усилий и на нативном уровне. См. здесь для обсуждения этого вопроса и здесь для результата, представленного в виде патча / билета JIRA.

Я написал гораздо более полное руководство по процессу здесь , которое может быть интересно всем, кто хочет пойти по этому пути.

Далее следует мое краткое расследование, прежде чем я действительно всерьез занялся сбором поддержки других средств массовой информации, хотя я оставлю это здесь для справки.

Теперь, когда JFX8 выпущен и является полностью открытым исходным кодом, я потратил немного времени на изучение того, как это можно сделать, и можно ли это сделать без исправления источника JFX. К сожалению, ответом на этот последний вопрос является почти однозначный отказ, по крайней мере, без ужасных манипуляций с байт-кодом. Я могу рассмотреть это более практично позже, но я документирую то, что я разработал, так далеко от доступного источника.

Волшебство начинается с Медиа-конструктора , из которого в конечном итоге выскочит MediaException (с флагом MEDIA_UNSUPPORTED, если вы пытаетесь воспроизвести неподдерживаемый формат.) Оттуда он создает Локатор , конструктор которого гарантирует, что 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 для меня не получается, иначе я бы попытался применить это на практике. Но вместо вышесказанного, что на самом деле должно произойти, чтобы добавить поддержку других форматов? На самом деле это не кажется чрезвычайно сложным.

  1. В MediaUtils необходимо добавить поддержку метода filenameToContentType() для обработки нового расширения файла. Это тривиально.

  2. В том же классе необходимо добавить поддержку в метод fileSignatureToContentType(), чтобы определить тип файла на основе его сигнатуры. Это немного сложнее, но все же не так уж плохо. Это может даже быть необязательным, так как текущий код, кажется, использует это как запасной вариант, если формат не идентифицирован правильно (или вообще не) из расширения файла. Полный список подписей файлов для различных форматов можно найти здесь , который должен помочь с этой задачей.

  3. В GSTPlatform необходимо добавить новый тип контента в список поддерживаемых типов контента.

Что касается Java, то это все, что необходимо для того, чтобы он принял тип контента и, по крайней мере, попытался передать его на собственный слой Gstreamer .

Однако я не эксперт в GStreamer, поэтому, хотя я знаю, что есть гораздо больше форматов, которые он может обрабатывать и воспроизводить, которые JavaFX в настоящее время отказывает, я не уверен относительно как именно онимы удалили эту способность.Они определенно сделали это на уровне Java выше, но, возможно, они также сделали это на родном уровне GStreamer - на данный момент я не уверен.

Я предполагаю, что они внесли некоторые изменения в GStreamer дляJFX8 - но в настоящее время они не перечислены на соответствующей странице проекта , поэтому довольно сложно понять, что именно они изменили для этой версии.

Следующий шагможно было бы получить исходный код JFX8, выполнить сборку с предложенными выше изменениями для нового типа контента, а затем посмотреть, какие ошибки (если таковые имеются) происходят на собственном уровне, а затем извлечь их оттуда.

6 голосов
/ 28 марта 2012

И теперь Javafx2.1 наконец-то поддерживает mp4 H.264, так что теперь вы должны хорошо обходиться без вышедших выше трюков. :)

5 голосов
/ 25 ноября 2011

Похоже, что в интерфейсе API нет поддержки прокрутки ваших собственных кодеков.Практически все классы являются окончательными (например, VideoTrack, Media, MediaPlayer и т. Д.).Я предполагаю, что фактическое декодирование видео выполняется с внутренними классами в настоящее время, то есть невозможно переопределить их.

Существует план по Open Source JavaFX 2.0 , я подозреваю, что мыподходить к выпуску JDK8.Надеемся, что когда они сделают это, мы увидим, как они разрешают свои кодеки из конструктора Media(String source), и посмотрим, сможем ли мы каким-то образом подключиться к этому.

2 голосов
/ 30 января 2018

Текущие открытые запросы функций для этого в системе отслеживания ошибок JavaFX:

Считать запросы связанных функций и связанные с ними комментарии, чтобы понять их текущее состояние (или его отсутствие ;-) для используемой версии дистрибутива JavaFX.,

Обратите внимание, что для Media API на основе InputStream один из более поздних комментариев разработчика JavaFX звучит так: «Я предлагаю рассмотреть это для JDK 10», поэтому я предполагаю, что это может произойти в будущем ...

Также обратите внимание, что если вы не уверены, что JavaFX в настоящее время имеет встроенную поддержку для данного типа кодировки, или нет, полный обзор поддерживаемых кодировок мультимедиа и типов контейнеров мультимедиа предоставляется в javadoc дляпакет javafx.media (просто убедитесь, что вы просматриваете версию javadoc, соответствующую вашей версии JavaFX).

Те, кто может быть заинтересован в других решениях, чтобы хотя бы получить видео для воспроизведения сJavaFX, даже если это тип мультимедиа, изначально не поддерживаемый JavaFX, и вы не хотите взламывать встроенную поддержку мультимедиа JavaFX просто для воспроизведения видео, также можете увидеть мой ответ на соответствующий вопрос:

...