Android Video Player

Introduction

In the world of mobile applications, video playback is a common requirement. Whether it’s for streaming content, displaying tutorials, or showcasing a product, integrating video functionality enhances user experience. In Android, the VideoView class simplifies the process of implementing a video player, while the MediaController class allows you to easily manage playback controls like play, pause, and seek.

This tutorial will guide you through creating a simple video player using Kotlin. By the end, you'll understand how to utilize these classes effectively and build a functional video player for your Android app.

Concept Explanation

What is VideoView?

The VideoView class is part of the Android framework that allows you to play video files in your application. Imagine it as a window through which your app can show moving images. When you want to include a video in your app, the VideoView is the go-to component.

Why Use MediaController?

The MediaController class provides a user interface for controlling video playback. Think of it as a remote control for your video player. Without it, users would have to interact with the video in a very limited manner, which could lead to frustration. With a MediaController, you can easily provide play, pause, rewind, and fast-forward options.

When to Use These Classes

You would typically use VideoView and MediaController in scenarios like:

  • Streaming video content from the internet.
  • Playing local video files stored on the device.
  • Displaying video tutorials or promotional content in your app.
  • Syntax Section

Here’s a brief overview of the basic syntax for using VideoView and MediaController:

Example

class MyActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val videoView = findViewById<VideoView>(R.id.videoView)
        val mediaController = MediaController(this)
        
        // Set up the MediaController
        mediaController.setAnchorView(videoView)

        // Specify the video file's URI
        val uri: Uri = Uri.parse("android.resource://" + packageName + "/" + R.raw.video)

        // Set the URI and MediaController
        videoView.setMediaController(mediaController)
        videoView.setVideoURI(uri)

        // Start playback
        videoView.requestFocus()
        videoView.start()
    }
}

Explanation of the Syntax Parts

  • VideoView: This is where the video is displayed.
  • MediaController: This provides playback controls.
  • setAnchorView: This method attaches the MediaController to the VideoView, allowing it to control playback.
  • setVideoURI: This method sets the source of the video.
  • start: This method begins video playback.
  • Examples

    Example 1: Playing a Local Video File

Let’s create a simple video player that plays a local video file stored in the "res/raw" directory.

activity_main.xml

Example

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <VideoView
        android:id="@+id/videoView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

MainActivity.kt

Example

package com.example.videoplayer

import android.net.Uri
import android.os.Bundle
import android.widget.MediaController
import android.widget.VideoView
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val videoView = findViewById<VideoView>(R.id.videoView)
        val mediaController = MediaController(this)
        mediaController.setAnchorView(videoView)

        // Specify the location of the video file
        val uri: Uri = Uri.parse("android.resource://${packageName}/${R.raw.sample_video}")

        // Set the MediaController and video URI
        videoView.setMediaController(mediaController)
        videoView.setVideoURI(uri)
        videoView.requestFocus()
        videoView.start()
    }
}

Expected Output:

When you run the app, the video located in res/raw/sample_video.mp4 will start playing with controls for play, pause, and seek.

---

Example 2: Playing Video from External Storage

In this example, let's play a video file stored on the device’s external storage.

MainActivity.kt

Example

package com.example.videoplayer

import android.net.Uri
import android.os.Bundle
import android.os.Environment
import android.widget.MediaController
import android.widget.VideoView
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val videoView = findViewById<VideoView>(R.id.videoView)
        val mediaController = MediaController(this)
        mediaController.setAnchorView(videoView)

        // Specify the location of the video file
        val uri: Uri = Uri.parse(Environment.getExternalStorageDirectory().absolutePath + "/Movies/sample_video.mp4")

        // Set the MediaController and video URI
        videoView.setMediaController(mediaController)
        videoView.setVideoURI(uri)
        videoView.requestFocus()
        videoView.start()
    }
}

Expected Output:

Running this code will play the video file located at /sdcard/Movies/sample_video.mp4.

---

Example 3: Handling Video Playback States

This example will demonstrate how to handle different video playback states such as pause, resume, and stop.

MainActivity.kt

Example

package com.example.videoplayer

import android.net.Uri
import android.os.Bundle
import android.os.Environment
import android.widget.Button
import android.widget.MediaController
import android.widget.VideoView
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {
    private lateinit var videoView: VideoView
    private lateinit var mediaController: MediaController

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        videoView = findViewById(R.id.videoView)
        mediaController = MediaController(this)
        mediaController.setAnchorView(videoView)

        val uri: Uri = Uri.parse(Environment.getExternalStorageDirectory().absolutePath + "/Movies/sample_video.mp4")
        videoView.setMediaController(mediaController)
        videoView.setVideoURI(uri)
        
        videoView.requestFocus()
        videoView.start()

        findViewById<Button>(R.id.btnPause).setOnClickListener {
            videoView.pause()
        }

        findViewById<Button>(R.id.btnResume).setOnClickListener {
            videoView.start()
        }

        findViewById<Button>(R.id.btnStop).setOnClickListener {
            videoView.stopPlayback()
        }
    }
}

activity_main.xml

Example

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <VideoView
        android:id="@+id/videoView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_marginBottom="16dp"
        app:layout_constraintBottom_toTopOf="@+id/buttonLayout"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <LinearLayout
        android:id="@+id/buttonLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent">

        <Button
            android:id="@+id/btnPause"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Pause" />

        <Button
            android:id="@+id/btnResume"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Resume" />

        <Button
            android:id="@+id/btnStop"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Stop" />
    </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

Expected Output:

This example provides buttons to pause, resume, and stop playback of the video, enhancing the user control over video playback.

Common Mistakes

Using Incorrect URI

One common mistake is providing an incorrect URI for the video file. For instance, if you specify a non-existent file path, the video won’t play, and you might encounter a FileNotFoundException.

Incorrect Example:

Example

val uri: Uri = Uri.parse("android.resource://${packageName}/non_existent_video.mp4")

Not Requesting Permissions

When accessing videos from external storage, you must ensure that your app has the appropriate permissions. If you forget to add the READEXTERNALSTORAGE permission in the AndroidManifest.xml, the app will crash when trying to access the file.

Correct Permissions:

Example

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

Best Practices

  • Handle Permissions: Always check and request runtime permissions for accessing external storage in Android 6.0 (API level 23) and above.
  • Check Video Format: Ensure the video format is supported. Android supports common formats like MP4, 3GP, and MKV.
  • Optimize Playback: Use lower resolution videos for better performance on lower-end devices.
  • Error Handling: Implement error handling to manage playback failures gracefully without crashing the app.
  • Practice Exercises

  1. Custom Video Player UI: Create a video player that includes a custom UI with buttons for play, pause, and stop.
  • Hint: Use ImageButton for custom buttons instead of the default MediaController.
  1. Video Selection: Build an activity that allows users to select a video from their device storage and play it.
  • Hint: Use an Intent to access the device's file picker.
  1. Playback State Management: Extend the previous examples to save and restore the video playback state when the app is paused or resumed.
  • Hint: Use onPause and onResume lifecycle methods to save and restore the current playback position.

By completing these exercises, you'll solidify your understanding of video playback in Android using Kotlin. Happy coding!

Input Required

This code uses input(). Please provide values below:

🤖 Coding Mentor
🤖

Hi! I'm your coding mentor

Ask me anything about programming:

• Python, Java, C++, JavaScript

• Algorithms & Data Structures

• Debugging & Code Help