Hi @Hari_Krishnan,
Thank you for your patience while we investigated this. Vega OS does support rendering a transparent WebView on top of video playback, which is exactly the pattern you need for overlaying UI controls over KeplerVideoSurfaceView.
How It Works
The approach is to layer a WebView (from @amazon-devices/webview) as a sibling on top of KeplerVideoSurfaceView, with the WebView set to a fully transparent background. The video shows through the transparent WebView, while your HTML-based controls render on top.
Steps to Implement
- Update your Metro config - Add
'html' to the assetExts resolver so Metro can bundle local HTML files as assets:
const defaultConfig = getDefaultConfig(__dirname);
const config = {
resolver: {
assetExts: defaultConfig.resolver.assetExts.includes('html')
? defaultConfig.resolver.assetExts
: [...defaultConfig.resolver.assetExts, 'html'],
},
};
module.exports = mergeConfig(defaultConfig, config);
- Load your HTML overlay as an asset source - Use
Image.resolveAssetSource to resolve the local HTML file:
import {Image} from 'react-native';
const overlaySource = {
uri: Image.resolveAssetSource(require('../assets/player-overlay.html')).uri,
};
- Layer the components - Place
KeplerVideoView and a transparent WebView container as siblings inside the same parent View:
<View style={styles.container}>
{useKeplerVideoView ? (
<KeplerVideoView style={styles.backgroundVideo} videoPlayer={video.current} />
) : null}
<View style={styles.modalContainer}>
<WebView
ref={webRef}
source={overlaySource}
style={styles.overlayWebView}
onMessage={handleTransportMessage}
onLoadStart={() => setIsWebViewReady(false)}
onLoad={() => setIsWebViewReady(true)}
/>
</View>
</View>
- Key styles - The WebView and its container must both have transparent backgrounds:
const styles = StyleSheet.create({
container: { flex: 1 },
overlayWebView: {
flex: 1,
backgroundColor: 'rgb(0,0,0, 0)',
},
modalContainer: {
flex: 1,
backgroundColor: 'rgba(0, 0, 0, 0)',
position: 'absolute',
top: 0,
left: 0,
width: 1920,
height: 1080,
},
});
-
Handle TV remote input - Use useTVEventHandler from @amazon-devices/react-native-kepler to capture remote control events (e.g., the select button) and forward them into the WebView via injectJavaScript.
-
Bidirectional communication - Your HTML overlay should send messages back to React Native using window.ReactNativeWebView.postMessage(...), and your React Native side should handle them via the WebView’s onMessage prop. To push state updates into the WebView, use webRef.current.injectJavaScript(...).
-
Track WebView readiness - Gate all injectJavaScript calls behind an isWebViewReady state flag (set to true in onLoad, false in onLoadStart) to avoid calling into the WebView before it’s ready.
-
Create your own HTML overlay page - Your HTML file should set background: transparent on both html and body elements. Only your actual control elements (buttons, text) should have visible styling. The HTML should expose functions that React Native can call via injectJavaScript and use postMessage to send user actions back.
This requires @amazon-devices/webview for the WebView component
This requires @amazon-devices/react-native-kepler for useTVEventHandler
Note: The code example uses KeplerVideoView (from @amazon-devices/react-native-w3cmedia), which is the component used for video rendering.
Let us know if you have any further questions!
Warm regards,
Aishwarya