Video Feed

Currently, there are eight source types of the video feed:

  • Discover

  • Channel

  • Playlist

  • Playlist Group(Only supported on iOS)

  • Dynamic Content

  • Hashtag Playlist

  • SKU

  • Single Content

Integration

import 'package:fw_flutter_sdk/fw_flutter_sdk.dart';

/// discover
VideoFeed(
  height: 200,
  source: VideoFeedSource.discover,
);

/// channel
VideoFeed(
  height: 200,
  source: VideoFeedSource.channel,
  channel: "your encoded channel id",
);

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


/// playlist group
VideoFeed(
  height: 200,
  source: VideoFeedSource.playlistGroup,
  playlistGroup: "your encoded playlist group id",
);

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

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

/// sku playlist
VideoFeed(
  height: 200,
  source: VideoFeedSource.sku,
  channel: "your encoded channel id",
  productIds: ["prodct_id_1", "prodct_id_2"],
);

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

Please refer to the Encoded IDs help article to learn about how to find your encoded channel ID, playlist ID, playlist Group ID

Mode

VideoFeed widget supports three modes: row, column, and grid.

Use grid mode:

Column(
  crossAxisAlignment: CrossAxisAlignment.stretch,
  children: [
    Expanded(
      child: VideoFeed(
        source: VideoFeedSource.discover,
        mode: VideoFeedMode.grid,
      ),
    )
  ],
);

Video feed configuration

VideoFeed widget provides videoFeedConfiguration property for configuring Video Feed. The current configurable are backgroundColor, cornerRadius, and titlePosition etc. Please refer to VideoFeedConfiguration for more details.

final videoFeedConfiguration = VideoFeedConfiguration();
videoFeedConfiguration.title = VideoFeedTitleConfiguration();
videoFeedConfiguration.title?.hidden = false;
videoFeedConfiguration.titlePosition = VideoFeedTitlePosition.nested;
videoFeedConfiguration.cornerRadius = 10;
videoFeedConfiguration.itemSpacing = 10;
VideoFeed(
  source: VideoFeedSource.discover,
  videoFeedConfiguration: videoFeedConfiguration,
);

Video player configuration

VideoFeed widget provides videoPlayerConfiguration property for configuring Video Player. The current configurable properties are playerStyle, videoCompleteAction, and ctaButtonStyle etc. Please refer to VideoPlayerConfiguration for more details.

final videoPlayerConfiguration = VideoPlayerConfiguration();
videoPlayerConfiguration.playerStyle = VideoPlayerStyle.full;
videoPlayerConfiguration.videoCompleteAction = VideoPlayerCompleteAction.advanceToNext;
videoPlayerConfiguration.showShareButton = true;
videoPlayerConfiguration.showMuteButton = true;
videoPlayerConfiguration.showPlaybackButton = true;

VideoFeed(
  source: VideoFeedSource.discover,
  videoPlayerConfiguration: videoPlayerConfiguration,
);

Video feed loading result callback

VideoFeed widget provides onVideoFeedLoadFinished property for setting video feed loading result callback.

VideoFeed(
  source: VideoFeedSource.discover,
  onVideoFeedLoadFinished: (error) {},
);

Video empty callback

VideoFeed widget provides onVideoFeedEmpty property for setting video feed empty callback. The callback is triggered when there are no items in the video feed. 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

VideoFeed(
  source: VideoFeedSource.discover,
  onVideoFeedEmpty: (error) {
    // Hide the widget
  },
);

Force refreshing video feed

VideoFeedController? _feedController;

VideoFeed(
  source: VideoFeedSource.discover,
  onVideoFeedCreated: (controller) {
    _feedController = controller;
  },
);

//force refreshing video feed
_feedController?.refresh();

Enable PiP(Picture in Picture)

You need to set enablePictureInPicture to true to enable PiP.

VideoFeed(
  height: 200,
  source: VideoFeedSource.discover,
  enablePictureInPicture: true,
);

Set up the iOS project

To enable PiP outside the iOS app, you also need to add Background Modes capability via Signing & Capabilities in your iOS project settings. More information about this can be found here: Apple Documentation

To use Picture in Picture, we configure the app to support background audio playback. See Configuring the Audio Playback of iOS and tvOS Apps for more details.

As the following screenshot, we should select "Audio, AirPlay, and Picture in Picture".

Keep alive when scrolling the widget out of the view box

Generally, if you put the video feed 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 video feed widget keep alive when scrolling the widget out of the view box.

VideoFeed(
  height: 200,
  source: VideoFeedSource.discover,
  // Keep the widget alive when scrolling the widget out of the view box
  wantKeepAlive: true,
);

onVideoFeedClick

The callback is triggered when users click the video feed item. The event type is VideoFeedClickEvent.

FireworkSDK.getInstance().onVideoFeedClick = (event) {};

onCustomCTAClick

The callback is triggered when users click the CTA button on the video in the video player. We start the floating player in the following sample codes. The event type is CustomCTAClickEvent.

FireworkSDK.getInstance().onCustomCTAClick =
    (CustomCTAClickEvent? event) async {
  final result =
      await FireworkSDK.getInstance().navigator.startFloatingPlayer();
  if (!result) {
    // When the result is false, the current fullscreen player may not
    // enable the floating player. In that case, we could call the
    // following method to close the fullscreen player.
    await FireworkSDK.getInstance().navigator.popNativeContainer();
  }
  
  // If the context is available, you could also call
  // Navigator.of(context).pushNamed to push the Flutter link content page.
  globalNavigatorKey.currentState?.pushNamed('/link_content', arguments: {
    "url": event?.url ?? '',
  });
};

Reference

VideoFeed

Last updated