android-youtube-player

Additional

Language
Java
Version
8.0.1 (Jun 30, 2018)
Created
Aug 29, 2016
Updated
Oct 7, 2018
Owner
Pierfrancesco Soffritti (PierfrancescoSoffritti)
Contributors
talklittle
Askar (askarsyzdykov)
Pierfrancesco Soffritti (PierfrancescoSoffritti)
Denino
RmK (rajeefmk)
ambiguous1991
ValCanBuild
7
Activity
Badge
Generate
Download
Source code
APK file

Show card

android-youtube-player

The android-youtube-player library is a stable and customizable open source YouTube player for Android. It provides a simple View that can be easily integrated in every Activity/Fragment.

The interaction with YouTube is based on the IFrame Player API, running inside of a WebView, therefore the YouTube app is not required on the user's device.

The web UI of the IFrame Player player is hidden. Instead, a native UI built on top of Android is used to interact with the player, providing a native experience to the users.

The UI of the player is 100% customizable. The default UI can be changed, to show and hide new views, or can be completely replaced by a custom UI.

This library also provides a Chromecast YouTube player, that you can use to cast YouTube videos from your app to a Chromecast device.

Why does this library exists?

This library has been developed out of necessity. The official library provided by Google to integrate YouTube videos in Android apps is the YouTube Android Player API. I've found the official library to be quite buggy (some bugs are 5+ years old) and lacking in support from Google. It was quite unreliable and therefore unusable in production.

This, added to its limited options for customization and lack of Chromecast support, lead me to the development of this open source library.

A lengthier explanation to why you may want to consider using an alternative to the official YouTube player is written in this Medium post.

A list of published apps that are using this library: (let me know if you want to add your app to this list)


Get a reference to the YouTubePlayerView in your code and initialize it

YouTubePlayerView youtubePlayerView = findViewById(R.id.youtube_player_view);
getLifecycle().addObserver(youtubePlayerView);

youtubePlayerView.initialize(new YouTubePlayerInitListener() {
    @Override
    public void onInitSuccess(@NonNull final YouTubePlayer initializedYouTubePlayer) {    
        initializedYouTubePlayer.addListener(new AbstractYouTubePlayerListener() {
            @Override
            public void onReady() {
                String videoId = "6JYIGclVQdw";
                initializedYouTubePlayer.loadVideo(videoId, 0);
            }
        });        
    }
}, true);

That's all you need, a YouTube video is now playing in your app.

YouTubePlayerView

YouTubePlayerView is the access point to the core library.

You can add the View to your layout

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <com.pierfrancescosoffritti.androidyoutubeplayer.player.YouTubePlayerView
        android:id="@+id/youtube_player_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
</LinearLayout>

or you can initialize it programmatically and manually add it to a ViewGroup

YouTubePlayerView youtubePlayerView = new YouTubePlayerView(this);
layout.addView(youtubePlayerView);

if the height of the View is set to wrap_content, the View will automatically have an aspect ratio of 16:9, to fit the aspect ratio of YouTube videos.

Initialization

In order to use the YouTube player you need to initialize it. To do that, call YouTubePlayerView.initialize(YouTubePlayerInitListener listener, boolean handleNetworkEvents).

This methods takes in a YouTubePlayerInitListener and a boolean. The boolean parameter is used to tell the library whether it should handle network events or not, read more about network events here.

The callback YouTubePlayerInitListener.onInitSuccess(YouTubePlayer initializedYouTubePlayer) will be called by the library when the initialization is completed. That is, when the IFrame YouTube player has been download in the WebView. The argument of the function is a reference to the initialized YouTubePlayer object. The YouTubePlayer is the object responsible for handling the playback of YouTube videos, read more about it here.

Full screen

You can use the YouTubePlayerView to set the player full screen or not, using these methods

youtubePlayerView.enterFullScreen();
youtubePlayerView.exitFullScreen();
youtubePlayerView.isFullScreen();
youtubePlayerView.toggleFullScreen();

You can also add listeners to get notified when the YouTubePlayerView enters or exits full screen

youtubePlayerView.addFullScreenListener(YouTubePlayerFullScreenListener fullScreenListener);
youtubePlayerView.removeFullScreenListener(YouTubePlayerFullScreenListener fullScreenListener);

The sample app contains an helper class that can help you to update your UI when enter/exit fullscreen.

It's important to keep in mind the the library is not responsible for changing the orientation of your Activity, that's up to you.

By default Android recreates Activities and Fragments when the orientation changes. Make sure that you manually handle orientation changes by adding the attribute android:configChanges to your Activity definition in the manifest.

<application >
  <activity  
    android:configChanges="orientation|screenSize|keyboardHidden|smallestScreenSize|screenLayout" />
</application>

If you don't do that the player will lose all the data it has buffered and re-start from zero after the orientation has changed.

UI

If you want to interact with the UI of the player you need to get a reference to the PlayerUIController from the YouTubePlayerView by calling this method

PlayerUIController YouTubePlayerView.getPlayerUIController();

You can read more about PlayerUIController here.

Release the YouTubePlayerView

Remember to release the YouTubePlayerView when you're done using it, by calling YouTubePlayerView.release().

@Override
public void onDestroy() {
    super.onDestroy();
    youtubePlayerView.release();
}

You don't need to manually release the player if you register it as an observer of your Activity/Fragment's lifecycle.

LifecycleObserver

YouTubePlayerView implements the LifecycleObserver interface, this means that is a lifecycle aware component. If added as an observer of your Activity/Fragment's lifecycle, the release() method will be called automatically.

lifecycleOwner.getLifecycle().addObserver(youTubePlayerView);

Adding YouTubePlayerView as an observer to a lifecycle will also automatically cause the player to pause the playback when the Activity/Fragment stops (not when it pauses, in order to support multi-window applications).

If you want your app to keep playing when the Activity/Fragment is not visible (remember that this behavior is not allowed, if you want to publish your app on the PlayStore), don't register the YouTubePlayerView as a lifecycle observer. But remember to manually call release() when the Activity/Fragment is being destroyed.

YouTubePlayer

YouTubePlayer is the component responsible for controlling the playback of YouTube videos. You can see its contract here.

You can only get a reference to the YouTubePlayer when initializing the YouTubePlayerView.

Events

During its existence the player will constantly emit events, you can easily listen to all of them by adding a YouTubePlayerListener to it.

The onReady event

The onReady callback of a YouTubePlayerListener is called once, when the YouTubePlayer is ready to be used. You can't use a YouTubePlayer before it is ready.

Player state

The player has a state, that changes accordingly to the playback changes. The list of possible states is the same of the YouTube IFrame Player API.

UNKNOWN
UNSTARTED
ENDED
PLAYING
PAUSED
BUFFERING
VIDEO_CUED

YouTubePlayerTracker

YouTubePlayerTracker is an utility provided by the library to easily keep track of a YouTubePlayer's state and other information.

YouTubePlayerTracker is a YouTubePlayerListener, therefore in order to use it you need to add it as a listener to the YouTubePlayer.

You can then use the tracker to get the player's state and various information about the video that is being played.

YouTubePlayerTracker tracker = new YouTubePlayerTracker();
youtubePlayer.addListener(tracker);

tracker.getState();
tracker.getCurrentSecond();
tracker.getVideoDuration();
tracker.getVideoId();

YouTubePlayerListener

A YouTubePlayerListener is used to intercept events emitted by a YouTubePlayer.

During its existence a YouTubePlayer will constantly emit events, you can listen to them by adding a YouTubePlayerListener to it.

youtubePlayer.addListener(YouTubePlayerListener listener);
youtubePlayer.removeListener(YouTubePlayerListener listener);

If you don't want to implement all the methods of the YouTubePlayerListener interface, you can extend AbstractYouTubePlayerListener instead of implementing YouTubePlayerListener and override only the methods you are interested in.

For more information on the methods defined in the YouTubePlayerListener interface, please refer to the documentation defined above each method here.

PlayerUIController

The PlayerUIController is responsible for controlling the UI of a YouTubePlayerView.

You can get a reference to the PlayerUIController from the YouTubePlayerView

youtubePlayerView.getPlayerUIController();

Show video title

PlayerUIController exposes a method called setVideoTitle(String videoTitle).

Unfortunately the library doesn't know the title of the videos it plays. Therefore, if you want to use this method to set the real title of the video, you need to find it first. The best way to do that is by using the YouTube Data API to fetch the video title from the video id.

You can see an example in the method setVideoTitle(PlayerUIController playerUIController, String videoId) from the sample app.

Live videos

If you want to play live videos you must setup the UI accordingly, by calling this method

PlayerUIController.enableLiveVideoUI(boolean enable);

Unfortunately there is no way for the player to automatically know if it is playing a live video or not, therefore is up to the developer to change the UI accordingly.

Custom actions

You can set custom actions on the right and left side of the Play/Pause button of the player

PlayerUIController.setCustomAction1(Drawable icon, OnClickListener listener);
PlayerUIController.setCustomAction2(Drawable icon, OnClickListener listener);
PlayerUIController.showCustomAction1(boolean show);
PlayerUIController.showCustomAction2(boolean show);

by default if you set a custom action with a null listener the icon won't be visible.

You can also add any type of View to the UI, this can be useful if you want to add a new icon to the UI.

PlayerUIController.addView(View view);
PlayerUIController.removeView(View view);

The View will be added to the top of the player.

Menu

You can use these methods to control the menu's behavior:

PlayerUIController.showMenuButton(boolean show);
PlayerUIController.setMenuButtonClickListener(@NonNull View.OnClickListener customMenuButtonClickListener);

By default the menu icon is not visible.

The default OnClickListener opens the default menu.

YouTubePlayerMenu

Internally the menu is represented by a YouTubePlayerMenu. You can see its contract here.

You can get a reference of the YouTubePlayerMenu from the PlayerUIController, using the method PlayerUIController.getMenu().

You can add your own implementation of YouTubePlayerMenu using PlayerUIController.setMenu(YouTubePlayerMenu youTubePlayerMenu).

DefaultYouTubePlayerMenu

The default implementation of YouTubePlayerMenu (provided by the library) shows a popup window when its show() method is called. The popup window contains a list of MenuItems. You can see the implementation of the default menu here.

Unless you want to provide a different UX to your users you can safely use the default implementation of YouTubePlayerMenu. Otherwise you can change the click listener of the menu icon or provide a custom implementation of YouTubePlayerMenu.

Initially the menu doesn't contain any MenuItem. You need to add them, using the method YouTubePlayerMenu.addItem(MenuItem menuItem).

MenuItem

MenuItems are the entries in the YouTubePlayerMenu. They are POJOs with a String of text, an icon and a OnClickListener. Here is the implementation.

Create your own custom UI

Customization is an important aspect of this library. If need to, you can completely replace the default UI of the player.

YouTubePlayerView's method

View inflateCustomPlayerUI(@LayoutRes int customUILayoutID)

can be used to replace the default UI of the player.

This method takes in the id of a layout resource, which is a regular XML file defining a layout. The default UI of the player is removed and replaced with the new UI. The method returns the View object corresponding to the newly inflated layout.

After calling this method, the default PlayerUIController won't be available anymore. Calling YouTubePlayerView.getPlayerUIController() will throw an exception.

You are now responsible for managing your custom UI with your own code. Meaning: you should write your own class to manage the UI. A simple but complete example can be seen here, in the sample app, I recommend taking a few minutes to read it, it should be trivial to understand.

Example (taken from sample app):

View customPlayerUI = youTubePlayerView.inflateCustomPlayerUI(R.layout.custom_player_ui);

youTubePlayerView.initialize(youTubePlayer -> {

  CustomPlayerUIController customPlayerUIController = new CustomPlayerUIController(this, customPlayerUI, youTubePlayer, youTubePlayerView);
  youTubePlayer.addListener(customPlayerUIController);
  youTubePlayerView.addFullScreenListener(customPlayerUIController);

  // ...
}, true);

A post on this topic is available here.

Sample app example:

Network events

This library is capable of handling network events, using an internal BroadcastReceiver. You can choose to use it or not when you are initializing the player.

Call YouTubePlayerView.initialize(..., true) to let the library register its BroadcastReceiver or call YouTubePlayerView.initialize(..., false) if you prefer to use your own.

Using the internal BroadcastReceiver is the easiest and recommended way to handle network events. The library is capable of handling cases in which the connection goes off and the playback can't continue, or cases in which the connection goes off while the player is in the process of initialization.

For example, if the player is playing but is stopped by a lost connection, once the connection is back the player automatically resumes the playback from where it left off. Otherwise if the player was paused, when the connection is back it just stays paused while automatically resuming the buffering of the video.

If you want to use your own BroadcastReceiver make sure to cover all this scenarios, in order to provide a good user experience.

Chromecast support

If you need to cast YouTube videos to a Chromecast device you can use the chromecast-sender extension library. Read its documentation here.

Useful info

Hardware acceleration

Is important that the Activity containing the YouTubePlayerView is hardware accelerated. This option is enabled by default, you don't have to change anything in your app. Unless you manually disabled hardware acceleration.

If you need to disable hardware acceleration in your application, you can enable it at the Activity level, only for the Activity containing the YouTubePlayerView, as explained here.

Disabling hardware acceleration on the Activity containing YouTubePlayerView may result in some weird behavior. The one I have observed so far shows a black image in the player, while the audio is playing normally.

Play YouTube videos in the background

With this library is easy to play YouTube videos when the app is not visible. In order to do that you simply have to not call youtubePlayer.pause() when the Activity is being paused or stopped.

Adding YouTubePlayerView as an observer to a lifecycle will automatically cause the player to pause the playback when the Activity/Fragment stops.

Therefore if you want your app to keep playing even when the Activity/Fragment is paused/stopped, don't register it as a lifecycle observer. But remember to manually call YouTubePlayerView.release() when the Activity/Fragment is destroyed.

Remember that this behavior is against YouTube terms of service, therefore if you decide to allow background playback you won't be able to publish your app on the Play Store.

Use this functionality only if you plan to build the app for personal use or if you plan to distribute it through different channels.

minSdk

The minSdk of the library is 17. At this point in time it doesn't make much sense for new apps to support older versions of Android.

I'm not sure how WebView will behave on older versions of Android, but technically it should be possible to lower the minSdk. If you absolutely need to support older devices, I suggest you fork the library and lower the minSdk yourself.