Video in Android Mode

… this takes over and continues from the thread at the old forum

@flashbacker

The line … afd = context.getAssets().openFd(“machine_compr.mp4”); generates a file error for me too if the video is in the project folder. if you create a Data folder and put the video in there it works! When Processing turns your sketch into ‘proper’ Java/Android, the video is put into the apps Assets folder which is where getAssets() looks for it. I am guessing that this is why trying to load from and SD with this method doesn’t work… the file has to be in the Assets folder.

A start at least!!

@akenaton At last I can see a video … phew … hard work yes and more yet to be done but it’s a start!

1 Like

@shedMusic===

i dont have time enough to go to the “old forum” but i un derstand reading your pos that you have tried the afd putting your video on the SD card: in this case afd cannot work (but you can use URI to make it running)
i am happy to have helped you and that finally it runs: now you can see that you can play video without any library…

good luck!

@akenaton
Yes, that’s right … it runs. Just now trying look at the surface view stacking order as if use full screen, the video goes behind the main sketch … I am at least again motivated to try again!

Edit:… and I found it … mySurface.setZOrderOnTop(true)

:slight_smile: Happy days

@shedMusic
Yes it works! :slight_smile:
So the problem is really the file location when trying to put it on the SD card… Should we get back to DataSource() for that?
I can’t just export the app with the videos because my “playlist” is supposed to change dynamically

But it feels good to see finally something happening, thank you so much! :slight_smile:

@flashbacker

Yes, the problem is using getAssets. as this is searching in the assets folder of the app. I want the same as you … dynamically from the SD Card! @akenaton say it can be done using URI … so that’s where I will be looking next.

We’ll get there!

Great, I’m starting to read about URI as well. I have to admit it’s a brand new world to me!

Hi all. First time on the new forum. Great.

Thanks to all the participants on this epic thread on how to get a bit of video to play in Android. I am trying to implement a simple looping video kiosk-style Android app for deployment on a tablet. I’m struggling putting together the bits from this thread to get a demo going! Question is – is there any simple single code listing for how to do it? Ideally I’d like to play back the video in the data folder as per a desktop app. Any help appreciated.

I have sorted it! Apologies – found another bit of this thread. I slightly adjusted the example (removed SD card stuff) and made it full screen. It plays any video in the data folder (default is ‘video.mp4’). Thanks again to all previous posters and here is my final code for any others who come after:

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;

//File[] SDcards ; 
//String primarySD, externalSD;

void setup() {
  fullScreen(P2D);
  //size(400,400,P2D);
  act = this.getActivity();
  context = act.getApplicationContext();
  //SDcards = context.getExternalFilesDirs(null);
  //primarySD = SDcards[0].getPath().split("/Android")[0];
  //externalSD = SDcards[1].getPath().split("/Android")[0];
  //println("primarySD = " + primarySD) ;
  Looper.prepare();
  mMediaPlayer = new MediaPlayer();
  try {
    afd = context.getAssets().openFd("video.mp4"); /// video is in the sketch Data folder
    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);
  mySurface.setZOrderOnTop(true) ;
  mSurfaceHolder = mySurface.getHolder();
  mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
  mSurfaceHolder.addCallback(new SurfaceHolder.Callback() {
    //<a href="/two/profile/Override">@Override</a>
    public void surfaceCreated(SurfaceHolder surfaceHolder) {
      mMediaPlayer.setDisplay(surfaceHolder);
    }

    // <a href="/two/profile/Override">@Override</a>
    public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i2, int i3) {
      mMediaPlayer.setDisplay(surfaceHolder);
    }

    // <a href="/two/profile/Override">@Override</a>
    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));
        act.addContentView(mySurface, new ViewGroup.LayoutParams(width, height));
        if (mMediaPlayer.isPlaying() == false) {
          mMediaPlayer.start();
        }
      }
      catch (IllegalArgumentException e) {
        e.printStackTrace();
      }
      catch (IllegalStateException e) {
        e.printStackTrace();
      } 
      catch (IOException e) {
        e.printStackTrace();
      }
    }
  }
  );
};

void draw() {
// video plays on top of all graphics...
}

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

Great to hear you have it working😀

ok slight adjustment: to make the video loop:

after

        mMediaPlayer.prepare();

add this line

        mMediaPlayer.setLooping(true);