Android Native - Play videos using VideoView

dimitrilc 3 Tallied Votes 152 Views Share

Introduction

If your App only need a simple way to play videos on Android, then VideoView (android.widget.VideoView) might just fit the bill. In this tutorial, we will learn how to use VideoView for video playback in our App.

Goals

At the end of the tutorial, you would have learned:

  1. How to use VideoView to play videos.

Tools Required

  1. Android Studio. The version used in this tutorial is Arctic Fox 2020.3.1 Patch 4.

Prerequisite Knowledge

  1. Intermediate Android.
  2. Storage Access Framework (SAF).
  3. ActivityResult APIs.

Project Setup

To follow along with the tutorial, perform the steps below:

  1. Create a new Android project with the default Empty Activity.

  2. Remove the default “Hello World!” TextView.

  3. Add a new Button to ConstraintLayout.

  4. Constraint it to the top, left and right of the screen.

  5. Give the Button 64dp margin from the top of the screen.

  6. Extract the Button’s android:text value to strings.xml with the value as Play Video.

  7. Your activity_main.xml should now look similar to this.

     <?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"
         tools:context=".MainActivity">
    
         <Button
             android:id="@+id/button"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_marginTop="64dp"
             android:text="@string/button"
             app:layout_constraintEnd_toEndOf="parent"
             app:layout_constraintStart_toStartOf="parent"
             app:layout_constraintTop_toTopOf="parent" />
    
     </androidx.constraintlayout.widget.ConstraintLayout>
  8. From the test device’s web browser, download the sample video from this project’s Github repository here. The sample video used here is the trailer of the short movie Sintel (© copyright Blender Foundation | durian.blender.org). Optionally, you can also drag and drop the video from your computer directly into the AVD.

Supported Media Formats

For Android to be able to playback a video file, the file format must either be supported by the Android system or the device vendor. The list of supported media formats by Android can be found here. To find out the supported Media MIME types on a device, we can use the various functions in the MediaCodecList class and the MediaCodecInfo class. For example, to list all supported(either encoding or decoding) MIME types on our AVD,

  1. Add the function below to MainActivity.

     private fun logCodecs(){
        val codecList = MediaCodecList(ALL_CODECS)
    
        for (codecInfo in codecList.codecInfos){
            for (mimeType in codecInfo.supportedTypes){
                Log.d(TAG, mimeType)
            }
        }
     }
  2. Add the top-level TAG constant.

     private const val TAG = "MAIN_ACTIVITY"
  3. Call the function in onCreate().

     logCodecs()

If you run your App now, it will log something similar to the content below (output has been formatted for readability).

audio/mp4a-latm
audio/3gpp
audio/amr-wb
audio/flac
audio/g711-alaw
audio/g711-mlaw
audio/mpeg
audio/opus
audio/raw
audio/vorbis
video/avc
video/x-vnd.on2.vp8
video/x-vnd.on2.vp9
video/av01
video/3gpp
video/hevc
video/mp4v-es

Preparing the VideoView

  1. To play a video with a VideoView, first we will add a VideoView in activity_main.xml.

     <VideoView
        android:id="@+id/videoView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/button" />
  2. It looks a little bit better with some margin, so we will add 8dp of margins to videoView.

     android:layout_marginStart="8dp"
     android:layout_marginTop="8dp"
     android:layout_marginEnd="8dp"
     android:layout_marginBottom="8dp"
  3. We do not need to need to show the videoView until the video starts playing, so we will mark it as invisible at startup.

     android:visibility="invisible"

Open the Media file

Normally, only videos located under DCIM/, Movies/, and Pictures/ will be available in the MediaStore.Video table. Because our video file is located under /Downloads, we will interact with it via the SAF.

  1. Create the ActivityResultLauncher and an empty callback with the code below inside onCreate().

     val openVideoLauncher = registerForActivityResult(OpenDocument()) { uri ->
    
     }
  2. Retrieve the Button object.

     //Gets the button reference
     val button = findViewById<Button>(R.id.button)
  3. Bind the Button onClickListener to the file Picker, passing in an array of the video MIME types.

     button.setOnClickListener {
        val mimeTypes = arrayOf("video/mp4") //filters for mp4 videos
        openVideoLauncher.launch(mimeTypes)
     }

The VideoView object

The VideoView object provides convenient functions to make it super easy to play videos. To interact with it, follow the steps below.

  1. Just above openVideoLauncher, retrieves the VideoView object.

     //Gets the videoView reference
     val videoView = findViewById<VideoView>(R.id.videoView)
  2. Bind the code below to the openVideoLauncher callback. This code will set the URI object returned from ActivityResultLauncher as the source for the video, makes the VideoView visible, and then start the video.

     //Start the video now that we have the uri
     videoView.apply {
        setVideoURI(uri) //sets the video uri
        visibility = VISIBLE //makes videoView visible
     }.start()

Run the App

We are now ready to run our app. The workflow should be similar to the animation below.

SintelApp.gif

Solution Code

MainActivity.kt

package com.example.daniwebandroidplayvideo

import android.media.MediaCodecList
import android.media.MediaCodecList.ALL_CODECS
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.View.VISIBLE
import android.widget.Button
import android.widget.VideoView
import androidx.activity.result.contract.ActivityResultContracts.OpenDocument

private const val TAG = "MAIN_ACTIVITY"

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

       logCodecs()

       //Gets the videoView reference
       val videoView = findViewById<VideoView>(R.id.videoView)

       val openVideoLauncher = registerForActivityResult(OpenDocument()) { uri ->
           //Start the video now that we have the uri
           videoView.apply {
               setVideoURI(uri) //sets the video uri
               visibility = VISIBLE //makes videoView visible
           }.start()
       }

       //Gets the button reference
       val button = findViewById<Button>(R.id.button)

       button.setOnClickListener {
           val mimeTypes = arrayOf("video/mp4") //filters for mp4 videos
           openVideoLauncher.launch(mimeTypes)
       }

   }

   private fun logCodecs(){
       val codecList = MediaCodecList(ALL_CODECS)

       for (codecInfo in codecList.codecInfos){
           for (mimeType in codecInfo.supportedTypes){
               Log.d(TAG, mimeType)
           }
       }
   }
}

activity_main.xml

<?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"
   tools:context=".MainActivity">

   <Button
       android:id="@+id/button"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_marginTop="64dp"
       android:text="@string/button"
       app:layout_constraintEnd_toEndOf="parent"
       app:layout_constraintStart_toStartOf="parent"
       app:layout_constraintTop_toTopOf="parent" />

   <VideoView
       android:id="@+id/videoView"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:layout_marginStart="8dp"
       android:layout_marginTop="8dp"
       android:layout_marginEnd="8dp"
       android:layout_marginBottom="8dp"
       android:visibility="invisible"
       app:layout_constraintBottom_toBottomOf="parent"
       app:layout_constraintEnd_toEndOf="parent"
       app:layout_constraintStart_toStartOf="parent"
       app:layout_constraintTop_toBottomOf="@id/button" />

</androidx.constraintlayout.widget.ConstraintLayout>

strings.xml

<resources>
   <string name="app_name">Daniweb Android Play Video</string>
   <string name="button">Play Video</string>
</resources>

Summary

We have learned how to play a video using the VideoView. The full project code can be found at https://github.com/dmitrilc/DaniwebAndroidPlayVideoVideoView

Iqra_18 -8 Newbie Poster

Its impressive development. most informative.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.