android-youtube-player

repository·dev·Indexed 25 days ago

https://github.com/pierfrancescosoffritti/android-youtube-player

A stable and customizable open-source YouTube player for Android and Chromecast. It acts as a wrapper around the YouTube IFrame Player API running in a WebView, providing a native Java/Kotlin interface. Features include a YouTubePlayerView for XML or programmatic layouts, lifecycle observer integration, Chromecast support via the chromecast-sender module, and a YouTubePlayerListener for intercepting playback events.

Tokens
11.2K
Snippets
25
Records
51
Agent score
86%

What's inside android-youtube-player

  1. Setup and Host the Chromecast Receiver

    dev

    This library requires a custom receiver.

    1. Source Code: Use the source code provided in the chromecast-receiver directory of this repository.
    2. Registration: Register a Custom Receiver in the Google Cast SDK Developer Console to obtain a receiverId.
    3. Hosting: You must host the receiver code on a web server (e.g., Firebase Hosting). The receiver web app is what runs on the Chromecast device when a session is initiated.
  2. Change Video Quality

    dev

    Since the IFrame Player API does not natively support changing video quality on mobile devices, you can implement a workaround by manipulating the localStorage of the WebView.

    Steps to implement:

    1. Enable DOM Storage: In WebViewYouTubePlayer#initWebView, ensure domStorageEnabled is set to true.
    2. Update HTML/JS: Add sendVideoQuality and setPlaybackQuality functions to ayp_youtube_player.html. The setPlaybackQuality function updates the yt-player-quality key in localStorage and reloads the video to apply changes.
    3. Bridge to Android: Add a @JavascriptInterface method sendVideoQuality to YouTubePlayerBridge.kt to pass quality levels back to the Android side.
    4. Update Interfaces:
      • Add fun setPlaybackQuality(quality: String) to the YoutubePlayer interface.
      • Implement setPlaybackQuality in WebViewYouTubePlayer.kt by calling the JavaScript function via loadUrl.
      • Add onVideoQuality(instance, quality) to your YouTubePlayerListener implementation.

    Usage: Use YouTubePlayerListener#onVideoQuality to retrieve available qualities and youtubePlayer#setPlaybackQuality to set the desired one.

    // In WebViewYouTubePlayer#initWebView
    settings.domStorageEnabled = true
    
    // In WebViewYouTubePlayer.kt implementation
    override fun setPlaybackQuality(quality: String) {
      mainThreadHandler.post { loadUrl("javascript:setPlaybackQuality('$quality')") }
    }
  3. Install the Chromecast extension library

    dev

    To add Google Cast functionalities to your Android app, add the chromecast-sender module to your dependencies. It is also recommended to add androidx.mediarouter:mediarouter to provide the standard cast button UI.

    implementation 'com.pierfrancescosoffritti.androidyoutubeplayer:chromecast-sender:last-version'
    
    // provides the cast button
    implementation 'androidx.mediarouter:mediarouter:last-version'
  4. Block Ads

    dev

    You can implement an ad-blocking workaround by periodically checking the WebView for the .video-ads element. When detected, the script mutes the ad, hides it, and fast-forwards it to the end to simulate completion.

    Implementation: Add the initializeAdBlock() function to ayp_youtube_player.html and call it from sendPlayerStateChange. The function uses a setInterval to poll the iframe's content every 100ms.

  5. Add YouTubePlayerView to your layout

    dev

    You can include the YouTubePlayerView in your Android layout using XML or create it programmatically. If the height is set to wrap_content, the view automatically adopts a 16:9 aspect ratio.

    XML Implementation:

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

    Programmatic Implementation (Java):

    YouTubePlayerView youTubePlayerView = new YouTubePlayerView(this);
    layout.addView(youTubePlayerView);
    <com.pierfrancescosoffritti.androidyoutubeplayer.core.player.views.YouTubePlayerView
        android:id="@+id/youtube_player_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
  6. Implement Fullscreen functionality

    dev

    To enable the fullscreen button, pass .fullscreen(1) to your IFramePlayerOptions. To handle the transition, add a FullscreenListener to the YouTubePlayerView.

    Important: When onEnterFullscreen is triggered, the player is rendered inside the provided fullscreenView. You are responsible for adding this view to your app's hierarchy and removing it when onExitFullscreen is called. It is also recommended to handle Activity orientation changes in your AndroidManifest.xml using android:configChanges to prevent the Activity from recreating during fullscreen transitions.

    youTubePlayerView.addFullscreenListener(new FullscreenListener() {
      @Override
      public void onEnterFullscreen(@NonNull View fullscreenView, @NonNull Function0<Unit> exitFullscreen) {
        // Add fullscreenView to your hierarchy
      }
    
      @Override
      public void onExitFullscreen() {
        // Remove fullscreenView from your hierarchy
      }
    });
  7. Use the DefaultPlayerUiController

    dev

    Starting from version 12.0.0, the library provides a pre-made, ready-to-use custom UI via the custom-ui module. This allows you to quickly implement a professional-looking player interface.

    Installation: You must add both the core and custom-ui modules to your build.gradle dependencies:

    dependencies {
        implementation 'com.pierfrancescosoffritti.androidyoutubeplayer:core:{latest-version}'
        implementation 'com.pierfrancescosoffritti.androidyoutubeplayer:custom-ui:{latest-version}'
    }

    Usage: Initialize the DefaultPlayerUiController inside the onReady callback of your YouTubePlayerListener and pass its root view to setCustomPlayerUi.

    YouTubePlayerListener listener = new AbstractYouTubePlayerListener() {
      @Override
      public void onReady(@NonNull YouTubePlayer youTubePlayer) {
        // Using pre-made custom ui
        DefaultPlayerUiController defaultPlayerUiController = new DefaultPlayerUiController(youTubePlayerView, youTubePlayer);
        youTubePlayerView.setCustomPlayerUi(defaultPlayerUiController.getRootView());
      }
    };
    
    // Disable iframe ui to prevent overlap
    IFramePlayerOptions options = new IFramePlayerOptions.Builder(context).controls(0).build();
    youTubePlayerView.initialize(listener, options);
  8. Hide UI Elements (Title, Popups, Captions)

    dev

    You can remove certain UI elements that are not exposed by the official API by injecting JavaScript into ayp_youtube_player.html and calling these functions inside onReady.

    Hide Video Title

    Uses a setInterval to find and hide the .ytp-chrome-top element.

    Hide Tablet 'More Videos' Popup

    Uses a setInterval to find and hide the .ytp-pause-overlay-container element (primarily for tablets/large screens).

    Manage Captions

    Use player.unloadModule('captions') to hide captions or player.loadModule('captions') to enable them.

  9. Create a custom UI for YouTubePlayerView

    dev

    You can completely replace the default YouTube player UI by providing your own layout or View. The new UI will be overlaid on top of the player.

    To avoid visual conflicts, it is highly recommended to disable the default IFrame player controls by initializing the YouTubePlayerView with IFramePlayerOptions where controls(0) is set.

    Key Methods:

    • View inflateCustomPlayerUi(@LayoutRes int customUiLayoutID): Inflates a layout resource as the custom UI.
    • void setCustomPlayerUi(View view): Sets a specific View as the custom UI.

    Note: You are responsible for managing the logic of your custom UI (e.g., play/pause buttons) by implementing your own controller class and adding it as a listener to the YouTubePlayer.

    // 1. Disable iframe UI
    IFramePlayerOptions options = new IFramePlayerOptions.Builder(context).controls(0).build();
    
    // 2. Inflate custom UI
    View customPlayerUi = youTubePlayerView.inflateCustomPlayerUi(R.layout.custom_player_ui);
    
    // 3. Initialize player with listener
    YouTubePlayerListener listener = new AbstractYouTubePlayerListener() {
      @Override
      public void onReady(@NonNull YouTubePlayer youTubePlayer) {
        // Manage your UI logic here
        CustomPlayerUiController customPlayerUiController = new CustomPlayerUiController(CustomUiActivity.this, customPlayerUi, youTubePlayer, youTubePlayerView);
        youTubePlayer.addListener(customPlayerUiController);
      }
    };
    
    youTubePlayerView.initialize(listener, options);
  10. Manage YouTubePlayerView lifecycle

    dev

    It is highly recommended to register YouTubePlayerView as a LifecycleObserver of your Activity or Fragment. This allows the player to automatically pause playback when the lifecycle owner stops (supporting multi-window mode).

    Registering as observer:

    lifecycleOwner.getLifecycle().addObserver(youTubePlayerView);

    Manual Release: If you do not register the view as a LifecycleObserver, you must manually call release() in your onDestroy() method to prevent memory leaks.

    Note on Background Playback: If you want the video to keep playing when the Activity/Fragment is not visible, do not register it as a LifecycleObserver. However, be aware that this behavior may violate Play Store policies.

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