web-dev-qa-db-fra.com

Ajout de bitmap en filigrane sur une vidéo sous Android: MediaMuxer ou ffmpeg de la 4.3

Voici mon scénario:

  • Télécharger un film AVI à partir du Web
  • Ouvrir une ressource bitmap 
  • Superposer cette image bitmap au bas du film sur toutes les images en arrière-plan
  • Enregistrer la vidéo sur le stockage externe
  • La durée de la vidéo est généralement de 15 secondes

Est-ce possible d’utiliser MediaMuxer? Toute information sur le sujet est reçue avec plaisir

Je cherchais http://bigflake.com/mediacodec/#DecodeEditEncodeTest (Merci @fadden) et cela dit: 

"Décoder le cadre et le copier dans un ByteBuffer avec glReadPixels() prend environ 8 ms sur le Nexus 5, assez rapidement pour que .__ reste en phase avec une entrée à 30fps, mais les étapes supplémentaires nécessaires pour sauvegarder. sur un disque sous forme de fichier PNG sont coûteux (environ une demi-seconde) "

Donc, avoir presque 1 seconde/image n'est pas acceptable. D'après ce que je pense, une façon serait de sauvegarder chaque image au format PNG, de l'ouvrir, d'ajouter la superposition bitmap dessus et de l'enregistrer. Cependant, cela prendrait un temps énorme. 

Je me demande s'il existe un moyen de faire des choses comme celle-ci:

  1. Ouvrir un fichier vidéo depuis un stockage externe
  2. Commencez à le décoder
  3. Chaque image décodée sera modifiée avec la superposition bitmap en mémoire
  4. La trame est envoyée à un encodeur.

Sur iOS, j'ai vu qu'il y avait un moyen de prendre l'audio original + la vidéo originale + une image et de les ajouter dans un conteneur, puis de tout encoder ...

Devrais-je passer à ffmpeg? Quelle est la stabilité et la compatibilité de ffmpeg? Est-ce que je risque des problèmes de compatibilité avec les appareils Android 4.0+? Existe-t-il un moyen d'utiliser ffmpeg pour y parvenir? Je suis nouveau dans ce domaine et je fais encore de la recherche.


Années plus tard, éditez: 
Des années ont passé depuis la question et ffmpeg n’est pas facile à ajouter à un logiciel commercial en termes de licence. Comment cela a-t-il évolué? Les nouvelles versions d'Android sont plus capables sur cela avec le SDK par défaut?


Encore un peu de temps plus tard, éditer

J'ai eu des votes négatifs pour avoir posté des infos comme réponse, alors je vais éditer la question initiale. Voici une excellente bibliothèque qui, de par mes tests, applique un filigrane à la vidéo et le fait avec rappel de progression, ce qui facilite grandement l'affichage des progrès à l'utilisateur et utilise également les sdks Android par défaut. https://github.com/MasayukiSuda/Mp4Composer-Android

Cette bibliothèque génère un film Mp4 à l'aide de l'API Android MediaCodec et applique un filtre, une mise à l'échelle et une rotation de Mp4.

Exemple de code, pourrait ressembler à:

new mp4Composer(sourcePath, destinationPath)
        .filter(new GlWatermarkFilter(watermarkBitmap)
        .listener(){
              @Override 
              private void onProgress(double value){}

              @Override 
              private void onCompleted(double value){
                  runOnUiThread( () ->{
                     showSneakbar
                  }
              }

              @Override 
              private void onCancelled(double value){}

              @Override 
              private void onFailed(Exception e){}

        }).start();

Tester sur un émulateur semble fonctionner correctement sur Android 8+, tandis que sur les versions plus anciennes, un fichier vidéo noir est généré. Toutefois, lorsque les tests sur un périphérique réel semblent fonctionner.

28
Alin

Je ne connais pas grand chose à propos de MediaMuxer mais ffmpeg prend en charge la fonctionnalité de superposition. FFMPEG a divers filtres dont l’un est le filtre superposé. Ce que je comprends, c’est que vous souhaitiez superposer une image (c’est-à-dire png) à la vidéo. Ffmpeg est certainement un cadre utile pour faire ce travail. Vous pouvez définir le format de sortie, ainsi que les coordonnées de l'image à sur-afficher. 

Par exemple.

ffmpeg -i input.avi -i logo.png -filter_complex 'overlay=10:main_h-overlay_h-10' output.avi

La commande ci-dessus ajoute des superpositions logo.png sur le fichier vidéo input.avi dans le coin inférieur gauche.

Plus d'informations sur les filtres sont disponibles sur le site web suivant,

https://www.ffmpeg.org/ffmpeg-filters.html#overlay-1

S'il s'agit d'une solution à votre problème, vous avez besoin du code C équivalent à la commande ci-dessus. Vous devez également voir les performances de ffmpeg car il s’agit d’un framework logiciel pur.

J'espère avoir bien compris votre question et cela aide.

19
pragnesh

Si vous avez besoin de faire ceci sans ffmpeg sur un appareil Android:

À partir de: https://github.com/google/grafika

La réponse à votre question entre les exemples Lire la vidéo (PlayMovieActivity.Java) et Record Gl (RecordFBOActivity.Java)

Pas:

  1. Configurez mInputWindowSurface en tant que surface d’entrée du codeur vidéo. 

  2. Décode l'image du flux vidéo en utilisant MoviePlayer en tant que texture vidéo (externe).

  3. Dessine cette texture vidéo sur Surface.

  4. Dessinez un filigrane sur la même surface sur une texture vidéo.

  5. Avertissez MediaCodec que la surface est prête pour l'encodage:

    mVideoEncoder.frameAvailableSoon(); 
    mInputWindowSurface.setPresentationTime(timeStampNanos);
    

    et puis passez à l'étape 2.

N'oubliez pas de régler la vitesse de décodage. Supprimez simplement SpeedControlCallback qui, dans l'exemple, est configuré pour décoder la vidéo à 60 images par seconde.

Avantages de cette façon:

  1. Media Codec utilise un décodeur/encodeur matériel pour le traitement vidéo. 

  2. Vous pouvez modifier le débit binaire de la vidéo obtenue.

10
AndreyICE

Vous pouvez essayer INDE Media Pack - https://software.intel.com/en-us/articles/intel-inde-media-pack-for-Android-tutorials

Il a des fonctionnalités de transcodage\remuxage comme la classe MediaComposer et plusieurs exemples d'effets tels que JpegSubstituteEffect - il montre comment remplacer l'image par une image d'un fichier jpg et TextOverlayEffect pour superposer du texte sur une image, etc.

enter image description here

7
Marlon

C'est ce qui a fonctionné pour moi:

ffmpeg -i input.avi -i logo.png -filter_complex 'overlay=10:main_h-overlay_h-10' -strict -2 output.avi

ffmpeg a recommandé l'utilisation de -strict -2 afin d'autoriser l'utilisation de codecs expérimentaux. sans l'inclusion, la réponse acceptée ci-dessus ne fonctionne pas.

1
kc ochibili