Подтвердить что ты не робот

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

<я > Обновление:

Поскольку медиа-сторона 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 ответом на это, или просто еще одна наполовину попытка, которая никогда не будет играть больше, чем то, что она на данный момент! Я надеюсь, что это не последнее, но мне еще предстоит увидеть многое, чтобы показать это.

4b9b3361

Ответ 1

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

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

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

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

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

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

Ответ 2

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

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

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

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

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

Ответ 3

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

Ответ 4

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

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

Ответ 5

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

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

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

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

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