react-native-youtube-iframe

repository·master·Indexed 20 days ago

https://github.com/lonelycpp/react-native-youtube-iframe

A React Native wrapper for the YouTube IFrame player API (version 2.4.1) that provides a stable, webview-based video player for iOS and Android, including Expo environments. It allows for multiple player instances on a single page, metadata fetching via oEmbed without API keys, and does not require the native YouTube app to be installed on Android devices.

Tokens
8.6K
Snippets
32
Records
45
Agent score
71%

What's inside react-native-youtube-iframe

  1. Overview of react-native-youtube-iframe

    master

    react-native-youtube-iframe is a React Native wrapper for the YouTube IFrame Player API. It provides a stable way to embed YouTube videos in mobile applications by using a WebView-based player rather than relying on the native YouTube app installed on the device.

    Key Features:

    • Cross-Platform: Works on both iOS and Android.
    • Stability: Uses the webview player, which is more stable than the native YouTube app and prevents crashes on devices without the YouTube app installed.
    • Multi-instance Support: Allows multiple YouTube player instances on a single page.
    • Metadata Access: Can fetch basic video metadata using oEmbed without requiring an API key.
    • UI Compatibility: Works within modals and overlay components.
    • Expo Support: Fully compatible with Expo environments.
  2. Overview of react-native-youtube-iframe features

    master

    The react-native-youtube-iframe library is a wrapper for the YouTube IFrame player API designed for React Native. Key features include:

    • Cross-platform support: Works on both iOS and Android.
    • Stability: Uses a webview player instead of the native YouTube app, which prevents crashes on Android devices that lack the YouTube app.
    • Rich API: Provides access to the extensive YouTube IFrame API.
    • Multi-instance support: Allows multiple YouTube player instances on a single page.
    • Metadata fetching: Can fetch basic video metadata using oEmbed without requiring API keys.
    • UI Compatibility: Works within modals and overlay components.
    • Expo support: Fully compatible with Expo projects.
  3. Disable long-press context menu on YoutubePlayer

    master

    To prevent the default YouTube context menu from appearing when a user long-presses the player, you must prevent touch events from reaching the underlying WebView.

    Wrap the <YoutubePlayer /> in a View with pointerEvents="none". Then, wrap that View in a React Native Pressable (or another Touchable component) to intercept the touch events yourself.

    <Pressable
      onPress={() => {
        // handle or ignore
      }}
      onLongPress={() => {
        // handle or ignore
      }}>
    
      <View pointerEvents="none">
        <YoutubePlayer (...) />
      </View>
    
    </Pressable>
  4. Basic usage of YoutubePlayer

    master

    To render a YouTube video in a React Native application, use the YoutubePlayer component. You can control playback using the play prop and respond to player state changes (such as when a video ends) using the onChangeState prop.

    Key props used in this example:

    • videoId: The unique ID of the YouTube video to load.
    • play: A boolean determining if the video is currently playing.
    • height: The height of the player in pixels.
    • onChangeState: A callback function that receives the current state of the player (e.g., 'ended').
    import React, { useState, useCallback } from "react";
    import { Button, View, Alert } from "react-native";
    import YoutubePlayer from "react-native-youtube-iframe";
    
    export default function App() {
      const [playing, setPlaying] = useState(false);
    
      const onStateChange = useCallback((state) => {
        if (state === "ended") {
          setPlaying(false);
          Alert.alert("video has finished playing!");
        }
      }, []);
    
      const togglePlaying = useCallback(() => {
        setPlaying((prev) => !prev);
      }, []);
    
      return (
        <View>
          <YoutubePlayer
            height={300}
            play={playing}
            videoId={"iee2TATGMyI"}
            onChangeState={onStateChange}
          />
          <Button title={playing ? "pause" : "play"} onPress={togglePlaying} />
        </View>
      );
    }
  5. Show elapsed time using getCurrentTime()

    master

    To display the current playback time of a video, use the getCurrentTime() method provided by the YoutubePlayer component. Because getCurrentTime() returns a Promise, you must await the result.

    Since the player does not provide a continuous stream of time updates, the recommended pattern is to use setInterval to poll the current time at a specific frequency. You can adjust the interval duration (e.g., 100ms) to balance between UI update smoothness and performance/accuracy requirements.

    import React, {useState, useRef, useEffect} from 'react';
    import {Text, View} from 'react-native';
    import YoutubePlayer from 'react-native-youtube-iframe';
    
    const App = () => {
      const [elapsed, setElapsed] = useState(0);
      const playerRef = useRef();
    
      useEffect(() => {
        const interval = setInterval(async () => {
          // getCurrentTime() is a promise
          const elapsed_sec = await playerRef.current.getCurrentTime();
    
          // Convert seconds to MM:SS:mmm format
          const elapsed_ms = Math.floor(elapsed_sec * 1000);
          const ms = elapsed_ms % 1000;
          const min = Math.floor(elapsed_ms / 60000);
          const seconds = Math.floor((elapsed_ms - min * 60000) / 1000);
    
          setElapsed(
            min.toString().padStart(2, '0') +
              ':' +
              seconds.toString().padStart(2, '0') +
              ':' +
              ms.toString().padStart(3, '0'),
          );
        }, 100); // 100 ms refresh
    
        return () => {
          clearInterval(interval);
        };
      }, []);
    
      return (
        <>
          <YoutubePlayer
            height={250}
            ref={playerRef}
            videoId={'DC471a9qrU4'}
          />
          <View>
            <View style={{flexDirection: 'row'}}>
              <Text style={{flex: 1}}>{'elapsed time'}</Text>
              <Text style={{flex: 1, color: 'green'}}>{elapsed}</Text>
            </View>
          </View>
        </>
      );
    };
  6. Disable kebab menu (share) interaction on YoutubePlayer

    master

    You cannot modify the internal UI of the YouTube player to remove the kebab menu (three dots) or the logo. However, you can make these elements un-interactable by placing an absolutely positioned view over them.

    By placing a TouchableOpacity (or similar) with position: 'absolute' over the top area of the player, you "steal" the taps before they reach the WebView, preventing users from accessing the share/menu options.

    <View>
      <YoutubePlayer height={300} videoId={'XSqi5s3rfqk'} />
      <TouchableOpacity
        // TouchableOpacity to "steal" taps
        // absolutely positioned to the top
        // height must be adjusted to
        // just cover the top 3 dots
        style={{
          top: 0,
          height: 50,
          width: '100%',
          position: 'absolute',
        }}
      />
    </View>
  7. Install react-native-youtube-iframe

    master

    To use the YouTube IFrame player in your React Native project, install the react-native-youtube-iframe package. This library provides a webview-based player that works on both iOS and Android, including Expo environments. It does not require the native YouTube app to be installed on Android devices.

    npm install react-native-youtube-iframe
  8. Self-host the static HTML player page

    master

    To avoid the "embed not allowed" error that occurred in versions prior to v2.0.0 (caused by using about:blank as the base URL), you can host the required static HTML page on your own web server. This page handles the YouTube iframe logic.

    While the package now handles this more gracefully, you can manually host the iframe.html source on your own server if you have specific hosting requirements.

    Note: Manual hosting is not recommended because you will be responsible for manually updating the file if the source code changes.

    https://github.com/LonelyCpp/react-native-youtube-iframe/blob/master/iframe.html