Ajout d'autres codecs vidéo / support DVD à JavaFX 2.2


Mise à Jour:

Étant donné que le côté média de JFX est open source, j'ai moi-même examiné cela et c'est en effet possible, mais nécessite de changer et de reconstruire la source JFX (parties Java et C.) Le processus est décrit ici pour tous ceux qui veulent avoir un go - J'ajoute le support MKV dans cet exemple, mais il devrait être très similaire pour les autres plugins.

Le reste de la question est donc principalement historique, mais je la laisse ici pour référence.

Contexte

J'ai utilisé VLCJ jusqu'à présent pour lire des vidéos dans mon application. Cela fonctionne, mais si possible, j'aimerais voir si je peux atteindre un niveau de support similaire pour les codecs courants en migrant vers JavaFX et en m'épargnant beaucoup de tracas avec plusieurs machines virtuelles et tel que VLCJ doit lire plusieurs vidéos de manière fiable. Je ne vais pas y entrer ici mais voir ma réponse à cette question si vous êtes intéressé par les détails. Il y a aussi la question de la compatibilité multiplateforme, cela fonctionne sur Mac et Linux ok mais je n'ai pas encore trouvé comment l'afficher sur Mac (je crois qu'il y a une certaine sécurité en place pour empêcher un processus d'accéder aux composants natifs d'un autre, mais encore une fois, cela dépasse le cadre de cette question.)

Cela se résume au fait que pendant que cela fonctionne, il faut beaucoup de maintenance et de tracas pour travailler avec plusieurs machines virtuelles et les combler de manière stable s'il existe une autre solution qui serait plus facile. VLC a un niveau de support assez légendaire pour jouer à peu près n'importe quoi, c'est pourquoi je l'ai suivi jusqu'à présent, et je serais intéressé de voir si je peux obtenir un résultat similaire dans JavaFX - ou du moins s'il peut fournir les moyens de le faire de manière multiplateforme.

Recherche

JavaFX 2.0 prend en charge la vidéo - génial! Mais pour le moment, la ligne officielle est qu'il prend en charge "FLV contenant de la vidéo VP6 et de l'audio MP3". Existe-t-il un moyen d'étendre cela pour ajouter la prise en charge de plus de codecs? Il n'y a pas codec dur que j'aimerais soutenir, c'est plus un cas d'autant que je peux donc je cherche une méthode extensible pour aller sur ce qui précède.

Je me suis demandé s'il lirait la vidéo pour les codecs installés nativement sur la machine et qu'il ne se fait tout simplement pas de publicité en tant que telle (car cette fonctionnalité dépend évidemment de la machine et non multiplateforme.) Mais pas de dés, j'ai essayé un certain nombre de formats courants et il refuse vraiment de jouer autre chose que ce qu'il indique.

De en regardant JavaFX 1.3, il prend également en charge d'autres codecs dépendant de la plate-forme en fonction de l'endroit où il est installé . Est-il un moyen d'obtenir ce comportement avec JavaFX 2? Ou est-il prévu du tout pour une version ultérieure? Je n'ai pas pu trouver d'informations à ce sujet sur la feuille de route ni aucun commentaire d'Oracle à ce sujet.

La seule chose que j'ai pu trouver en cherchant beaucoup est ici ce qui implique que cela peut être possible mais personne ne semble savoir comment. Je serais également intéressé à savoir s'il est basé sur GStreamer pourquoi tous les formats pris en charge par GStreamer ne sont pas non plus inclus par défaut?

En termes de lecture de DVD avec JavaFX, je n'ai absolument nulle part, donc je suppose que c'est juste un no-go pour le moment. Si quelqu'un a des idées ou des informations, je suis tout ouïe.

Autres approches

Une approche dont je me demandais à moitié peut être possible est de sortir le pot JMC de l'ancien JavaFX comme décrit ici et d'essayer d'obtenir qui travaille aux côtés de JavaFX 2. Je suppose que personne n'a eu de chance avec cette approche ou quelque chose de similaire?

Toutes les choses échouent, si quelqu'un a des informations ou des liens sur si / quand la prise en charge de codecs supplémentaires sera prise en charge hors de la boîte, alors je serais intéressé d'entendre cela aussi. Ou si quelqu'un a des coordonnées pour quelqu'un chez Oracle, je pourrais demander cela serait également apprécié! Je rêvais d'un support vidéo décent en Java depuis un certain temps, et je suppose ce que cela se résume à essayer de comprendre si JavaFX est la réponse à cela, ou juste une autre tentative timide qui ne jouera jamais plus que ce qu'il fait en ce moment! J'espère que ce n'est pas le dernier, mais je n'ai pas encore beaucoup à montrer qui est le cas.

Author: Community, 2011-11-16

5 answers

Croyez-moi, je ressens et connais votre frustration. J'ai réfléchi à cela pendant un moment, mais j'ai dû utiliser des moyens non droits pour résoudre mes problèmes.

Il y a plusieurs façons de contourner cela, chacune avec des limitations mais dépend de ce qui fonctionne pour vous:

  1. Les documents disent que WebView fonctionne avec HTML5, qui lit les vidéos prises en charge sur la plate-forme (mais malheureusement pas flash). Si l'utilisation d'une vue Web pour lire une vidéo fonctionne pour vous, vous pouvez l'essayer. Vous pouvez même dessiner dessus avec d'autres nœud.

  2. Lecteur VLC portable! Si vous développez peut-être une sorte d'application projecteur/réalisateur et que vous voulez une vidéo en plein écran, vous pouvez demander au lecteur VLC portable de lire la vidéo en plein écran sur un écran avec ses commandes dans l'autre. Utilisé cette solution et il fonctionne très bien pour Mac et Windows. :) La seule chose est que vous ne pouvez pas dessiner de nœuds sur la vidéo car il s'agit d'une application externe, avec juste l'illusion d'une vidéo en plein écran de votre application.

  3. Si jamais vous avez besoin d'utiliser la puissance de flash dans votre application javafx 2.0, puis utilisez un navigateur basé sur swt (ou quelque chose comme le DJ Project si vous êtes un échangiste) car ils prennent en charge toutes les fonctionnalités de votre navigateur natif.

 10
Author: Glstunna, 2011-11-27 00:06:29

J'ai maintenant réussi à compiler le support MKV dans JavaFX avec succès, et cela prend un peu, mais pas beaucoup d'efforts sur la couche native également. Voir icipour la discussion qui l'entoure, et ici pour le résultat soumis en tant que ticket patch / JIRA.

J'ai écrit un guide beaucoup plus complet sur le processus ici qui peut intéresser quiconque cherche à suivre cette voie.

Ce qui suit est-ce que ma brève enquête avant que je ne regarde sérieusement la compilation d'autres supports médiatiques, bien que je le laisse ici pour référence.

Maintenant que JFX8 a été publié et est complètement open source, j'ai passé un peu de temps à regarder comment cela pourrait être fait, et si cela pourrait être fait sans patcher la source JFX. Malheureusement, la réponse à ce dernier point est un non presque définitif, du moins pas sans hacks horribles de manipulation de bytecode. Je peux examiner cela plus pratiquement à une date ultérieure, mais je vais documenter ce que j'ai travaillé jusqu'à présent à partir de la source disponible.

La magie commence à partir du Media constructor, qui est finalement d'où sort le MediaException (avec l'indicateur MEDIA_UNSUPPORTED si vous essayez de lire un format non pris en charge.) À partir de là, il crée le Locator, dont le constructeur garantit que l'URL est prise en charge. Sa méthode init() est ensuite appelée dans un thread séparé, qui effectue une vérification de la santé mentale sur la chaîne d'URL, lit le fichier, puis procède à essayer de déterminer quel est le format.

Le code pour cette partie de la méthode est donc:

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;
}

De cela, nous pouvons voir une première tentative "stupide" est faite pour récupérer le contenu du fichier en fonction de son nom (c'est ce que fait MediaUtils.filenameToContentType().) Il y a alors quelques cas spéciaux pour vérifier différents types de fichiers wav, mais si cela échoue, nous nous rabattons sur une vérification plus intelligente qui regarde la signature réelle du fichier. Ces deux contrôles sont en MediaUtils . Ce dernier contrôle est beaucoup plus vaste, et regarde les premiers octets du fichier pour voir s'il peut travailler sur un format moyen. S'il ne peut pas, alors il renfloue et jette l'exception qui apparaît alors comme notre drapeau redouté MEDIA_UNSUPPORTED.

Si le type est correctement identifié, il y a encore un autre obstacle à franchir - il doit être pris en charge par la plate-forme actuelle. Certaines plates-formes sont chargées dynamiquement en fonction de l'environnement, cependant GSTPlatform existe toujours, nous aurions donc besoin de mettre tous les formats supplémentaires (universels) ici. C'est relativement simple, un tableau CONTENT_TYPES existe qui contient juste le tableau des formats pris en charge.

Malheureusement, le clonage du dépôt JavaFX semble échouer pour le moment, sinon j'essaierais de mettre cela en pratique. Mais au lieu de ce qui précède, que doit-il se passer pour ajouter la prise en charge d'autres formats? Cela ne semble pas énorme difficile.

  1. Dans MediaUtils, le support doit être ajouté à la filenameToContentType() méthode pour gérer la nouvelle extension de fichier. C'est trivial.

  2. Dans la même classe, le support doit être ajouté à la méthode fileSignatureToContentType() pour calculer le type de fichier en fonction de sa signature. C'est un peu plus complexe, mais toujours pas trop mal. Cela peut même être facultatif, car le code actuel ne semble l'utiliser que si le format n'est pas identifié correctement (ou pas du tout) à partir de l'extension de fichier. Une liste complète des signatures de fichiers pour différents formats peut être trouvée ici ce qui devrait aider à cette tâche.

  3. Dans GSTPlatform, le nouveau type de contenu doit être ajouté à la liste des types de contenu pris en charge.

Du côté Java des choses, cela semble être tout ce qui est nécessaire pour l'amener à accepter le type de contenu et au moins tenter de le transmettre au Gstreamer natif couche .

Cependant, je ne suis pas un expert en GStreamer, donc bien que je sache qu'il peut gérer et lire beaucoup plus de formats que JavaFX refuse actuellement, je ne sais pas comment comment exactement ils ont supprimé cette capacité. Ils l'ont certainement fait dans la couche Java ci - dessus, mais ils l'ont peut-être également fait au niveau GStreamer natif-à ce stade, je ne suis pas sûr.

Je suppose qu'ils ont apporté quelques modifications à GStreamer pour JFX8-mais à l'heure actuelle, ils ne sont pas répertoriés sur lapage de projet pertinente , il est donc assez difficile de déterminer exactement ce qu'ils ont changé pour cette version.

L'étape suivante consisterait à saisir la source JFX8, à construire avec les modifications proposées ci-dessus pour un nouveau type de contenu, puis à voir quelles erreurs (le cas échéant) se produisent au niveau natif, puis à le prendre à partir de là.

 8
Author: Michael Berry, 2014-03-27 16:13:33

Et maintenant, Javafx2.1 prend enfin en charge mp4 H. 264, vous devriez donc maintenant être prêt à partir sans les cascades affichées ci-dessus. :)

 6
Author: Glstunna, 2012-03-27 23:19:52

La conception de l'API ne semble pas prendre en charge le déploiement de vos propres codecs. Presque toutes les classes sont finales (par exemple VideoTrack, Media, MediaPlayer, etc.). Je suppose que le décodage vidéo réel se fait avec des classes internes à l'heure actuelle, ce qui signifie qu'il n'y a aucun moyen de les remplacer.

Il existe un plan pour ouvrir JavaFX 2.0, je soupçonne que nous approchons de la sortie de JDK8. Espérons que quand ils font cela, nous pouvons voir comment ils résolvent leurs codecs à partir du constructeur Media(String source) et voir si nous pouvons accrocher à ce en quelque sorte.

 5
Author: Bringer128, 2011-11-25 06:12:20

Demandes de fonctionnalités ouvertes actuelles pour cela dans le système de suivi des bogues JavaFX:

Lisez les demandes de fonctionnalités liées et les commentaires associés à leur sujet pour comprendre leur statut actuel (ou leur absence ;-) pour la version de distribution JavaFX que vous utilisez.

Remarque, pour l'API multimédia basée sur InputStream, l'un des les commentaires d'un développeur JavaFX sont "Je propose que nous considérions cela pour JDK 10", donc je suppose que cela peut être une possibilité à l'avenir...

Notez également que si vous n'êtes pas sûr que JavaFX ait actuellement un support intégré pour un type d'encodage donné ou non, un aperçu complet des encodages multimédias pris en charge et des types de conteneurs multimédias est fourni dans le javadoc pour javafx.media package (assurez-vous simplement de vérifier la version du javadoc qui correspond à votre version de JavaFX).

Ceux qui pourraient être intéressés par d'autres solutions pour au moins obtenir une vidéo à lire à partir de JavaFX, même s'il s'agit d'un type de média non supporté nativement par JavaFX et que vous ne voulez pas pirater le support multimédia natif de JavaFX juste pour que votre vidéo soit lue, peuvent également voir ma réponse à]}

 2
Author: jewelsea, 2018-01-30 00:32:36