> For the complete documentation index, see [llms.txt](https://docs.firework.com/firework-for-developers/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.firework.com/firework-for-developers/flutter-sdk/integration-guide-v2/player-deck.md).

# Player Deck (Flutter) -Beta

The `PlayerDeck` widget displays a horizontally scrollable row of video thumbnails with inline playback and product cards. Currently, there are seven source types of the player deck:

* Discover
* Channel
* Playlist
* Dynamic Content
* Hashtag Playlist
* SKU
* Single Content

## Integration

```dart
import 'package:fw_flutter_sdk/fw_flutter_sdk.dart';

/// discover
PlayerDeck(
  height: 481,
  source: VideoFeedSource.discover,
);

/// channel
PlayerDeck(
  height: 481,
  source: VideoFeedSource.channel,
  channel: "your encoded channel id",
);

/// playlist
PlayerDeck(
  height: 481,
  source: VideoFeedSource.playlist,
  channel: "your encoded channel id",
  playlist: "your encoded playlist id",
);

/// dynamic content
PlayerDeck(
  height: 481,
  source: VideoFeedSource.dynamicContent,
  dynamicContentParameters: const {
    '<cohort key>': ['<cohort value1>', '<cohort value2>']
  },
);

/// hashtag playlist
PlayerDeck(
  height: 481,
  source: VideoFeedSource.hashtagPlaylist,
  channel: "your encoded channel id",
  hashtagFilterExpression: "<hashtag filter expression>",
);

/// sku playlist
PlayerDeck(
  height: 481,
  source: VideoFeedSource.sku,
  channel: "your encoded channel id",
  productIds: ["product_id_1", "product_id_2"],
);

/// single content
PlayerDeck(
  height: 481,
  source: VideoFeedSource.singleContent,
  contentId: "your encoded video or live stream id",
);
```

{% hint style="info" %}
Please refer to the [Encoded IDs](/firework-for-developers/additional-resources/encoded-ids.md) help article to learn about how to find your encoded channel ID and playlist ID
{% endhint %}

### Player deck loading result callback

`PlayerDeck` widget provides `onPlayerDeckLoadFinished` property for setting player deck loading result callback.

```dart
PlayerDeck(
  height: 481,
  source: VideoFeedSource.discover,
  onPlayerDeckLoadFinished: (error) {
    if (error != null) {
      // Handle the loading error
    }
  },
);
```

### Empty callback

`PlayerDeck` widget provides `onPlayerDeckEmpty` property for setting player deck empty callback. The callback is triggered when there are no items in the player deck. For example, you could hide the widget when the callback is triggered. The callback is triggered in the following scenarios:

1. Load successfully but the back end returns an empty list
2. The load failed and the list is empty

```dart
PlayerDeck(
  height: 481,
  source: VideoFeedSource.discover,
  onPlayerDeckEmpty: (error) {
    // Hide the widget
  },
);
```

### Force refreshing player deck

```dart
PlayerDeckController? _playerDeckController;

PlayerDeck(
  height: 481,
  source: VideoFeedSource.discover,
  onPlayerDeckCreated: (controller) {
    _playerDeckController = controller;
  },
);

// Force refreshing player deck
_playerDeckController?.refresh();
```

### Get feed id

`PlayerDeck` widget provides `onPlayerDeckGetFeedId` property for getting the feed id.

```dart
PlayerDeck(
  height: 481,
  source: VideoFeedSource.discover,
  onPlayerDeckGetFeedId: (feedId) {
    // Use feedId
  },
);
```

### 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. 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)

#### Set enablePictureInPicture to true on Dart side

```dart
PlayerDeck(
  height: 481,
  source: VideoFeedSource.discover,
  enablePictureInPicture: true,
  onPlayerDeckDidStartPictureInPicture: (error) {
    // Handle PiP start result
  },
  onPlayerDeckDidStopPictureInPicture: (error) {
    // Handle PiP stop result
  },
);
```

### Keep alive when scrolling the widget out of the view box

Generally, if you put the player deck widget as the child of ListView, it will be rebuilt when scrolling the widget out of the view box. You could set `wantKeepAlive` as `true` to make the player deck widget keep alive when scrolling the widget out of the view box.

```dart
PlayerDeck(
  height: 481,
  source: VideoFeedSource.discover,
  // Keep the widget alive when scrolling the widget out of the view box
  wantKeepAlive: true,
);
```

### Player deck configurations

Please refer to [Player deck configurations (Flutter)](/firework-for-developers/flutter-sdk/integration-guide-v2/customization/player-deck-configurations-flutter.md).

### Player configurations

Please refer to [Player configurations (Flutter)](/firework-for-developers/flutter-sdk/integration-guide-v2/customization/player-configurations-flutter.md).

## Reference

[PlayerDeck](https://eng.firework.com/fw_flutter_sdk/v2/fw_flutter_sdk/PlayerDeck-class.html)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://docs.firework.com/firework-for-developers/flutter-sdk/integration-guide-v2/player-deck.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
