Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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.

Julien Salvi

April 10, 2017
Tweet

More Decks by Julien Salvi

Other Decks in Programming

Transcript

  1. Julien Salvi Android addict depuis Froyo Belgium beer lover! Twitter:

    @JulienSalvi Creative Technologist & Ingénieur Android @ Cinémur
  2. 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
  3. 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
  4. // 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
  5. 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
  6. 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
  7. 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
  8. // 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);
  9. // 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);
  10. 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);
  11. Lecture d’une vidéo en boucle MediaSource source = new ExtractorMediaSource(videoUri,

    ...); // Loops the video indefinitely. LoopingMediaSource loopingSource = new LoopingMediaSource(source);
  12. 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);
  13. GoogleVR SDK (1.30) Java, OpenGL ES, JNI GearVR Mobile SDK

    (1.5) C/C++, JNI Développement natif sur Android
  14. 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
  15. 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
  16. Developper son plugin en Java ou C/C++ Plugins utilisables avec

    Unity : .jar, .aar ou .so Développer un plugin Android pour Unity
  17. 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
  18. 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 ();
  19. 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++
  20. 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++
  21. 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++
  22. 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
  23. "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 !