import React, {useRef, useState} from 'react'; import { Alert, ScrollView, StatusBar, View, Text, StyleSheet, TouchableOpacity, Platform, } from 'react-native'; import {useSafeAreaInsets} from 'react-native-safe-area-context'; import JWPlayer, {JWPlayerConfig} from '@jwplayer/jwplayer-react-native'; import PlayerContainer from '../components/PlayerContainer'; import {IOS_API_KEY, ANDROID_API_KEY} from '@env'; /** * TypeScript Example Screen * * Demonstrates the unified configuration types with: * - Full TypeScript type safety * - Cross-platform IMA DAI configuration * - Platform-specific feature examples */ const licenseKey = Platform.OS === 'android' ? ANDROID_API_KEY || '' : IOS_API_KEY || ''; // Example 1: Basic video with IMA DAI (VOD) const basicDAIConfig: JWPlayerConfig = { license: licenseKey, autostart: true, playlist: [ { title: 'IMA DAI VOD Stream', file: 'http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8', image: 'https://cdn.jwplayer.com/thumbs/demo-live.jpg', description: 'VOD Stream with Dynamic Ad Insertion', ...(Platform.OS === 'ios' ? { daiSetting: { videoID: 'tears-of-steel', cmsID: '2528370', }, } : { imaDaiSettings: { videoId: 'tears-of-steel', cmsId: '2528370', streamType: 'hls', }, }), }, ], advertising: { client: Platform.OS === 'ios' ? 'GoogleIMADAI' : 'IMA_DAI', }, }; // Example 2: IMA DAI Live Stream const liveDAIConfig: JWPlayerConfig = { license: licenseKey, autostart: true, playlist: [ { title: 'DAI - BB Bunny (Live) HLS - BipBop fallback', file: 'http://playertest.longtailvideo.com/adaptive/bipbop/gear4/prog_index.m3u8', description: "This stream contains variables in it's Ad Tag.", ...(Platform.OS === 'ios' ? { daiSetting: { assetKey: 'c-rArva4ShKVIAkNfy6HUQ', }, } : { imaDaiSettings: { assetKey: 'c-rArva4ShKVIAkNfy6HUQ', }, }), }, ], }; // Example 3: VAST ads with schedule const vastConfig: JWPlayerConfig = { license: licenseKey, autostart: true, playlist: [ { title: 'Video with VAST Ads', file: 'https://content.bitsontherun.com/videos/q1fx20VZ-52qL9xLP.mp4', image: 'https://cdn.jwplayer.com/thumbs/q1fx20VZ-480.jpg', }, ], advertising: { client: 'vast', schedule: [ { offset: 'pre', tag: 'https://pubads.g.doubleclick.net/gampad/ads?sz=640x480&iu=/124319096/external/single_ad_samples&ciu_szs=300x250&impl=s&gdfp_req=1&env=vp&output=vast&unviewed_position_start=1&cust_params=deployment%3Ddevsite%26sample_ct%3Dlinear&correlator=', }, ], skipoffset: 5, }, }; // Example 4: Google IMA with inline ad const imaConfig: JWPlayerConfig = { license: licenseKey, autostart: true, playlist: [ { title: 'Single Inline Linear Preroll', file: 'https://content.bitsontherun.com/videos/q1fx20VZ-52qL9xLP.mp4', adschedule: { adBreak1: { offset: 'pre', ad: { source: 'googima', tag: 'https://pubads.g.doubleclick.net/gampad/ads?sz=640x480&iu=/124319096/external/single_ad_samples&ciu_szs=300x250&impl=s&gdfp_req=1&env=vp&output=vast&unviewed_position_start=1&cust_params=deployment%3Ddevsite%26sample_ct%3Dlinear&correlator=', }, }, }, }, ], advertising: { client: 'googima', }, }; // Example 5: Platform-specific configuration const platformSpecificConfig: JWPlayerConfig = { license: licenseKey, file: 'http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8', autostart: true, // iOS-specific features (with @platform ios annotation in types) ...(Platform.OS === 'ios' && { styling: { colors: { buttons: '#FF0000', backgroundColor: '#000000', fontColor: '#FFFFFF', }, showTitle: true, showDesc: true, }, backgroundAudioEnabled: true, category: 'Playback', categoryOptions: ['MixWithOthers', 'DuckOthers'], }), // Android-specific features (with @platform android annotation in types) ...(Platform.OS === 'android' && { uiConfig: { hasOverlay: true, hasControlbar: true, hasCenterControls: true, hasNextUp: true, hasQualitySubMenu: true, hasCaptionsSubMenu: true, hasPlaybackRatesSubMenu: true, hasMenu: true, hasAds: true, }, useTextureView: true, }), }; const TypeScriptExample: React.FC = () => { const playerRef = useRef(null); const [selectedConfig, setSelectedConfig] = useState( null, ); const [configName, setConfigName] = useState(''); const insets = useSafeAreaInsets(); const onTime = (_e: any) => { // const { position, duration } = _e.nativeEvent; // console.log('onTime:', position, duration); }; const onFullScreen = () => { StatusBar.setHidden(true); }; const onFullScreenExit = () => { StatusBar.setHidden(false); }; const onPlayerReady = () => { console.log('Player is ready!'); }; const onPlayerError = (error: any) => { console.error('Player error:', error); Alert.alert('Player Error', JSON.stringify(error.nativeEvent)); }; const selectConfig = (config: JWPlayerConfig, name: string) => { setSelectedConfig(config); setConfigName(name); }; const resetSelection = () => { setSelectedConfig(null); setConfigName(''); }; // Show config selection screen if no config is selected if (!selectedConfig) { return ( Select a Configuration to Test Choose one of the configurations below to load the player with full TypeScript type safety selectConfig(basicDAIConfig, 'IMA DAI VOD')}> IMA DAI VOD Video on Demand with Google Dynamic Ad Insertion • Uses unified imaDaiSettings{'\n'}• Cross-platform compatible {'\n'}• VideoId + CmsId configuration selectConfig(liveDAIConfig, 'IMA DAI Live')}> IMA DAI Live Live stream with Google Dynamic Ad Insertion • Uses assetKey for live streams{'\n'}• Real-time ad insertion {'\n'}• Cross-platform compatible selectConfig(vastConfig, 'VAST Ads')}> VAST Ads VAST ads with preroll schedule • VAST ad schedule{'\n'}• Preroll configuration{'\n'}• Skip after 5 seconds selectConfig(imaConfig, 'Google IMA')}> Google IMA Google IMA inline preroll ad • Google IMA SDK{'\n'}• Single preroll ad{'\n'}• Ad schedule configuration selectConfig(platformSpecificConfig, 'Platform Specific') }> Platform Specific ({Platform.OS}) Demonstrates platform-specific features {Platform.OS === 'ios' ? '• iOS styling configuration\n• Background audio support\n• Audio session management' : '• Android UI configuration\n• TextureView support\n• Granular UI control'} ); } // Show player with selected config return ( } text={`TypeScript Example - ${configName}`} /> Configuration: {configName} Using unified JWPlayerConfig types Change Config ); }; const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#000', }, player: { flex: 1, }, selectionContainer: { flex: 1, padding: 20, backgroundColor: '#1a1a1a', }, title: { color: '#fff', fontSize: 24, fontWeight: 'bold', marginBottom: 10, textAlign: 'center', }, subtitle: { color: '#999', fontSize: 14, marginBottom: 25, textAlign: 'center', lineHeight: 20, }, configList: { flex: 1, }, configCard: { backgroundColor: '#2a2a2a', padding: 15, marginBottom: 15, borderRadius: 12, borderWidth: 1, borderColor: '#444', }, configTitle: { color: '#fff', fontSize: 18, fontWeight: 'bold', marginBottom: 8, }, configDescription: { color: '#ccc', fontSize: 14, marginBottom: 10, lineHeight: 18, }, configDetails: { color: '#999', fontSize: 12, lineHeight: 18, marginTop: 5, }, infoBar: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', backgroundColor: '#1a1a1a', paddingVertical: 15, paddingHorizontal: 20, borderTopWidth: 1, borderTopColor: '#333', }, infoContent: { flex: 1, }, infoText: { color: '#fff', fontSize: 14, fontWeight: '600', marginBottom: 3, }, infoSubtext: { color: '#999', fontSize: 11, fontStyle: 'italic', }, resetButton: { backgroundColor: '#007AFF', paddingVertical: 8, paddingHorizontal: 16, borderRadius: 8, marginLeft: 10, }, resetButtonText: { color: '#fff', fontSize: 13, fontWeight: '600', }, }); export default TypeScriptExample;