Skip to main content

Implement Caast player with Flutter

This tutorial purpose is to help you implement Caast via the use of a webview. You will implement listener throught the webview in order to apply your app behaviour based on Caast's emitted events.

Needed libraries

Implementation

1. Controller creation

Firstly, lets create a controller for our webview. This controller purpose will be to control the webview and transmit javascript commands.

final PlatformWebViewControllerCreationParams params =
WebViewPlatform.instance is WebKitWebViewPlatform
? WebKitWebViewControllerCreationParams(
allowsInlineMediaPlayback: true,
mediaTypesRequiringUserAction: const <PlaybackMediaTypes>{},
)
: const PlatformWebViewControllerCreationParams();

final WebViewController controller =
WebViewController.fromPlatformCreationParams(params);

await setNavigationDelegate();

if (controller.platform is AndroidWebViewController) {
if (kDebugMode) {
await AndroidWebViewController.enableDebugging(true);
}

await (controller.platform as AndroidWebViewController)
.setMediaPlaybackRequiresUserGesture(false);
}

2. Forward Caast event to Flutter

In order to get access to Caast's events in Flutter, we need to add a javascript listener which will forward all these events to Flutter.

await controller.runJavaScript('''
if (document.readyState !== 'complete' &&
document.querySelector('video') == null) {
window.$_javaScriptChannelName.postMessage(
JSON.stringify({
'type': 'onError',
'data': {
'message': 'No video element on screen.',
},
}),
);
}

window.caast.on('all', function (response) {
window.$_javaScriptChannelName.postMessage(
JSON.stringify(response),
);
});
''')`

3. Interact with forwarded events

Now that you can catch those events, we need to interact with them. To do so, we need to add a JavaScriptChannel to our webview.

In this JavaScriptChannel, you will be able to consume all those events and apply your custom logic.

You can find all the events on this page, there is also a section with the data related to each specific events here.

! All the forwarded data is in JSON, we need to parse it before being able to use it

await controller.addJavaScriptChannel(
'YourJavaScriptChannelName',
onMessageReceived: (JavaScriptMessage event) async {
try {
final Map<String, dynamic> payload = jsonDecode(event.message);

final String type = payload['type'];

switch (type) {
// Custom error from the player.
case 'onError':
throw Exception(payload['data']['message']);

// Called when the player is loading live products.
case 'onProductLoaded':
break;

// Called when clicking on the products menu button.
case 'onProductDetailsClick':
break;

// Called when clicking on a product.
case 'onProductDetailsShow':
break;

// Called when clicking in the product link before redirection.
case 'onProductOpen':
break;

default:
debugPrint('$type is not handled.');
}
} catch (error, stackTrace) {
debugPrint('Error: $error');
debugPrint('Stack trace: $stackTrace');
}
},
);