Video in Android Mode

2»

Answers

  • Thanks @hudson_m4000 that looks really promissing! But it seems i'm missing some android methods, and can't solve "Build" and "context" Are you importing anything which doesn't show in the code here?

    (thanks for the tip @Chrisir, this post just looked the closest to my problem I could find :) )

  • @flashbacker

    Please post the entire error and if possible, your code. Referring to the context, you can get it from the Activity. There are few examples in the forum showing how to do this.

    Notice there is a new forum @ https://discourse.processing.org

    Kf

  • Actually I could make it work by changing a few things and not testing the API (since I don't need that for now). I get the path right I guess, for both external and internal memory (the previous method was only giving internal memory actually), but I still get the same error "file not found"...

  • @kfrajer

    I've actually managed to use hudson_m4000 code to confirm what the path of my video file should be. Problem even with this info, my processing sketch won't find my file. The following code (even if I know it can't show the video image) compile on my device, but return to the console "error loading transit.mp4":

    import android.media.MediaPlayer;
    import android.os.Environment;
    import android.app.Activity;
    import android.content.Context;
    MediaPlayer mp ;
    Context context ;
    Activity activity ;
    String statusText = "VIDEO INITIALIZING";
    String SDCard = new String(Environment.getExternalStorageDirectory().getAbsolutePath());
    //String SDCard = "/storage/3E07-120C/";
    
    void setup() {
      size(400,400);
      activity = this.getActivity();
      context = activity.getApplicationContext();
      mp = new MediaPlayer();
      println( SDCard);
      try {
        mp.setDataSource(SDCard + "machine.mp4");
        mp.prepare();
        mp.start();
        statusText = "VIDEO PLAYING";
      }
      catch (IOException e) {
        println("error loading transit.mp4");
      }
      fill(255); 
      textAlign(CENTER, CENTER);
    }
    

    This code can't compile:

    import android.media.MediaMetadataRetriever;
    import android.os.Handler;
    import android.os.HandlerThread;
    import android.os.Looper;
    import android.app.Activity;
    import android.view.ViewGroup;
    import android.view.View;
    import android.view.SurfaceHolder;
    import android.view.SurfaceView;
    import android.media.MediaMetadataRetriever;
    import android.media.MediaPlayer;
    import android.content.res.Resources;
    import android.content.res.AssetFileDescriptor;
    import android.content.res.AssetManager;
    import android.content.Context;
    
    AssetFileDescriptor afd;
    Context context;
    Activity act;
    SurfaceView mySurface;
    SurfaceHolder mSurfaceHolder;
    MediaMetadataRetriever metaRetriever;
    MediaPlayer mMediaPlayer;
    
    void setup() {
      size(400, 400, P2D);
      act = this.getActivity();
      context = act.getApplicationContext();
      Looper.prepare();
      mMediaPlayer = new MediaPlayer();
      try {
        afd = context.getAssets().openFd("machine_compr.mp4");
        MediaMetadataRetriever metaRetriever = new MediaMetadataRetriever();
        metaRetriever.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
        String height = metaRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT); 
        if (int(height) < 2) {
          throw new IOException();
        }
      }
      catch (IllegalArgumentException e) {
        e.printStackTrace();
      }
      catch (IllegalStateException e) {
        e.printStackTrace();
      } 
      catch (IOException e) {
        e.printStackTrace();
      }
    
      mySurface = new SurfaceView(act);
      mSurfaceHolder = mySurface.getHolder();
      mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
      mSurfaceHolder.addCallback(new SurfaceHolder.Callback() {
        @Override
          public void surfaceCreated(SurfaceHolder surfaceHolder) {
          mMediaPlayer.setDisplay(surfaceHolder);
        }
    
        @Override
          public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i2, int i3) {
          mMediaPlayer.setDisplay(surfaceHolder);
        }
    
        @Override
          public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
        }
      }
      );
      startVideo();
    }
    
    void startVideo() {
      act.runOnUiThread(new Runnable() {
        public void run() {
          try {
            mMediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
            mSurfaceHolder = mySurface.getHolder();
            mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
            mMediaPlayer.prepare();
    //        act.addContentView(mySurface, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT));
            act.addContentView(mySurface, new ViewGroup.LayoutParams(400,400));
            if (mMediaPlayer.isPlaying() == false) {
              mMediaPlayer.start();
            }
          }
          catch (IllegalArgumentException e) {
            e.printStackTrace();
          }
          catch (IllegalStateException e) {
            e.printStackTrace();
          } 
          catch (IOException e) {
            e.printStackTrace();
          }
        }
      }
      );
    };
    
    void draw() {
    }
    
    void onPause() {
      if (mMediaPlayer!=null) {
        mMediaPlayer.release();
        mMediaPlayer = null;
      }
      super.onPause() ;
    }
    
    void onStop() {
      if (mMediaPlayer!=null) {
        mMediaPlayer.release();
        mMediaPlayer = null;
      }
      super.onStop() ;
    }
    
    void onDestroy() {
      if (mMediaPlayer!=null) {
        mMediaPlayer.release();
        mMediaPlayer = null;
      }
      super.onDestroy() ;
    }
    
    void onResume() {
      super.onResume() ;
    }
    

    and the console says it's because file couldn't be loaded

    OpenGL error 1280 at bot beginDraw(): invalid enum
    java.io.FileNotFoundException: machine_compr.mp4
        at android.content.res.AssetManager.openAssetFd(Native Method)
        at android.content.res.AssetManager.openFd(AssetManager.java:334)
        at processing.test.android_nativeplayer.android_nativeplayer.setup(android_nativeplayer.java:66)
        at processing.core.PApplet.handleDraw(PApplet.java:1801)
        at processing.opengl.PSurfaceGLES$RendererGLES.onDrawFrame(PSurfaceGLES.java:264)
        at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1590)
        at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1286)
    FATAL EXCEPTION: main
    Process: processing.test.android_nativeplayer, PID: 12773
    java.lang.NullPointerException: Attempt to invoke virtual method 'java.io.FileDescriptor android.content.res.AssetFileDescriptor.getFileDescriptor()' on a null object reference
        at processing.test.android_nativeplayer.android_nativeplayer$2.run(android_nativeplayer.java:110)
        at android.os.Handler.handleCallback(Handler.java:815)
        at android.os.Handler.dispatchMessage(Handler.java:104)
        at android.os.Looper.loop(Looper.java:207)
        at android.app.ActivityThread.main(ActivityThread.java:5765)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:679)
    OpenGL error 1285 at bot endDraw(): out of memory
    

    I'll maybe try a post on the new forum, but there's so much ressource here, it felt more accurate to post here rather than create a new post which would point towards here...

  • @flashbacker

    Yes, you need these imports and create a context (as you have done in your code above)

    import android.content.Context; import android.os.Build ;

    Context context;' Activity act;

    and in setup ...

    act = this.getActivity(); context = act.getApplicationContext();

  • @flashbacker

    What is the full address of your video file?

    You seem to just be trying to open "machine_compr.mp4", which without anything else is just your data folder. If it's on your internal/external SD, then this will give you the error!

  • edited July 2018

    @hudson_m4000 Thanks a lot for your feed back! I've finally found out about your code for the file's path and thanks for explaining me for the second code where I was calling the file from the data folder, I was a bit confused about this method compared to the previous one...

    However, I tried to replace with
    "/storage/emulated/0/machine_compr.mp4"
    in my both devices and
    "storage/3E07-120C/machine_compr.mp4"
    in my device which has an external SD card (the video file is always placed in the root folder of the storage).
    I even tried to put the video in the data folder, just for the sake of it... I always end up with the same error that I described above.

    I've allowed the 3 access location permissions types in the sketch permissions, but nothing will do

    Is there anything else I could try?

  • edited July 2018

    @flashbacker I am going to try your code ... will post back soon with my findings

  • There was a recent change of the dataPath() function and it should work if you place your video inside the data folder. When the Android app is built, dataPath() works along the same lines as getAssets(). I haven't had the chance to test your code but I would like to suggest you try getAssets() instead for now. Please check this post and see if it works for you:

    https://discourse.processing.org/t/tracking-high-score-for-android/678/4

    Kf

  • thanks

    @kfrajer isn't it what is already in use in the second code here ? afd = context.getAssets().openFd("machine_compr.mp4");

    @hudson_m4000 I would be curious to see if it works for you and what you changed

    Over all, thanks for your help and feedbacks, I wanted to make a simple video player controlled by OSC for a project, and run it on several tablets. I choose to use processing because I'm used to make simple projects with it, I think I didn't realized there was such a step when working for android... Maybe it's out of reach for my level now and I should find some work arounds...

  • edited July 2018

    @flashbacker

    No luck so far! Like you I am a Processing fan rather than AS or Eclipse as I'm not a professional programmer! It is clear that anything like this dealing with video, the Processing way of being simple for us artists and designers just doesn't apply sometimes, especially for Android .... we need to know the SDK (and then workarounds!) to get things going after that, so even by looking at tutorial code websites, it's all for AS so can't be used in Processing without a lot of knowledge ... which we don't have! It would be great to have something like the Image class so we can just load a play the audio/video, but we don't ... and we struggle to even get anything.

    Why we you need to have to get the activity/context and then use MediaPlayer with VideoView etc ... why not just a method that has something like:

    myVideo = loadVideo("myvideo.mp4")

    and then just

    myVideo.play().

    I bet hundreds of experienced coders could easily wrap all the hard stuff in a VideoClasss for users like us ... but no one has ... :( I hope and pray that @akenaton may one day share his full working code in Processing sketch. I understand his desire for us all to learn (and move to AS .. but let's face it most of us won't because we buy into and like Processing) and is always so helpful, but this has been going for 3 years now and we still can't do it. Please share with us .... if I can have some working code, I will put it it a class to wrap it all and then see if I can get the Android dev team to add it to the Android Mode .. not a library as they always go out of date ... if it's in the mode itself then it's going to be there forever!

    'For now though I carry on tinkering and sort of learning :)

    I am going to stop posting here and start a new thread at the new forum to see if we can get some new insights .... see you there under my new userID of sessionShed :)

  • Really good comments @hudson_m4000

    Please don't forget to cross link your posts.

    I haven't had the time to check your code @flashbacker. I have had some issues myself with accessing Android res from processing. However, I know it is possible as it has been done before. I think we just need better documentation.

    Related to the wrapper for MediaPlayer, I believe @codeanticode has suggested something like that before. There are no enough hands on deck to do this type of work. Nevertheless, I agree it is important thing to do as it would make things much easier to implement, at least for the demonstration stage.

    These two links are relevant for anybody else reading this post:

    https://github.com/processing/processing-library-template
    https://github.com/processing/processing-android-library-template

    Kf

  • @kfrajer

    See new forum ... I got it working

Sign In or Register to comment.