# Player configurations (React Native)

We have the following three entries to open the player.

1. `VideoFeed` component
2. `StoryBlock` component
3. `openVideoPlayer` API

When customizing the player, you need to handle the above entries if you use them.

### Configuration reference <a href="#configuration-reference" id="configuration-reference"></a>

1. [VideoPlayerConfiguration](https://eng.firework.com/react-native-firework-sdk/v2/interfaces/VideoPlayerConfiguration.html)
2. [StoryBlockConfiguration](https://eng.firework.com/react-native-firework-sdk/v2/interfaces/StoryBlockConfiguration.html)
3. [OpenVideoPlayerConfiguration](https://eng.firework.com/react-native-firework-sdk/v2/interfaces/OpenVideoPlayerConfiguration.html)

### Customize player styles

As the following code snippets, we could customize styles for video overlay CTA, countdown timer, etc.

```tsx
// Configure player configuration for VideoFeed component
<VideoFeed
  style={{ height: 200 }}
  source="discover"
  videoPlayerConfiguration={{
    // Customize the video overlay CTA button style
    ctaButtonStyle: {
      backgroundColor: '#2089ff',
      textColor: '#ffffff',
      fontSize: 14,
      shape: 'roundRectangle',
      iOSFontInfo: {
        fontName: 'Helvetica',
        systemFontStyle: 'italic',
        systemFontWeight: 'bold',
      },
    },
    countdownTimerConfiguration: { appearance: 'light' },
  }}
/>;

// Configure player configuration for StoryBlock component
<StoryBlock
  style={{ height: 200 }}
  source="discover"
  storyBlockConfiguration={{
    // Customize the video overlay CTA button style
    ctaButtonStyle: {
      backgroundColor: '#2089ff',
      textColor: '#ffffff',
      fontSize: 14,
      shape: 'roundRectangle',
      iOSFontInfo: {
        fontName: 'Helvetica',
        systemFontStyle: 'italic',
        systemFontWeight: 'bold',
      },
    },
    countdownTimerConfiguration: { appearance: 'light' },
  }}
/>;

// Configure player configuration for openVideoPlayer API
FireworkSDK.getInstance().openVideoPlayer(url, {
  // Customize the video overlay CTA button style
  ctaButtonStyle: {
    backgroundColor: '#2089ff',
    textColor: '#ffffff',
    fontSize: 14,
    shape: 'roundRectangle',
    iOSFontInfo: {
      fontName: 'Helvetica',
      systemFontStyle: 'italic',
      systemFontWeight: 'bold',
    },
  },
  countdownTimerConfiguration: { appearance: 'light' },
});
```

### Enable PiP(Picture in Picture)

Please refer to <https://docs.firework.com/firework-for-developers/react-native-sdk/integration-guide-v2/customization-react-native/player-configurations-react-native#enable-pip-picture-in-picture>

#### Set up the iOS project

To enable PiP outside the iOS app, you also need to add "Audio, Airplay, and Picture in Picture" background mode via Signing & Capabilities in your iOS project settings(as shown in the following screenshot). More information about this can be found here: [Apple Documentation](https://developer.apple.com/documentation/avfoundation/media_playback/configuring_the_audio_playback_of_ios_and_tvos_apps)

<figure><img src="/files/WKWATSXvTrLwuiHFwgzt" alt=""><figcaption></figcaption></figure>

#### Set enablePictureInPicture to true on JS side

```tsx
// Enable PiP for VideoFeed component
<VideoFeed
  style={{ height: 200 }}
  source="discover"
  enablePictureInPicture={true}
/>

// Enable PiP for StoryBlock component
<StoryBlock
  style={{ height: 400 }}
  source="discover"
  enablePictureInPicture={true}
/>

// Enable PiP for openVideoPlayer API
FireworkSDK.getInstance().openVideoPlayer(url, {
  enablePictureInPicture: true,
});
```

### Customize player button icons

#### **Set up the iOS project**

Add your custom button icons to the asset catalogs(e.g. Images.xcassets, Assets.xcassets or other names) in your iOS project. Such as:

<figure><img src="/files/rnrx2GiDe7CQJRU63jkk" alt=""><figcaption></figcaption></figure>

**For more details, please refer to** [**https://developer.apple.com/documentation/xcode/adding-images-to-your-xcode-project**](https://developer.apple.com/documentation/xcode/adding-images-to-your-xcode-project)**.**

#### **Set up the Android project**

Add your custom button icons to the drawable directory([<mark style="color:orange;">App resources overview</mark>](https://developer.android.com/guide/topics/resources/providing-resources#ResourcesFromCode) and [<mark style="color:orange;">Support different pixel densities</mark>](https://developer.android.com/training/multiscreen/screendensities)) in your Android project. Such as:

<figure><img src="/files/4ePrGu4jaZREIJthJ9NJ" alt=""><figcaption></figcaption></figure>

#### **Config player button icon names on the JS side**

<pre class="language-tsx"><code class="lang-tsx"><strong>// Configure button icon names for video feed component
</strong><strong>&#x3C;VideoFeed
</strong>  style={{ height: 200 }}
  source="discover"
  mode="row"
  videoFeedConfiguration={videoFeedConfiguration}
  videoPlayerConfiguration={{
    buttonConfiguration: {
      videoDetailButton: { imageName: 'custom_more' },
<strong>      closeButton: { imageName: 'custom_close' },
</strong>      muteButton: { imageName: 'custom_mute' },
      unmuteButton: { imageName: 'custom_unmute' },
      playButton: { imageName: 'custom_play' },
      pauseButton: { imageName: 'custom_pause' },
    },
  }}
/>

// Configure button icon names for story block component
&#x3C;StoryBlock
  style={{ height: 200 }}
  source="discover"
  storyBlockConfiguration={{
    buttonConfiguration: {
      videoDetailButton: { imageName: 'custom_more' },
      closeButton: { imageName: 'custom_close' },
      muteButton: { imageName: 'custom_mute' },
      unmuteButton: { imageName: 'custom_unmute' },
      playButton: { imageName: 'custom_play' },
      pauseButton: { imageName: 'custom_pause' },
    },
  }}
/>;

// Configure button icon names for openVideoPlayer API
FireworkSDK.getInstance().openVideoPlayer(url, {
  buttonConfiguration: {
    videoDetailButton: { imageName: 'custom_more' },
    closeButton: { imageName: 'custom_close' },
    muteButton: { imageName: 'custom_mute' },
    unmuteButton: { imageName: 'custom_unmute' },
    playButton: { imageName: 'custom_play' },
    pauseButton: { imageName: 'custom_pause' },
  },
});
</code></pre>

Please refer to [buttonConfiguration](https://eng.firework.com/react-native-firework-sdk/v2/interfaces/VideoPlayerConfiguration.html#buttonConfiguration) for more details.

### Customize player logo

To display the channel logo instead of the more icon (three dots) in the player, you could refer to the following code snippets.

```tsx
// Customize player logo for video feed component
<VideoFeed
  style={{ height: 200 }}
  source="discover"
  videoPlayerConfiguration={{
    videoPlayerLogoConfiguration: {
      option: 'creator',
      encodedId: 'encoded channel id', // encoded channel id
    }
  }}
/>

// Customize player logo for story block component
<StoryBlock
  style={{ height: 400 }}
  source="discover"
  storyBlockConfiguration={{
    videoPlayerLogoConfiguration: {
      option: 'creator',
      encodedId: 'encoded channel id', // encoded channel id
    }
  }}
/>

// Customize player logo for openVideoPlayer API
FireworkSDK.getInstance().openVideoPlayer(url, {
  videoPlayerLogoConfiguration: {
    option: 'creator',
    encodedId: 'encoded channel id', // encoded channel id
  },
});
```

### Customize Ad badge

We offer a global API for customizing ad badges, and these configurations are applicable to both the player and the video feed. The API is `FireworkSDK.getInstance().adBadgeConfiguration`.

```dart
FireworkSDK.getInstance().adBadgeConfiguration = {
  badgeTextType: 'ad', // or sponsored
  backgroundColor: '#ffffff',
  textColor: '#000000',
  androidFontInfo: {
    isCustom: false,
    typefaceName: 'SANS_SERIF',
  },
};
```

### Customize other player configurations

```tsx
// Customize other player configurations for video feed component
<VideoFeed
  style={{ height: 200 }}
  source="discover"
  // Configure player configuration for VideoFeed component
  videoPlayerConfiguration={{
    // Configure player style: full or fit
    playerStyle: 'fit',
    // Configure video complete action: advanceToNext or loop
    videoCompleteAction: 'advanceToNext',
    // Indicates if the video player shows share button
    showShareButton: true,
    // Indicates if the video player shows playback button
    showPlaybackButton: true,
    // Indicates if the video player shows mute button
    showMuteButton: true,
    // Specifies if the video detail title should be showed
    showVideoDetailTitle: true,
    // Enable vertical scroll for player
    scrollDirection: 'vertical',
    // Hide prev/next navigation arrow buttons
    isArrowButtonVisible: false,
    // Loop back to the first video when the feed reaches the end
    feedCompleteAction: 'loop',
  }}
/>;

// Customize other player configurations for story block component
<StoryBlock
  style={{ height: 200 }}
  source="discover"
  storyBlockConfiguration={{
    // Configure player style: full or fit
    playerStyle: 'fit',
    // Configure video complete action: advanceToNext or loop
    videoCompleteAction: 'advanceToNext',
    // Indicates if the video player shows share button
    showShareButton: true,
    // Indicates if the video player shows playback button
    showPlaybackButton: true,
    // Indicates if the video player shows mute button
    showMuteButton: true,
    // Specifies if the video detail title should be showed
    showVideoDetailTitle: true,
    // Enable vertical scroll for player
    scrollDirection: 'vertical',
    // Hide prev/next navigation arrow buttons for embedded mode
    isArrowButtonVisible: false,
    // Hide prev/next navigation arrow buttons for fullscreen mode
    isFullscreenArrowButtonVisible: false,
    // Loop back to the first video when the feed reaches the end
    // This property only applies to fullscreen mode
    feedCompleteAction: 'loop',
    // Additional controls inset for embedded mode
    // This adds extra margin/padding to controls in the embedded story block
    additionalControlsInset: {
      top: 20, 
      bottom: 30,
    },
  }}
/>;

// Customize other player configurations for openVideoPlayer API
FireworkSDK.getInstance().openVideoPlayer(url, {
  // Configure player style: full or fit
  playerStyle: 'fit',
  // Configure video complete action: advanceToNext or loop
  videoCompleteAction: 'advanceToNext',
  // Indicates if the video player shows share button
  showShareButton: true,
  // Indicates if the video player shows playback button
  showPlaybackButton: true,
  // Indicates if the video player shows mute button
  showMuteButton: true,
  // Specifies if the video detail title should be showed
  showVideoDetailTitle: true,
  // Enable vertical scroll for player
  scrollDirection: 'vertical',
  // Hide prev/next navigation arrow buttons
  isArrowButtonVisible: false,
  // Loop back to the first video when the feed reaches the end
  feedCompleteAction: 'loop',
});
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.firework.com/firework-for-developers/react-native-sdk/integration-guide-v2/customization-react-native/player-configurations-react-native.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
