Video challenge


#1

Setup : Android Studio 0.9.1, Windows 7 (x64), testing on Galaxy Nexus (4.2.2) and Samsung Galaxy S3 (4.4.2).

Trying the VideoView option completely failed. I could not get the darn thing to play the video for the life of me, even after converting the file to mp4, and sacrificing small rodents. The consistent response was that it could not open the file.

I finally started searching for information on using the SurfaceView, and ran across this tutorial: github.com/dmytrodanylyk/dmytro … w-intro.md

This, I was able to get to work, as long as I ran the VideoAssetActivity as the main Activity. I was wondering how one might convert this to using the Fragment, however, as this seems to rely on implementing an interface (TextureView.SurfaceTextureListener)?

One thing of note: I had to move the movie to a folder named assets under src/main. Could it be that using the “raw” folder runs into some permissions error, and that’s why the original attempts “could not find” the video?


#2

After more research…

One: it seems to work just fine if you change the Activity to a FragmentActivity, and still implement the TextureView.SurfaceTextureListener. So, cool.
Two: it appears that if I want to reference the file /inside/ the /res/raw dir, I should reference it like so:

That was a lot easier than I expected… I was going through some really nasty roundabouts trying to get it to read from the raw dir!

So, taking the code from that link, I modify it to look like this:

import android.content.res.AssetFileDescriptor;
import android.graphics.SurfaceTexture;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.Surface;
import android.view.TextureView;

import java.io.IOException;

public class VideoAssetActivity extends FragmentActivity implements TextureView.SurfaceTextureListener {
    // Log tag
    private static final String TAG = VideoAssetActivity.class.getName();

    // MediaPlayer instance to control playback of video file.
    private MediaPlayer mMediaPlayer;

    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.fragment_hello_moon);

        initView();
    }

    private void initView(){
        TextureView textureView = (TextureView) findViewById(R.id.textureView);
        textureView.setSurfaceTextureListener(this);
    }

    @Override
    protected void onDestroy(){
        super.onDestroy();
        if(mMediaPlayer != null){
            mMediaPlayer.stop();
            mMediaPlayer.release();
            mMediaPlayer = null;
        }
    }

    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i2){
        Surface surface = new Surface(surfaceTexture);

        try{
            AssetFileDescriptor afd = getResources().openRawResourceFd(R.raw.apollo_17_stroll);
            mMediaPlayer = new MediaPlayer();
            mMediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
            mMediaPlayer.setSurface(surface);
            mMediaPlayer.setLooping(true);
            mMediaPlayer.prepareAsync();

            // Play video when the media source is ready for playback.
            mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                @Override
                public void onPrepared(MediaPlayer mp) {
                    mp.start();
                }
            });
        } catch (IllegalArgumentException e){
            Log.d(TAG, e.getMessage());
        } catch (SecurityException e){
            Log.d(TAG, e.getMessage());
        } catch (IllegalStateException e){
            Log.d(TAG, e.getMessage());
        } catch (IOException e){
            Log.d(TAG, e.getMessage());
        }
    }

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i2){}

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture){return true;}

    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture){}
}

and in my fragment_hello_moon.xml, I need this:

<TextureView
        android:id="@+id/textureView"
        android:layout_width="@dimen/texture_view_width"
        android:layout_height="@dimen/texture_view_height"
        />

Everything else from that tutorial stands as-is.