ExoPlayer, player multimédia pour les applications et la réalité virtuelle

ExoPlayer, player multimédia pour les applications et la réalité virtuelle

Cette présentation commencera avec une introduction à ExoPlayer qui en fait un remplaçant naturel de MediaPlayer. Les fonctionnalités de la v1 à v2 seront exposées avec les pour et les contre, le différents formats supportés par la player, ses différentes extensions... On vous montrera comment migrer votre code MediaPlayer vers ExoPlayer en quelques lignes de code. On finira par la capacité d'ExoPlayer à être utilisé dans le domaine de la réalité virtuelle sur Android pour créer des players pour Cardboard / Daydream ou GearVR et comment l'utiliser à l'aide d'un plugin sur Unity.

56047a7b11797f42c2e7030d771fe803?s=128

Julien Salvi

April 10, 2017
Tweet

Transcript

  1. ExoPlayer Julien Salvi Player multimédia pour les applications et la

    réalité virtuelle
  2. Julien Salvi Android addict depuis Froyo Belgium beer lover! Twitter:

    @JulienSalvi Creative Technologist & Ingénieur Android @ Cinémur
  3. ExoPlayer à votre service ! Un player multimédia sur Android

    ?
  4. 1 Pour commencer Ce bon vieux MediaPlayer

  5. Modèle du MediaPlayer sur Android

  6. MediaPlayer, lecteur média par défaut sur Android. Introduction des API

    bas niveau MediaExtractor, MediaCodec ou MediaDrm depuis Jelly Bean. → Simple d’utilisation → Customisation difficile → Un nombre de formats limité Une solution basique
  7. 2.1 Passons aux choses sérieuses ExoPlayer - Version 1

  8. repositories { jcenter() } dependencies { ……. compile 'com.google.android.exoplayer:exoplayer:rX.X.X' …….

    } Import dans Gradle
  9. Une architecture améliorée

  10. Exoplayer v1 en chiffres 5 Extensions Supports DRM 2 10+

    Formats vidéo MP4, FMP4, FLV, WebM, MKV, Ogg... 10+ Formats audio MP3, AAC, Flac, MIDI, Opus, WAV... Formats textes 3 Adaptive streaming 3
  11. Un peu de code ! (quand même)

  12. // 1. Instantiate the player. player = ExoPlayer.Factory.newInstance(RENDERER_COUNT); // 2.

    Construct renderers. MediaCodecVideoTrackRenderer videoRenderer = ... MediaCodecAudioTrackRenderer audioRenderer = ... // 3. Inject the renderers through prepare. player.prepare(videoRenderer, audioRenderer); // 4. Pass the surface to the video renderer. player.sendMessage(videoRenderer, MediaCodecVideoTrackRenderer.MSG_SET_SURFACE, surface); // 5. Start playback. player.setPlayWhenReady(true); ... player.release(); // Don’t forget to release when done! Instantiation du player
  13. Allocator allocator = new DefaultAllocator(BUFFER_SEGMENT_SIZE); DataSource dataSource = new DefaultUriDataSource(context,

    null, userAgent); ExtractorSampleSource sampleSource = new ExtractorSampleSource( uri, dataSource, allocator, BUFFER_SEGMENT_COUNT * BUFFER_SEGMENT_SIZE); MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer( context, sampleSource, MediaCodecSelector.DEFAULT, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT); MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer( sampleSource, MediaCodecSelector.DEFAULT); Préparation des renderers
  14. 2.2 On sort l’artillerie lourde ExoPlayer - La version 2

    à la rescousse !
  15. Introduit en Septembre 2016 (version 2.3.1 actuellement) Une nouvelle architecture

    pour lutter contre les limitations de la v1 Amélioration de l’audio et des supports de formats vidéo Introduction de nouvelles extensions (ffmpeg, GVR) Implémentation et customisation simplifiées ExoPlayer v2 en quelques mots
  16. Et en chiffres ? 7 Extensions Supports DRM 3 10+

    Formats vidéo MP4, FMP4, FLV, WebM, MKV, Ogg... 10+ Formats audio MP3, AAC, Flac, MIDI, Opus, WAV... Formats textes 4+ Adaptive streaming 3
  17. Spoiler : OUI Mais c’est si simple que ça dans

    le code ?
  18. // 1. Create a default TrackSelector Handler mainHandler = new

    Handler(); BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter(); TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter); TrackSelector trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory); // 2. Create a default LoadControl LoadControl loadControl = new DefaultLoadControl(); // 3. Create the player SimpleExoPlayer player = ExoPlayerFactory.newSimpleInstance(context, trackSelector, loadControl); // 4.Bind the player to the view. simpleExoPlayerView.setPlayer(player);
  19. // 5. Preparing the player // Produces DataSource instances through

    which media data is loaded. DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(this, Util.getUserAgent(this, "yourApplicationName"), bandwidthMeter); // Produces Extractor instances for parsing the media data. ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory(); // This is the MediaSource representing the media to be played. MediaSource videoSource = new ExtractorMediaSource(mp4VideoUri, dataSourceFactory, extractorsFactory, null, null); // Prepare the player with the source. player.prepare(videoSource); // 6. Play the content player.setPlayWhenReady(true);
  20. Nouvelles fonctionnalités

  21. Changement de sous-titres externes MediaSource videoSource = new ExtractorMediaSource(videoUri, ...);

    MediaSource subtitleSource = new SingleSampleMediaSource(subtitleUri, ...); // Plays the video with the sideloaded subtitle. MergingMediaSource mergedSource = new MergingMediaSource(videoSource, subtitleSource);
  22. Lecture d’une vidéo en boucle MediaSource source = new ExtractorMediaSource(videoUri,

    ...); // Loops the video indefinitely. LoopingMediaSource loopingSource = new LoopingMediaSource(source);
  23. Concaténation de vidéos MediaSource firstSource = new ExtractorMediaSource(firstVideoUri, ...); MediaSource

    secondSource = new ExtractorMediaSource(secondVideoUri, ...); // Plays the first video, then the second video. ConcatenatingMediaSource concatenatedSource = new ConcatenatingMediaSource(firstSource, secondSource);
  24. MediaPlayer ExoPlayer (You vs. the guy she told you not

    to worry about)
  25. 3 La vidéo sur mobile ? #old Place à la

    Réalité Virtuelle !
  26. John Carmack It's a moral imperative that we must create

    this “ NOT SO BAD
  27. GoogleVR SDK (1.30) Java, OpenGL ES, JNI GearVR Mobile SDK

    (1.5) C/C++, JNI Développement natif sur Android
  28. Création d’une lib wrapper Création d’une classe helper pour exposer

    les méthodes d’initialisation du player et de ses contrôles. Ajout d’extensions nécessaires (GVR, FFMPEG, OkHttp… ) Intégration d’une gestion DRM autre que Widevine
  29. Plugin player basé sur ExoPlayer GoogleVR SDK OpenGL ES Player

    de test
  30. MovieTexture de Unity pas compatible avec Android Etablir le lien

    entre la texture Unity et la surface Android pour effectuer le rendu vidéo Player Android pour Unity
  31. Developper son plugin en Java ou C/C++ Plugins utilisables avec

    Unity : .jar, .aar ou .so Développer un plugin Android pour Unity
  32. Avec du C# et C++ au menu Direction Unity et

    la JNI !
  33. AndroidJavaObject localMediaPlayer = null; using (AndroidJavaClass javaUnityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))

    { using (currentActivity = javaUnityPlayer.GetStatic<AndroidJavaObject>("currentActivity")) { localMediaPlayer = new AndroidJavaObject("my/plugin/vr/ExoPlayerBridge", currentActivity); if (localMediaPlayer != null) { // Do some work with your java object outside the Android UI thread localMediaPlayer.Call("addSubtitles", subtitleURL); currentActivity.Call("runOnUiThread", new AndroidJavaRunnable(() => { // Do some work on Android UI thread localMediaPlayer.Call("prepare", true); })); } } } Appeler un objet Java depuis Unity
  34. Fonction se trouvant dans le plugin Définition de la fonction

    dans le script Unity extern "C" { float FooPluginFunction (); } Plugin C/C++ [DllImport ("PluginName")] private static extern float FooPluginFunction ();
  35. Gain de performance en passant par la JNI pour appeler

    des fonctionnalités de votre plugin Java Important: chargement de la JVM jint JNI_OnLoad(JavaVM* vm, void* reserved) { JNIEnv* jni_env = 0; vm->AttachCurrentThread(&jni_env, 0); return JNI_VERSION_1_6; } Plugin Java et C/C++
  36. Exemple de fonction JNI pour interagir avec votre class Java

    JNIEXPORT jobject JNICALL Java_com_example_NativeClass_nativeMethod(JNIEnv* env) { jclass cls_JavaClass = env->FindClass("com/your/java/Class"); // find class definition jmethodID mid_JavaClass = env->GetMethodID (cls_JavaClass, "<init>", "()V"); // find constructor method jobject obj_JavaClass = env->NewObject(cls_JavaClass, mid_JavaClass); // create object instance return env->NewGlobalRef(obj_JavaClass); // return object with a global reference } Plugin Java et C/C++
  37. Passage de la texture Unity vers Android // Can't use

    AndroidJavaObject.Call() with a jobject, must use low level interface IntPtr setSimplePlayerID = AndroidJNI.GetMethodID(localMediaPlayer.GetRawClass(), "setSurface", "(Landroid/view/Surface;)V"); jvalue[] parms = new jvalue[1]; parms[0] = new jvalue(); parms[0].l = _androidSurface; // Android Surface reference as an IntPtr AndroidJNI.CallVoidMethod(localMediaPlayer.GetRawObject(), setSimplePlayerID, parms); Plugin Java et C/C++
  38. J N I Java code C/C++ code ExoPlayer

  39. None
  40. https://medium.com/google-exoplayer https://medium.com/@cinemur/73ec7e83dd5c Medium ExoPlayer: ExoPlayer for building powerful VR players

    on Cardboard and GearVR: https://docs.unity3d.com/Manual/PluginsForAndroid.html Développer des plugins Android pour Unity: Pour en savoir plus
  41. "VR can be tremendously fun and beautiful. It's been frustrating

    that more people haven't been able to enjoy it for so many years. I hope lots of people will soon find VR to be as fascinating as I have." “La Réalité virtuelle peut être fun et magnifique. C’est frustrant de savoir que les gens n’en ont pas profité depuis des années. J’espère que bientôt beaucoup de monde seront fascinés par la VR autant que je le suis” Jaron Lanier - term of Virtual Reality Inventor Merci !