# Video Player Configuration(Android)

This guide covers player configuration options for all Firework video widgets. These options are set through `PlayerOption` in `ViewOptions` and control the video player's behavior, appearance, and features.

For a complete reference of all player options with detailed documentation, see [PlayerOption Configuration](https://docs.firework.com/firework-for-developers/android-sdk/integration-guide/configuration/player-options).

## Player Display

### Player Mode

Controls how video content is scaled and displayed within the player.

**Values:**

* `PlayerMode.FIT_MODE` - Video fits within bounds maintaining 9:16 aspect ratio, may have letterboxing
* `PlayerMode.FULL_BLEED_MODE` - Video fills the entire screen, may be cropped (default)

```kotlin
val viewOptions = viewOptions {
    playerOptions {
        playerMode(PlayerMode.FIT_MODE)
    }
}

val videoFeedView = findViewById<FwVideoFeedView>(R.id.videoFeedView)
videoFeedView.init(viewOptions)
```

### Scrolling Orientation

Controls the swipe direction for navigating between videos in the player.

**Values:**

* `ScrollingOrientation.HORIZONTAL` - Swipe left/right (default)
* `ScrollingOrientation.VERTICAL` - Swipe up/down

```kotlin
val viewOptions = viewOptions {
    playerOptions {
        scrollingOrientation(ScrollingOrientation.VERTICAL)
    }
}
```

## UI Element Visibility

### Firework Logo

Control whether the Firework logo is displayed in the player. Default is `true`.

```kotlin
val viewOptions = viewOptions {
    playerOptions {
        showFireworkLogo(false)
    }
}
```

### Custom Channel Logo

Configure custom logo display in the player using `LogoConfig`.

**Options:**

* `LogoConfig.NoLogo` - No logo shown
* `LogoConfig.Logo.AggregatorLogo(channelId, isClickable)` - Custom drawable logo from channel
* `LogoConfig.Logo.CreatorLogo(channelId, isClickable)` - Custom drawable logo from creator

```kotlin
val viewOptions = viewOptions {
    playerOptions {
        logoConfig(
            LogoConfig.Logo.AggregatorLogo(
                channelId = "your_encoded_channel_id",
                isClickable = true
            )
        )
    }
}
```

Set `isClickable = false` if you don't want the share menu to appear when clicking the logo.

### Share Button

Show or hide the share button. Default is `true`.

```kotlin
val viewOptions = viewOptions {
    playerOptions {
        showShareButton(true)
    }
}
```

### Mute Button

Show or hide the mute/unmute button. Default is `true`.

```kotlin
val viewOptions = viewOptions {
    playerOptions {
        showMuteButton(true)
    }
}
```

### Play/Pause Button in Videos

Show or hide the play/pause button for regular videos. Default is `true`.

```kotlin
val viewOptions = viewOptions {
    playerOptions {
        showPlayPauseButtonInVideo(true)
    }
}
```

### Play/Pause Button in Replays

Show or hide the play/pause button for livestream replays. Default is `true`.

```kotlin
val viewOptions = viewOptions {
    playerOptions {
        showPlayPauseButtonInReplay(true)
    }
}
```

### More Button

Show or hide the more options button. Default is `true`.

```kotlin
val viewOptions = viewOptions {
    playerOptions {
        showMoreButton(true)
    }
}
```

## Playback Behavior

### Autoplay

Enable autoplay for the first visible video in FwVideoFeedView. Default is `false`.

```kotlin
val viewOptions = viewOptions {
    playerOptions {
        autoplay(true)
    }
}
```

### Auto-Play Next Video

Automatically play the next video when the current video ends. When `true`, the player advances to the next video. When `false`, the current video loops. Default is `true`.

```kotlin
val viewOptions = viewOptions {
    playerOptions {
        autoPlayOnComplete(true)
    }
}
```

## Sharing

### Share Base URL

Configure a base URL for generating share links.

```kotlin
val viewOptions = viewOptions {
    playerOptions {
        shareBaseUrl("https://your-app.com/videos")
    }
}
```

### Custom Share URL Callback

Customize share URLs before sharing using a suspend callback.

```kotlin
val viewOptions = viewOptions {
    playerOptions {
        shareUrlCustomCallBack { url, videoInfo ->
            // Add custom parameters
            "$url?utm_source=app&video_id=${videoInfo.videoId}"
        }
    }
}
```

## CTA Configuration

### SDK Handle CTA Button Click

Control whether the SDK automatically handles CTA button clicks. Default is `true`.

When set to `false`, you must handle CTA clicks in your app using the `OnCtaButtonClickListener`.

```kotlin
val viewOptions = viewOptions {
    playerOptions {
        sdkHandleCtaButtonClick(false)
    }
}

// Set your CTA click listener
FireworkSdk.shopping.setOnCtaButtonClickListener { url, videoInfo ->
    // Handle CTA click
}
```

### CTA Button Visibility Delay

Control when the CTA button becomes visible during video playback.

**Delay Units:**

* `CtaDelayUnit.SECONDS` - Delay in seconds (0.0f - 10.0f, default: 3 seconds)
* `CtaDelayUnit.PERCENTAGE` - Delay as percentage of video duration (0.0f - 1.0f, default: 0.2f or 20%)

```kotlin
val viewOptions = viewOptions {
    ctaOptions {
        ctaDelay(CtaDelay(2.0f, CtaDelayUnit.SECONDS))
    }
}
```

**Example with percentage:**

```kotlin
val viewOptions = viewOptions {
    ctaOptions {
        ctaDelay(CtaDelay(0.5f, CtaDelayUnit.PERCENTAGE)) // Show at 50% of video
    }
}
```

### CTA Button Highlight Delay

Control when the CTA button becomes highlighted after it appears.

```kotlin
val viewOptions = viewOptions {
    ctaOptions {
        ctaHighlightDelay(CtaDelay(2.0f, CtaDelayUnit.SECONDS))
    }
}
```

### Custom CTA Button Styling

Override `FwCtaButtonViewStyle` in your app's theme to customize CTA button appearance:

```xml
<resources>
    <style name="FwCtaButtonViewStyle">
        <item name="android:backgroundTint">@color/customBackgroundColor</item>
        <item name="android:textColor">@color/customTextColor</item>
        <item name="android:fontFamily">@font/customFont</item>
    </style>
</resources>
```

For rounded corners and shape customization:

```xml
<resources>
    <style name="FwCtaButtonViewStyle">
        <item name="shapeAppearanceOverlay">@style/MyCustomCtaButtonShapeStyle</item>
    </style>
    
    <style name="MyCustomCtaButtonShapeStyle">
        <item name="cornerFamily">rounded</item>
        <item name="cornerSizeTopLeft">6dp</item>
        <item name="cornerSizeBottomLeft">6dp</item>
        <item name="cornerSizeBottomRight">6dp</item>
        <item name="cornerSizeTopRight">6dp</item>
    </style>
</resources>
```

## Picture-in-Picture (PIP)

### Enable PIP Mode

Enable Picture-in-Picture mode. Default is `false`.

```kotlin
val viewOptions = viewOptions {
    playerOptions {
        enablePipMode(true)
    }
}
```

### Enter PIP Programmatically

```kotlin
FireworkSdk.enterPip { success ->
    // true if entering PIP was successful
}
```

### Close PIP

```kotlin
FireworkSdk.closePip()
```

### PIP Cleanup on Activity Destroy

In Android 11+, removing the app's task from the task manager doesn't kill the player in PIP mode. Close PIP in your Activity's `onDestroy`:

```kotlin
override fun onDestroy() {
    FireworkSdk.closePip()
    super.onDestroy()
}
```

## Subtitles and Captions

### Show Subtitles

Show or hide video subtitles. Default is `true`.

```kotlin
val viewOptions = viewOptions {
    playerOptions {
        showSubtitle(true)
    }
}
```

### Show Captions

Show or hide video captions. Default is `true`.

```kotlin
val viewOptions = viewOptions {
    playerOptions {
        showCaption(true)
    }
}
```

### Subtitle Text Color

Customize the text color for subtitles. Default is white (`0xFFFFFFFF`).

```kotlin
val viewOptions = viewOptions {
    playerOptions {
        subtitleTextColor(0xFFFFFFFF.toInt())
    }
}
```

### Subtitle Background Color

Customize the background color for subtitles. Default is semi-transparent black (`0x66121212`).

```kotlin
val viewOptions = viewOptions {
    playerOptions {
        subtitleBackgroundColor(0x66121212.toInt())
    }
}
```

### Reverse Audio Controls Order

Rearrange the order of mute/unmute button and closed captions button. Default is `false`.

When `true`, the closed captions button appears to the right of the mute/unmute button. When `false`, the closed captions button appears to the left of the mute/unmute button.

```kotlin
val viewOptions = viewOptions {
    playerOptions {
        reverseAudioControls(false)
    }
}
```

## Livestream Features

### Livestream Countdown

Display a countdown timer before livestream starts (over trailer video). Users can set reminders for the livestream.

```kotlin
val viewOptions = viewOptions {
    playerOptions {
        livestreamCountDownOption(
            LivestreamCountDownOption.Builder()
                .isHidden(false)
                .theme(Theme.DARK)
                .build()
        )
    }
}
```

## Immersive Mode

Enable immersive fullscreen mode that hides system UI (navigation bars, status bar). Default is `false`.

```kotlin
val viewOptions = viewOptions {
    playerOptions {
        enableImmersiveMode(true)
    }
}
```

## Advanced UI Configuration

### Player UI Options

Configure advanced player UI elements including custom icons and detailed options.

```kotlin
val customIcon = WidgetImage(
    drawableRes = R.drawable.ic_custom,
    tintColor = Color.WHITE
)

val viewOptions = viewOptions {
    playerOptions {
        playerUiOption(
            PlayerUiOption.Builder()
                .videoDetailsOption(
                    VideoDetailsOption.Builder()
                        .showCaption(true)
                        .buttonIcon(customIcon)
                        .build()
                )
                .closeButtonOption(
                    CloseButtonOption.Builder()
                        .icon(customIcon)
                        .shouldShowWhenPiPEnabled(false)
                        .build()
                )
                .pipButtonOption(
                    PipButtonOption.Builder()
                        .icon(customIcon)
                        .build()
                )
                .muteButtonOption(
                    MuteButtonOption.Builder()
                        .muteIcon(customIcon)
                        .unmuteIcon(customIcon)
                        .build()
                )
                .playbackButtonOption(
                    PlaybackButtonOption.Builder()
                        .playIcon(customIcon)
                        .pauseIcon(customIcon)
                        .build()
                )
                .build()
        )
    }
}
```

**Customizable Icons:**

* **Player detail button (More Button)** - Three dots on top left showing details/share
* **Mute button** - Icon for muted state
* **Unmute button** - Icon for unmuted state
* **Close button** - Icon on top right to close player
* **Play button** - Icon for paused state (center of player)
* **Pause button** - Icon for playing state (when WCAG Talkback is on)
* **PIP button** - Icon for Picture-in-Picture mode

### Action Buttons

Add custom action buttons to the player.

```kotlin
val viewOptions = viewOptions {
    playerOptions {
        actionButtonOption(
            ActionButtonOption.Builder()
                .addActionButton(
                    ActionButton(
                        icon = R.drawable.ic_custom_action,
                        action = { videoInfo ->
                            // Handle custom action
                            Log.d("Player", "Custom action for video: ${videoInfo.videoId}")
                        }
                    )
                )
                .build()
        )
    }
}
```

## Complete Configuration Example

```kotlin
class VideoPlayerActivity : AppCompatActivity() {
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_video_player)
        
        val customIcon = WidgetImage(
            drawableRes = R.drawable.ic_custom_close,
            tintColor = Color.WHITE
        )
        
        val viewOptions = viewOptions {
            baseOptions {
                feedResource(FeedResource.Discovery)
            }
            playerOptions {
                // Display
                playerMode(PlayerMode.FULL_BLEED_MODE)
                scrollingOrientation(ScrollingOrientation.VERTICAL)
                
                // UI Elements
                showFireworkLogo(false)
                showShareButton(true)
                showMuteButton(true)
                showPlayPauseButtonInVideo(true)
                showMoreButton(true)
                
                // Playback
                autoplay(true)
                autoPlayOnComplete(true)
                
                // Sharing
                shareBaseUrl("https://your-app.com/videos")
                shareUrlCustomCallBack { url, videoInfo ->
                    "$url?utm_source=app&video_id=${videoInfo.videoId}"
                }
                
                // CTA
                sdkHandleCtaButtonClick(true)
                
                // PIP
                enablePipMode(true)
                
                // Subtitles
                showSubtitle(true)
                showCaption(true)
                subtitleTextColor(0xFFFFFFFF.toInt())
                subtitleBackgroundColor(0x66121212.toInt())
                reverseAudioControls(false)
                
                // Livestream
                livestreamCountDownOption(
                    LivestreamCountDownOption.Builder()
                        .isHidden(false)
                        .theme(Theme.DARK)
                        .build()
                )
                
                // Immersive Mode
                enableImmersiveMode(true)
                
                // Custom UI
                playerUiOption(
                    PlayerUiOption.Builder()
                        .closeButtonOption(
                            CloseButtonOption.Builder()
                                .icon(customIcon)
                                .build()
                        )
                        .build()
                )
            }
            ctaOptions {
                ctaDelay(CtaDelay(3.0f, CtaDelayUnit.SECONDS))
                ctaHighlightDelay(CtaDelay(2.0f, CtaDelayUnit.SECONDS))
            }
        }
        
        val videoFeedView = findViewById<FwVideoFeedView>(R.id.videoFeedView)
        videoFeedView.init(viewOptions)
    }
    
    override fun onDestroy() {
        FireworkSdk.closePip()
        super.onDestroy()
    }
}
```

## See Also

* [PlayerOption Reference](https://docs.firework.com/firework-for-developers/android-sdk/integration-guide/configuration/player-options) - Complete player options documentation
* [ViewOptions Overview](https://docs.firework.com/firework-for-developers/android-sdk/integration-guide/configuration) - All configuration options
* [Shopping Integration](https://docs.firework.com/firework-for-developers/android-sdk/integration-guide/shoppable-videos) - CTA handling and shopping features
* [Livestream Integration](https://docs.firework.com/firework-for-developers/android-sdk/integration-guide/livestream) - Livestream features and callbacks
* [Widgets Overview](https://docs.firework.com/firework-for-developers/android-sdk/integration-guide/widgets) - All available widgets
