Play Quad Videos in 4V
Learn to play a Quad (2x2) video on a QuadView using ExoPlayer
The Android Media SDK offers easy integration with the ExoPlayer to play 2x2 videos in 4V. By leveraging the power of ExoPlayer, you can play 2x2 or 2x1 videos using different media sources.
In this guide, you will learn how to load a 2x2 video from the project's asset folder and play it using ExoPlayer on the QuadView.
We won't go over the implementation of ExoPlayer in this tutorial. You can learn more about ExoPlayer here.

Setup Resources

Add the video we will be working with to the assets directory of your project.
You can download the video for this tutorial below.
cat_2x2.mp4
1MB
Binary
cat_2x2.mp4
Add this video file to your project's assets directory as shown below

Setup Environment.

Setup the Android SDK in your Android project by following the steps outlined in the Getting Started Section.
We will also need to add the ExoPlayer dependency to our project. Add the following dependency to your app's build.gradle file.
1
implementation 'com.google.android.exoplayer:exoplayer:2.11.7'
Copied!

Add the QuadView to your XML Layout file

1
<com.leiainc.androidsdk.core.QuadView
2
android:id="@+id/quad_view"
3
android:layout_width="match_parent"
4
android:layout_height="match_parent"/>
Copied!
The QuadView is a reusable Android view which allows you to easily render a quad with just one line of code.
Obtain the reference to the QuadView in your Activity or Fragment using findViewById()
Kotlin
Java
1
val quadView: QuadView = findViewById(R.id.quad_view)
Copied!
1
QuadView quadView = findViewById(R.id.quad_view);
Copied!

Implement SurfaceTextureReady Callbacks

In order to play videos on the QuadView, you need to obtain the SurfaceTexture when it becomes available. You can do so by implementing the SurfaceTextureReadyCallback which will notify you when the Surface Texture becomes available via callbacks
Kotlin
Java
1
class VideoActivity : AppCompatActivity(), SurfaceTextureReadyCallback {
2
// rest of activity code
3
4
override fun onSurfaceTextureReady(surfaceTexture: SurfaceTexture?) {
5
TODO("Not yet implemented")
6
}
7
}
Copied!
1
public class VideoActivity extends AppCompatActivity implements SurfaceTextureReadyCallback {
2
// rest of activity code
3
4
@Override
5
public void onSurfaceTextureReady(SurfaceTexture surfaceTexture) {
6
// TODO
7
}
8
}
Copied!

Attach Callbacks to QuadView

We now have to attach the callback to the QuadView. We can do this by calling getInputSurfaceTexture() as shown below.
Kotlin
Java
1
val quadView: QuadView = findViewById(R.id.quad_view)
2
quadView.getInputSurfaceTexture(this)
Copied!
1
QuadView quadView = findViewById(R.id.quad_view);
2
quadView.getInputSurfaceTexture(this);
Copied!

Initialize ExoPlayer

Initialize ExoPlayer in your Activity's onCreate() function. Add exoPlayer as a global variable so it can be accessed in other functions as well.
Kotlin
Java
1
private lateinit var exoPlayer: SimpleExoPlayer
2
3
override fun onCreate(savedInstanceState: Bundle?) {
4
super.onCreate(savedInstanceState)
5
setContentView(R.layout.activity_video)
6
7
val quadView: QuadView = findViewById(R.id.quad_view)
8
quadView.getInputSurfaceTexture(this)
9
10
// Initialize ExoPlayer
11
exoPlayer = SimpleExoPlayer.Builder(this).build()
12
}
Copied!
1
private SimpleExoPlayer exoPlayer;
2
3
@Override
4
public void onCreate(Bundle savedInstanceState) {
5
super.onCreate(savedInstanceState);
6
setContentView(R.layout.activity_video);
7
8
QuadView quadView = findViewById(R.id.quad_view);
9
quadView.getInputSurfaceTexture(this);
10
11
// Initialize ExoPlayer
12
exoPlayer = SimpleExoPlayer.Builder(this).build();
13
}
Copied!

Implement Surface Texture Ready

We can now use the surface texture to play the video using ExoPlayer. We can do this by passing the surface texture to the ExoPlayer.
Kotlin
Java
1
exoPlayer.setVideoSurface(Surface(surfaceTexture))
Copied!
1
exoPlayer.setVideoSurface(new Surface(surfaceTexture));
Copied!
You can now load the asset and play it using ExoPlayer. We are using a Looping Media Source to loop the video in this example.
Kotlin
Java
1
class VideoActivity : AppCompatActivity(), SurfaceTextureReadyCallback {
2
// rest of activity code
3
4
override fun onSurfaceTextureReady(surfaceTexture: SurfaceTexture?) {
5
// Set surface Texture in ExoPlayer
6
exoPlayer.setVideoSurface(Surface(surfaceTexture))
7
8
// Load Asset
9
val mp4VideoUri =
10
Uri.parse("asset:///cat_2x2.mp4")
11
12
val userAgent = Util.getUserAgent(this, "exoplayerQuadExample")
13
val dataSourceFactory = DefaultDataSourceFactory(this, userAgent)
14
15
// Create a looping Media Source
16
val videoSource: MediaSource = ProgressiveMediaSource.Factory(dataSourceFactory)
17
.createMediaSource(mp4VideoUri)
18
val loopingSource = LoopingMediaSource(videoSource)
19
20
exoPlayer.prepare(loopingSource)
21
}
22
}
Copied!
1
public class VideoActivity extends AppCompatActivity implements SurfaceTextureReadyCallback {
2
// rest of activity code
3
4
@Override
5
public void onSurfaceTextureReady(SurfaceTexture surfaceTexture) {
6
exoPlayer.setVideoSurface(new Surface(surfaceTexture));
7
8
// Load Asset
9
Uri mp4VideoUri =
10
Uri.parse("asset:///cat_2x2.mp4");
11
12
String userAgent = Util.getUserAgent(this, "exoplayerQuadExample");
13
DefaultDataSourceFactory dataSourceFactory = new DefaultDataSourceFactory(this, userAgent);
14
15
// Create a looping Media Source
16
MediaSource videoSource = ProgressiveMediaSource.Factory(dataSourceFactory)
17
.createMediaSource(mp4VideoUri);
18
LoopingMediaSource loopingSource = new LoopingMediaSource(videoSource);
19
20
exoPlayer.prepare(loopingSource);
21
}
22
}
Copied!

Playing the Video

With the ExoPlayer now setup, we can play the video by calling playWhenReady() in your Activity's onResume() function.
Kotlin
Java
1
override fun onResume() {
2
super.onResume()
3
exoPlayer.playWhenReady = true
4
}
Copied!
1
@Override
2
protected void onResume() {
3
super.onResume();
4
exoPlayer.setPlayWhenReady(true);
5
}
Copied!
Pause playing the video when the activity's onPause() is called.
Kotlin
Java
1
override fun onPause() {
2
super.onPause()
3
exoPlayer.playWhenReady = false
4
}
Copied!
1
@Override
2
protected void onPause() {
3
super.onPause();
4
exoPlayer.setPlayWhenReady(false);
5
}
Copied!
You can learn more about using the ExoPlayer here.

Toggle the Backlight

The last step is to switch on the backlight to view the image in 4V. We can request toggling backlight using the LeiaDisplayManager .
Place the following line of code in your Activity/Fragment's onResume() function.
Kotlin
Java
1
override fun onResume() {
2
super.onResume()
3
exoPlayer.playWhenReady = true
4
5
val displayManager: LeiaDisplayManager? = LeiaSDK.getDisplayManager(applicationContext)
6
displayManager?.requestBacklightMode(LeiaDisplayManager.BacklightMode.MODE_3D)
7
}
Copied!
1
@Override
2
protected void onResume() {
3
super.onResume();
4
exoPlayer.setPlayWhenReady(true);
5
6
LeiaDisplayManager displayManager = LeiaSDK.getDisplayManager(applicationContext);
7
displayManager.requestBacklightMode(LeiaDisplayManager.BacklightMode.MODE_3D);
8
}
Copied!
This will turn on the backlight on a Leia Light-field device.
To turn off the backlight, you can call the same line of code with BacklightMode.MODE_2D. Its a good practice to turn off the backlight in your activity's onPause() function. This ensures the backlight is turned off when the user exits the app.
Kotlin
Java
1
override fun onPause() {
2
super.onPause()
3
exoPlayer.playWhenReady = false
4
5
val displayManager: LeiaDisplayManager? = LeiaSDK.getDisplayManager(applicationContext)
6
displayManager?.requestBacklightMode(LeiaDisplayManager.BacklightMode.MODE_2D)
7
}
Copied!
1
@Override
2
protected void onPause() {
3
super.onPause();
4
exoPlayer.setPlayWhenReady(false);
5
6
LeiaDisplayManager displayManager = LeiaSDK.getDisplayManager(applicationContext);
7
displayManager.requestBacklightMode(LeiaDisplayManager.BacklightMode.MODE_2D);
8
}
Copied!
You can learn more about the LeiaDisplayManager here.

Build your app

If you followed the steps above correctly, you should be able to play the video in 4V. If you had trouble following the steps, you can checkout the sample app on Github
Last modified 11mo ago