Smooth Video Streaming with React Native

ajmal_hasan

Ajmal Hasan

Posted on August 23, 2024

Smooth Video Streaming with React Native

Building a Smooth Video Streaming Experience with React Native Video

In today’s mobile-centric world, video streaming is a core feature of many applications. Whether it's a video-sharing platform, an educational app, or a multimedia-rich social network, providing a seamless video experience is essential. With React Native, a popular framework for building cross-platform mobile apps, integrating video streaming is made easy with the react-native-video library.

In this blog, we'll walk through the steps to install, configure, and use react-native-video to create a smooth video streaming experience in your React Native applications.


1. Installation

To get started, you need to install the react-native-video and react-native-video-cache library in your React Native project.

Step 1: Install the package

First, install the library using npm or yarn:

npm install react-native-video react-native-video-cache
Enter fullscreen mode Exit fullscreen mode

or

yarn add react-native-video react-native-video-cache
Enter fullscreen mode Exit fullscreen mode

For iOS, you might need to install the necessary pods:

cd ios
pod install
cd ..
Enter fullscreen mode Exit fullscreen mode

Step 2: Additional native setup for iOS/Android

a) Android:

i) android/build.gradle

buildscript {
  ext {
    // Enable IMA (Interactive Media Ads) integration with ExoPlayer
    useExoplayerIMA = false

    // Enable support for RTSP (Real-Time Streaming Protocol) with ExoPlayer
    useExoplayerRtsp = true

    // Enable support for Smooth Streaming with ExoPlayer
    useExoplayerSmoothStreaming = true

    // Enable support for DASH (Dynamic Adaptive Streaming over HTTP) with ExoPlayer
    useExoplayerDash = true

    // Enable support for HLS (HTTP Live Streaming) with ExoPlayer
    useExoplayerHls = true
  }
}

allprojects {
    repositories {
        mavenLocal()
        google()
        jcenter()
         maven {
            url "$rootDir/../node_modules/react-native-video-cache/android/libs"
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

This configuration enables various streaming protocols (IMA, RTSP, Smooth Streaming, DASH, HLS) in ExoPlayer and sets up repositories to include local, Google, JCenter, and a custom Maven repository for react-native-video-cache.
Each of these features enabled will increase the size of your APK, so only enable the features you need. By default enabled features are: useExoplayerSmoothStreaming, useExoplayerDash, useExoplayerHls

ii) AndroidManifest.xml

    <application
      ...
      android:largeHeap="true" 
      android:hardwareAccelerated="true">
Enter fullscreen mode Exit fullscreen mode

The combination ensures that the app has enough memory to handle large datasets (via largeHeap) and can render graphics efficiently (via hardwareAccelerated), leading to a smoother and more stable user experience. However, both should be used with consideration of the app's performance and the specific needs of its functionality.

b) iOS:

i) In ios/your_app/AppDelegate.mm inside didFinishLaunchingWithOptions add:

#import <AVFoundation/AVFoundation.h> 

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  self.moduleName = @"your_app";

  // --- You can add your custom initial props in the dictionary below.
  [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
  // --- They will be passed down to the ViewController used by React Native.

  self.initialProps = @{};
  return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
Enter fullscreen mode Exit fullscreen mode

Ensuring that audio continues to play even when the app is in the background or in silent mode

ii) ios/Podfile:

...
# ENABLE THIS FOR CACHEING THE VIDEOS 
platform :ios, min_ios_version_supported
prepare_react_native_project!
# -- ENABLE THIS FOR CACHEING THE VIDEOS 
$RNVideoUseVideoCaching=true

...

target 'your_app' do

  config = use_native_modules!
  # ENABLE THIS FOR CACHEING THE VIDEOS 
  pod 'SPTPersistentCache', :modular_headers => true;
  pod 'DVAssetLoaderDelegate', :modular_headers => true;

...

Enter fullscreen mode Exit fullscreen mode

This configuration enables video caching in the iOS project by adding specific CocoaPods (SPTPersistentCache and DVAssetLoaderDelegate) that handle caching and asset loading. The flag $RNVideoUseVideoCaching=true signals that the project should use these caching capabilities. This setup improves the performance of video playback by reducing the need to re-fetch video files.


2. Usage:

import Video from 'react-native-video';
import convertToProxyURL from 'react-native-video-cache';

          <Video
  // Display a thumbnail image while the video is loading
  poster={item.thumbUri}

  // Specifies how the thumbnail should be resized to cover the entire video area
  posterResizeMode="cover"

  // Sets the video source URI if the video is visible; otherwise, it avoids loading the video
  source={
    isVisible
      ? { uri: convertToProxyURL(item.videoUri) } // Converts the video URL to a proxy URL if visible
      : undefined // Avoid loading the video if not visible
  }

  // Configures buffer settings to manage video loading and playback
  bufferConfig={{
    minBufferMs: 2500, // Minimum buffer before playback starts
    maxBufferMs: 3000, // Maximum buffer allowed
    bufferForPlaybackMs: 2500, // Buffer required to start playback
    bufferForPlaybackAfterRebufferMs: 2500, // Buffer required after rebuffering
  }}

  // Ignores the silent switch on the device, allowing the video to play with sound even if the device is on silent mode
  ignoreSilentSwitch={'ignore'}

  // Prevents the video from playing when the app is inactive or in the background
  playWhenInactive={false}
  playInBackground={false}

  // Disables the use of TextureView, which can optimize performance but might limit certain effects
  useTextureView={false}

  // Hides the default media controls provided by the video player
  controls={false}

  // Disables focus on the video, which is useful for accessibility and UI focus management
  disableFocus={true}

  // Applies the defined styles to the video container
  style={styles.videoContainer}

  // Pauses the video based on the isPaused state
  paused={isPaused}

  // Repeats the video playback indefinitely
  repeat={true}

  // Hides the shutter view (a black screen that appears when the video is loading or paused)
  hideShutterView

  // Sets the minimum number of retry attempts when the video fails to load
  minLoadRetryCount={5}

  // Ensures the video maintains the correct aspect ratio by covering the entire view area
  resizeMode="cover"

  // Sets the shutter color to transparent, so the shutter view is invisible
  shutterColor="transparent"

  // Callback function that is triggered when the video is ready for display
  onReadyForDisplay={handleVideoLoad}
/>

Enter fullscreen mode Exit fullscreen mode

3. Tips for Optimization

To ensure smooth video playback:

  • Use a CDN: Host your videos on a CDN (Content Delivery Network) for faster loading.
  • Adaptive Streaming: Implement adaptive streaming (HLS or DASH) to adjust the video quality based on network conditions.
  • Preload Videos: Preload videos to avoid buffering during playback.
  • Optimize Video Files: Compress video files without losing quality to reduce load times.

Conclusion

The react-native-video library is a powerful tool for adding video functionality to your React Native applications. With its extensive configuration options and event handling capabilities, you can create a smooth and customized video streaming experience for your users. Whether you need a basic player or a fully customized one, react-native-video has you covered.

💖 💪 🙅 🚩
ajmal_hasan
Ajmal Hasan

Posted on August 23, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related