Best Android YouTube Player Libraries and Examples
In this lesson we will look at some of the best youtube player libraries. These are libraries that allow us play or load YouTube videos.
Why Libraries?
Well you certainly have several options when intending to play youtube videos in your app:
- Using YouTube API.
- Using WebView with iFrame.
- Using Third Party library.
Because YouTube API is quite buggy and doesn't work in devices where the user hasn't installed the official YouTube App, the best option for you is to use a solution that provides a fallback in case the API doesn't work. That's where libraries come in.
Libaries can attempt to load videos via the API, if this fails then they can revert to webview.
Let's look at some libraries.
1. Android YouTube PLayer
This library is written by PierfrancescoSoffritti and it is probably the best youtube library out there. It incorporates native UI as well as web UI and plays videos reliably.
A stable and customizable open source YouTube player for Android. It provides a simple View that can be easily integrated in every Activity/Fragment.
To interact with YouTube the library uses the IFrame Player API, inside of a WebView, therefore the YouTube app is not required on the user's device and there are no issues with YouTube Terms of Service.
Let's now see how to use this library.
Step 1: Install it
Install it by adding the following in your app level build.gradle file:
Then sync to download the library.
Step 2: Add YouTubePlayerView Layout
Next you need to add the YouTubePlayerView in your XML layout:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<com.pierfrancescosoffritti.androidyoutubeplayer.core.player.views.YouTubePlayerView
android:id="@+id/youtube_player_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:videoId="S0Q4gqBUs7c"
app:autoPlay="true"
app:showFullScreenButton="false" />
</LinearLayout>
You can see you can provide details like whether the youtube video will autoplay, you can provide the video ID declaratively. All these can also be done imperatively in kotlin or java.
Step 3: Kotlin/Java Code
It is recommended that you add
YouTubePlayerView
as a lifecycle observer of its parent Activity/Fragment.
YouTubePlayerView youTubePlayerView = findViewById(R.id.youtube_player_view);
getLifecycle().addObserver(youTubePlayerView);
Be sure you are using androidx before adding YouTubePlayerView as a LifecycleObserver.
In fact that's all you need toplay a youtube video in android.
However obviously you can add more control programmatically:
YouTubePlayerView youTubePlayerView = findViewById(R.id.youtube_player_view);
getLifecycle().addObserver(youTubePlayerView);
youTubePlayerView.addYouTubePlayerListener(new AbstractYouTubePlayerListener() {
@Override
public void onReady(@NonNull YouTubePlayer youTubePlayer) {
String videoId = "S0Q4gqBUs7c";
youTubePlayer.loadVideo(videoId, 0);
}
});
Example
Let's look a complete example:
First install the library as we'd dicussed above.
Then create a layout:
activity_basic_example.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.pierfrancescosoffritti.androidyoutubeplayer.core.player.views.YouTubePlayerView
android:id="@+id/youtube_player_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/next_video_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="26dp"
android:backgroundTint="@android:color/white"
android:text="Play Next Video" />
</LinearLayout>
MainActivity.java
Here's the main activity in java:
package com.pierfrancescosoffritti.androidyoutubeplayer.core.sampleapp.examples.completeExample;
import android.annotation.SuppressLint;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.Log;
import android.widget.Button;
import android.widget.Toast;
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.utils.YouTubePlayerUtils;
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.views.YouTubePlayerView;
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.YouTubePlayer;
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners.AbstractYouTubePlayerListener;
import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners.YouTubePlayerFullScreenListener;
import com.pierfrancescosoffritti.androidyoutubeplayer.core.ui.PlayerUiController;
import com.pierfrancescosoffritti.androidyoutubeplayer.core.ui.menu.MenuItem;
import com.pierfrancescosoffritti.androidyoutubeplayer.core.sampleapp.utils.VideoIdsProvider;
import com.pierfrancescosoffritti.androidyoutubeplayer.core.sampleapp.utils.VideoInfo;
import com.pierfrancescosoffritti.androidyoutubeplayer.core.sampleapp.utils.FullScreenHelper;
import com.pierfrancescosoffritti.androidyoutubeplayer.core.sampleapp.utils.YouTubeDataEndpoint;
import com.pierfrancescosoffritti.aytplayersample.R;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
public class CompleteExampleActivity extends AppCompatActivity {
private YouTubePlayerView youTubePlayerView;
private FullScreenHelper fullScreenHelper = new FullScreenHelper(this);
// a list of videos not available in some countries, to test if they're handled gracefully.
// private String[] nonPlayableVideoIds = { "sop2V_MREEI" };
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_basic_example);
youTubePlayerView = findViewById(R.id.youtube_player_view);
initYouTubePlayerView();
}
@Override
public void onConfigurationChanged(Configuration newConfiguration) {
super.onConfigurationChanged(newConfiguration);
youTubePlayerView.getPlayerUiController().getMenu().dismiss();
}
@Override
public void onBackPressed() {
if (youTubePlayerView.isFullScreen())
youTubePlayerView.exitFullScreen();
else
super.onBackPressed();
}
private void initYouTubePlayerView() {
initPlayerMenu();
// The player will automatically release itself when the activity is destroyed.
// The player will automatically pause when the activity is stopped
// If you don't add YouTubePlayerView as a lifecycle observer, you will have to release it manually.
getLifecycle().addObserver(youTubePlayerView);
youTubePlayerView.addYouTubePlayerListener(new AbstractYouTubePlayerListener() {
@Override
public void onReady(@NonNull YouTubePlayer youTubePlayer) {
YouTubePlayerUtils.loadOrCueVideo(
youTubePlayer,
getLifecycle(),
VideoIdsProvider.getNextVideoId(),
0f
);
addFullScreenListenerToPlayer();
setPlayNextVideoButtonClickListener(youTubePlayer);
}
});
}
/**
* Shows the menu button in the player and adds an item to it.
*/
private void initPlayerMenu() {
youTubePlayerView.getPlayerUiController()
.showMenuButton(true)
.getMenu()
.addItem(new MenuItem("menu item1", R.drawable.ic_android_black_24dp,
view -> Toast.makeText(this, "item1 clicked", Toast.LENGTH_SHORT).show())
).addItem(new MenuItem("menu item2", R.drawable.ic_mood_black_24dp,
view -> Toast.makeText(this, "item2 clicked", Toast.LENGTH_SHORT).show())
).addItem(new MenuItem("menu item no icon",
view -> Toast.makeText(this, "item no icon clicked", Toast.LENGTH_SHORT).show()));
}
private void addFullScreenListenerToPlayer() {
youTubePlayerView.addFullScreenListener(new YouTubePlayerFullScreenListener() {
@Override
public void onYouTubePlayerEnterFullScreen() {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
fullScreenHelper.enterFullScreen();
addCustomActionsToPlayer();
}
@Override
public void onYouTubePlayerExitFullScreen() {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
fullScreenHelper.exitFullScreen();
removeCustomActionsFromPlayer();
}
});
}
/**
* This method adds a new custom action to the player.
* Custom actions are shown next to the Play/Pause button in the middle of the player.
*/
private void addCustomActionsToPlayer() {
Drawable customAction1Icon = ContextCompat.getDrawable(this, R.drawable.ic_fast_rewind_white_24dp);
Drawable customAction2Icon = ContextCompat.getDrawable(this, R.drawable.ic_fast_forward_white_24dp);
assert customAction1Icon != null;
assert customAction2Icon != null;
youTubePlayerView.getPlayerUiController().setCustomAction1(customAction1Icon, view ->
Toast.makeText(this, "custom action1 clicked", Toast.LENGTH_SHORT).show());
youTubePlayerView.getPlayerUiController().setCustomAction2(customAction2Icon, view ->
Toast.makeText(this, "custom action1 clicked", Toast.LENGTH_SHORT).show());
}
private void removeCustomActionsFromPlayer() {
youTubePlayerView.getPlayerUiController().showCustomAction1(false);
youTubePlayerView.getPlayerUiController().showCustomAction2(false);
}
/**
* Set a click listener on the "Play next video" button
*/
private void setPlayNextVideoButtonClickListener(final YouTubePlayer youTubePlayer) {
Button playNextVideoButton = findViewById(R.id.next_video_button);
playNextVideoButton.setOnClickListener(view ->
YouTubePlayerUtils.loadOrCueVideo(
youTubePlayer, getLifecycle(),
VideoIdsProvider.getNextVideoId(),0f
));
}
/**
* This method is here just for reference, it is not being used because the IFrame player already shows the title of the video.
*
* This method is called every time a new video is being loaded/cued.
* It uses the YouTube Data APIs to fetch the video title from the video ID.
* The YouTube Data APIs are nothing more then a wrapper over the YouTube REST API.
* You can learn more at the following urls:
* https://developers.google.com/youtube/v3/docs/videos/list
* https://developers.google.com/apis-explorer/#p/youtube/v3/youtube.videos.list?part=snippet&id=6JYIGclVQdw&fields=items(snippet(title))&_h=9&
*
* This method does network operations, therefore it cannot be executed on the main thread.
* For simplicity I have used RxJava to implement the asynchronous logic. You can use whatever you want: Threads, AsyncTask ecc.
*/
@SuppressLint("CheckResult")
private void setVideoTitle(PlayerUiController playerUiController, String videoId) {
Single<VideoInfo> observable = YouTubeDataEndpoint.getVideoInfoFromYouTubeDataAPIs(videoId);
observable
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
videoInfo -> playerUiController.setVideoTitle(videoInfo.getVideoTitle()),
error -> { Log.e(getClass().getSimpleName(), "Can't retrieve video title, are you connected to the internet?"); }
);
}
}
Find source code here.
Reference
There is great and detailed documentation here.
Kotlin Android YouTubePlayerView Examples
Let us look at a Android YouTubePlayerView example.
What is YouTubePlayerView?
It is a library to play YouTube Videos.
- YouTube Player API is too old version
: Never updated from 2015/10/12 - There are 3 problems with YouTube Player API library.
Problem 1 - Jar File
- We should use Jar library file, not like
implementation xxxx
- That is old way and it makes difficult to manage the library
Problem 2 - Fragment style
-
If you want YouTube player with another view, you have to use
YouTubePlayerFragment
(Or you have to extendYouTubeBaseActivity
)
<FrameLayout
android:id="@+id/youtube_player_container"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
val youtubePlayerFragment = YouTubePlayerSupportFragment()
fragmentManager.beginTransaction()
.replace(binding.youtubePlayerContainer.id, youtubePlayerFragment)
.commitAllowingStateLoss()
youtubePlayerFragment.initialize(...)
Problem 3 - Conflict Fragment with androidx
- Furthermore if you use
androidx
package, you can not useYouTubePlayerFragment
. androidx.fragment.app.FragmentManager
needandroidx.fragment.app.Fragment
, butYouTubePlayerFragment
isandroid.app.Fragment
- You can find many question about this issue
: Youtube player support fragment no longer working on Android studio 3.2 (androidx)
: YoutubeAndroidPlayerAPI error after migrating to AndroidX in Android Studio
YouTubePlayerView
is super easy YouTube Player View.
Step 1: Install it
Install it from Maven central:
dependencies {
implementation 'kr.co.prnd:youtube-player-view:x.x.x'
//implementation 'kr.co.prnd:youtube-player-view:1.3.0'
}
Step 2: Add to Layout
- You can use 2 style
XML style
<kr.co.prnd.YouTubePlayerView
android:id="@+id/you_tube_player_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:videoId="VIDEO_ID" />
Dynamic code style
<kr.co.prnd.YouTubePlayerView
android:id="@+id/you_tube_player_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
Step 3: Write Code
Invoke the play()
function to play a YouTube video:
val youTubePlayerView:YouTubePlayerView = findViewById(R.id.you_tube_player_fragment_view)
youTubePlayerView.play(VIDEO_ID)
Fragment
- If you want use this
YouTubePlayerView
in fragment, you have to usefragment
attribute in xml
<kr.co.prnd.YouTubePlayerView
android:id="@+id/you_tube_player_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:fragment="com.example.youtubeplayerview.Sample2Fragment" />
- If you use Proguard, you have to add your fragment class name in your
proguard-rules.pro
file
FAQ
Why don't you need a developer key?
- This is a very strange thing.
- When we use youtube player api, you can use any developer key without empty string
- So
YouTubePlayerView
set developer key itself - Check this code
Here is a full example:
Example 1: YouTubePlayerView-master
This example will comprise the following files:
MainActivity.kt
Sample1Activity.kt
Sample2Activity.kt
Sample2Fragment.kt
Step 1: Create Project
- Open your
AndroidStudio
IDE. - Go to
File-->New-->Project
to create a new project.
Step 2: Add Dependencies
In your app/build.gradle
add dependencies as shown below:
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 30
defaultConfig {
applicationId "com.example.youtubeplayerview"
minSdkVersion 16
targetSdkVersion 30
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation project(':youtube-player-view')
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation "com.google.android.material:material:1.2.0-alpha01"
}
Step 3: Design Layouts
*(a). activity_main.xml
Create a file named activity_main.xml
and design it as follows:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/btn_sample1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Activity Style" />
<Button
android:id="@+id/btn_sample2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Fragment Style" />
</LinearLayout>
activity_sample1.xml
Create a file named activity_sample1.xml
and design it as follows:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<kr.co.prnd.YouTubePlayerView
android:id="@+id/you_tube_player_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<!--
<kr.co.prnd.YouTubePlayerView
android:id="@+id/you_tube_player_fragment_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:videoId="m2SZ6RV_J7I" />
-->
</LinearLayout>
activity_sample2.xml
Create a file named activity_sample2.xml
and design it as follows:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
fragment_sample1.xml
Create a file named fragment_sample1.xml
and design it as follows:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<kr.co.prnd.YouTubePlayerView
android:id="@+id/you_tube_player_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:fragment="com.example.youtubeplayerview.Sample2Fragment" />
<!--
<kr.co.prnd.YouTubePlayerView
android:id="@+id/you_tube_player_fragment_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:fragment="com.example.youtubeplayerview.Sample2Fragment"
app:videoId="m2SZ6RV_J7I" />
-->
</LinearLayout>
Step 4: Write Code
Write Code as follows:
(a). MainActivity.kt
Create a file named MainActivity.kt
This will start the activity that will play the youtube video in an activity
findViewById<Button>(R.id.btn_sample1).setOnClickListener {
startActivity(Intent(this, Sample1Activity::class.java))
}
This will start the activity hosting Fragments that will play the youtube video
findViewById<Button>(R.id.btn_sample2).setOnClickListener {
startActivity(Intent(this, Sample2Activity::class.java))
}
Here is the full code
package com.example.youtubeplayerview
import android.content.Intent
import android.os.Bundle
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
findViewById<Button>(R.id.btn_sample1).setOnClickListener {
startActivity(Intent(this, Sample1Activity::class.java))
}
findViewById<Button>(R.id.btn_sample2).setOnClickListener {
startActivity(Intent(this, Sample2Activity::class.java))
}
}
}
(b). Sample1Activity.kt
Create a file named Sample1Activity.kt
Reference the YouTubePlayerView and set its ID to the play()
function
val youTubePlayerView = findViewById<YouTubePlayerView>(R.id.you_tube_player_view)
youTubePlayerView.play(VIDEO_ID)
Here is the full code
package com.example.youtubeplayerview
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import kr.co.prnd.YouTubePlayerView
class Sample1Activity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_sample1)
val youTubePlayerView = findViewById<YouTubePlayerView>(R.id.you_tube_player_view)
youTubePlayerView.play(VIDEO_ID)
}
companion object {
private const val VIDEO_ID = "m2SZ6RV_J7I"
}
}
(c). Sample2Activity.kt
Create a file named Sample2Activity.kt
Here is the full code
package com.example.youtubeplayerview
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
class Sample2Activity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_sample2)
if (savedInstanceState == null) {
supportFragmentManager.beginTransaction()
.replace(R.id.container, Sample2Fragment.newInstance())
.commitNow()
}
}
}
(d). Sample2Fragment.kt
Create a file named Sample2Fragment.kt
This example looks at how to play the YouTube video in a Fragment. Override the onActivityCreated()
then reference YouTubePlayerView
and invoke its play()
function, passing in the ID
:
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
val youTubePlayerView =
view?.findViewById<YouTubePlayerView>(R.id.you_tube_player_view)
youTubePlayerView?.play(VIDEO_ID)
}
Here is the full code
package com.example.youtubeplayerview
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import kr.co.prnd.YouTubePlayerView
class Sample2Fragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View = inflater.inflate(R.layout.fragment_sample1, container, false)
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
val youTubePlayerView =
view?.findViewById<YouTubePlayerView>(R.id.you_tube_player_view)
youTubePlayerView?.play(VIDEO_ID)
}
companion object {
fun newInstance() = Sample2Fragment()
private const val VIDEO_ID = "m2SZ6RV_J7I"
}
}
Run
Simply copy the source code into your Android Project,Build and Run.