Skip to content

Embedded Clips#

StorytellerEmbeddedClipsView lets you place the native Storyteller clips experience inline within your Flutter UI while keeping full control of layout, scrolling, and lifecycle.

Basic usage#

class InlineClips extends StatelessWidget {
  const InlineClips({super.key});

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      height: 420,
      child: StorytellerEmbeddedClipsView(
        collectionId: 'featured-highlights',
        shouldPlay: true,
        topLevelBack: false,
        onDataLoadStarted: () => debugPrint('Loading clips...'),
        onDataLoadComplete: (result) {
          debugPrint('Loaded ${result.totalClips} clips');
        },
      ),
    );
  }
}

Key parameters:

  • collectionId (required) – the Storyteller collection to play.
  • clipId – start playback at a specific clip.
  • initialCategory – open the embedded UI within a category.
  • shouldPlay – autoplay behaviour (defaults to true).
  • topLevelBack – whether to expose a back button for nested navigation.
  • theme – apply a StorytellerTheme override.
  • context – attach analytics context metadata.
  • topInset / bottomInset – provide safe area values in logical pixels. Available on Android only.

React to embedded callbacks#

Three callbacks surface native lifecycle events:

  • onDataLoadStarted() – when Storyteller begins loading collection data.
  • onDataLoadComplete(StorytellerEmbeddedClipsLoadResult result) – includes status and counts; inspect result.error when result.success is false.
  • onUserActivityOccurred(Map<String, dynamic> payload) – emits the same payloads you see on the global onUserActivityOccurred stream, scoped to this embedded instance.

Control playback programmatically#

Attach a StorytellerEmbeddedClipsController to pause/resume playback, reload data, or propagate inset changes after creation.

class ControllableEmbeddedClips extends StatefulWidget {
  const ControllableEmbeddedClips({super.key});

  @override
  State<ControllableEmbeddedClips> createState() =>
      _ControllableEmbeddedClipsState();
}

class _ControllableEmbeddedClipsState
    extends State<ControllableEmbeddedClips> {
  final _controller = StorytellerEmbeddedClipsController();

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Expanded(
          child: StorytellerEmbeddedClipsView(
            collectionId: 'live-stream',
            controller: _controller,
            shouldPlay: false,
          ),
        ),
        FilledButton(
          onPressed: () async {
            await _controller.setShouldPlay(true);
          },
          child: const Text('Play clips'),
        ),
      ],
    );
  }
}

Available controller actions:

  • reloadData() – refreshes the native data source.
  • goBack() / canGoBack() – traverse nested embedded navigation.
  • setShouldPlay(bool) – toggle playback.
  • updateInsets({int top, int bottom}) – sync safe areas when your layout changes.

If the controller receives a command before the platform view is ready, the SDK safely ignores it until the view attaches.