This is a Part 2 of Android SurfaceView story.
Playing video
Playing video from assets folder
This tutorial describes how to use TextureView to load and play video from assets folder. For this task, you'll need a video sample file which you can get from here.
Step 1 - Preparing
Create Android project and target Android version 4.0. Remember that TextureView is available since API level 14
Make sure you have the following lines in your AndroidManifest.xml file.
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="14"/>
Step 2 - XML
Copy video file big_buck_bunny.mp4 to your assets folder.
In your values folder, create dimen.xml file and add following lines.
<dimen name="texture_view_width">320dp</dimen> <dimen name="texture_view_height">176dp</dimen>
Why 320dp and 176dp ?
Video file big_buck_bunny.mp4 has 320px width and 176px height. We are using the same values but in dp to stretch view and keep proportions. In other words, video will look bigger.
In your layout folder create texture_video_simple.xml file and add following lines.
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <TextureView android:id="@+id/textureView" android:layout_width="@dimen/texture_view_width" android:layout_height="@dimen/texture_view_height" android:layout_centerInParent="true"/> </RelativeLayout>
Step 3 - Code
Create a new activity class and name it VideoAssetActivity. Don’t forget to declare it inside AndroidManifest.xml file. And here comes the main part.
Imports
import android.app.Activity; import android.content.res.AssetFileDescriptor; import android.graphics.SurfaceTexture; import android.media.MediaPlayer; import android.os.Bundle; import android.util.Log; import android.view.Surface; import android.view.TextureView; import java.io.IOException;
Picture below shows how our activity structure will look like:
Code
public class VideoAssetActivity extends Activity implements TextureView.SurfaceTextureListener { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.texture_video_simple); initView(); } private void initView() { } @Override protected void onDestroy() { super.onDestroy(); } @Override public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i2) { } @Override public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i2) { } @Override public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) { return true; } @Override public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) { } }
Now we need to fill it in with logic. Declare three class member variables.
// Log tag. private static final String TAG = VideoAssetActivity.class.getName(); // Asset video file name. private static final String FILE_NAME = "big_buck_bunny.mp4"; // MediaPlayer instance to control playback of video file. private MediaPlayer mMediaPlayer;
Start point is initView() method. To display video we need to get - SurfaceTexture - which is available only after the TextureView is attached to a window and onAttachedToWindow() has been invoked. So we are using SurfaceTextureListener to be notified when the SurfaceTexture becomes available.
private void initView() { TextureView textureView = (TextureView) findViewById(R.id.textureView); textureView.setSurfaceTextureListener(this); }
When SurfaceTexture is available onSurfaceTextureAvailable method is automatically called.
@Override public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i2) { Surface surface = new Surface(surfaceTexture); try { AssetFileDescriptor afd = getAssets().openFd(FILE_NAME); 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 mediaPlayer) { mediaPlayer.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()); } }
So, what is happening here? We are using AssetFileDescriptor to open video file from assets folder.MediaPlayer object is used to control video file, so we are packaging things like surface and data source inside. We also set looping flag to true, to make video automatically restarts when it is over. The last part is to set onPreparedListener and callMediaPlayer.prepareAsync() method which fire onPrepared event when we can start video playback.
Tip
Don't forget to call MediaPlayer.prepareAsync() method when you use constructor for creating MediaPlayer object and if you use MediaPlayer.create(...) factory method MediaPlayer.prepareAsync() is called automatically.
Step 4 - Memory cleanup
Keep in mind that we are working with resources that require a lot of memory. To avoid memory leaks make sure you stop video and release resources when activity is destroyed.
@Override protected void onDestroy() { super.onDestroy(); if (mMediaPlayer != null) { mMediaPlayer.stop(); mMediaPlayer.release(); mMediaPlayer = null; } }
Step 5 - Launch
Now you can launch application. Remember you need Emulator or device with Android version 4.0 or higher. Here is a screenshot of how it should look like. Video is centered, it starts playing automatically and loops. When activity is destroyed, video is stopped and resources are released.
Playing video from url
This tutorial shows how to use TextureView to load and play video from url.
Important: almost all code is the same as in Playing video from assets tutorial, so you need to complete it first and here I will describe which lines of code you need to modify.
Step 1 - Preparing
As we are going to play video from the Internet, we need to add Internet permission to AndroidManifest.xml file.
<uses-permission android:name="android.permission.INTERNET"/>
Step 2 - XML
The same as in Playing video from assets tutorial, except video coping part.
Step 3 - Code
The same as in Playing video from assets tutorial, plus additional changes.
Our file url variable now should point to video url file:
private static final String FILE_URL = "http://www.w3schools.com/html/mov_bbb.mp4";
Next change is inside onSurfaceTextureAvailable listener. Delete here two lines which are responsible for playing asset video, and add one line which sets data source to video url.
@Override public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i2) { Surface surface = new Surface(surfaceTexture); try { AssetFileDescriptor afd = getAssets().openFd(FILE_NAME); mMediaPlayer = new MediaPlayer(); mMediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength()); mMediaPlayer.setDataSource(getApplicationContext(), Uri.parse(FILE_URL)); 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 mediaPlayer) { mediaPlayer.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()); } }
Step 4 - Memory cleanup
The same as in Playing video from assets tutorial.
Step 5 - Launch
The same as in Playing video from assets tutorial, but keep in mind that you need Internet connection. Also, note we didn’t put any code to check the network state. In real application, you should first check if Internet connection is available.
Original article here.
SEE ALSO: