UNPKG

unified-video-framework

Version:

Cross-platform video player framework supporting iOS, Android, Web, Smart TVs (Samsung/LG), Roku, and more

302 lines (264 loc) 7.63 kB
import React, { useRef } from 'react'; import { PortraitPlayerView } from '../PortraitPlayerView'; /** * URL Routing Example for Portrait Player * * This demonstrates YouTube Shorts-style URL routing where: * - Scrolling updates the URL without page reload * - Browser back/forward buttons work seamlessly * - Direct URL access loads the specific video * - No page refreshes occur during navigation */ // Example video data const sampleVideos = [ { id: 'gP6Lqo9WUNk', url: 'https://example.com/video1.mp4', posterUrl: 'https://example.com/poster1.jpg', title: 'Amazing Nature Scene', description: 'Beautiful footage of nature #nature #wildlife', hashtags: ['nature', 'wildlife', 'beautiful'], creator: { name: 'Nature Channel', avatar: 'https://example.com/avatar1.jpg', verified: true, followers: 125000, }, likes: 12500, comments: 342, shares: 89, views: 250000, }, { id: 'xYz123AbCd', url: 'https://example.com/video2.mp4', posterUrl: 'https://example.com/poster2.jpg', title: 'Cooking Tutorial', description: 'Quick and easy recipe #cooking #food', hashtags: ['cooking', 'food', 'recipe'], creator: { name: 'Chef Master', avatar: 'https://example.com/avatar2.jpg', verified: true, followers: 89000, }, likes: 8900, comments: 234, shares: 56, views: 180000, }, { id: 'qWe456RtY', url: 'https://example.com/video3.mp4', posterUrl: 'https://example.com/poster3.jpg', title: 'Dance Performance', description: 'Epic dance moves #dance #performance', hashtags: ['dance', 'performance', 'talent'], creator: { name: 'Dance Studio', avatar: 'https://example.com/avatar3.jpg', verified: false, followers: 45000, }, likes: 15000, comments: 567, shares: 123, views: 320000, }, ]; /** * Example 1: Path-based routing (like YouTube Shorts) * URL: /shorts/gP6Lqo9WUNk */ export const PathBasedRoutingExample = () => { const playerRef = useRef(null); return ( <PortraitPlayerView videos={sampleVideos} playerRef={playerRef} // Enable URL routing enableUrlRouting={true} urlPattern="path" baseUrl="/shorts" // Optional: Custom URL generator getVideoUrl={(video) => `/shorts/${video.id}`} // Optional: Start with specific video from URL initialVideoId={undefined} // Auto-detects from URL onVideoChange={(index, video) => { console.log('Video changed:', video.id); // URL is automatically updated! }} onLike={(video) => console.log('Liked:', video.id)} onComment={(video) => console.log('Comment on:', video.id)} onShare={(video) => { const url = `${window.location.origin}/shorts/${video.id}`; navigator.clipboard.writeText(url); alert(`Link copied: ${url}`); }} /> ); }; /** * Example 2: Hash-based routing (for single-page apps) * URL: #/video/gP6Lqo9WUNk */ export const HashBasedRoutingExample = () => { const playerRef = useRef(null); return ( <PortraitPlayerView videos={sampleVideos} playerRef={playerRef} // Enable hash-based routing enableUrlRouting={true} urlPattern="hash" baseUrl="/video" onVideoChange={(index, video) => { console.log('Current video:', video.id); console.log('Current URL:', window.location.hash); }} /> ); }; /** * Example 3: Custom URL format * URL: /watch/gP6Lqo9WUNk?mode=portrait */ export const CustomUrlFormatExample = () => { const playerRef = useRef(null); return ( <PortraitPlayerView videos={sampleVideos} playerRef={playerRef} enableUrlRouting={true} urlPattern="path" baseUrl="/watch" // Custom URL generator with query params getVideoUrl={(video) => `/watch/${video.id}?mode=portrait`} onVideoChange={(index, video) => { // Update page title for better SEO document.title = `${video.title || 'Video'} - Portrait Player`; }} /> ); }; /** * Example 4: Without URL routing (default behavior) */ export const NoRoutingExample = () => { return ( <PortraitPlayerView videos={sampleVideos} // enableUrlRouting is false by default onVideoChange={(index, video) => { console.log('Video changed (no URL update):', video.id); }} /> ); }; /** * Example 5: Server-side rendering with hydration */ export const SSRExample = ({ videoId }) => { const playerRef = useRef(null); return ( <PortraitPlayerView videos={sampleVideos} playerRef={playerRef} enableUrlRouting={true} urlPattern="path" baseUrl="/shorts" // Start with specific video for SSR initialVideoId={videoId} onVideoChange={(index, video) => { console.log('Hydrated and changed:', video.id); }} /> ); }; /** * Example 6: Programmatic navigation with URL sync */ export const ProgrammaticNavigationExample = () => { const playerRef = useRef(null); const navigateToVideo = (videoId) => { const index = sampleVideos.findIndex(v => v.id === videoId); if (index !== -1) { playerRef.current?.goTo(index); // URL will automatically update! } }; return ( <div> <div style={{ padding: 20, background: '#f0f0f0' }}> <h3>Quick Navigation</h3> {sampleVideos.map((video) => ( <button key={video.id} onClick={() => navigateToVideo(video.id)} style={{ margin: 5, padding: '8px 16px' }} > Go to {video.title} </button> ))} </div> <PortraitPlayerView videos={sampleVideos} playerRef={playerRef} enableUrlRouting={true} urlPattern="path" baseUrl="/shorts" /> </div> ); }; /** * Example 7: React Router Integration */ export const ReactRouterExample = () => { const playerRef = useRef(null); return ( <PortraitPlayerView videos={sampleVideos} playerRef={playerRef} // Use hash-based routing when using React Router enableUrlRouting={true} urlPattern="hash" baseUrl="/player" onVideoChange={(index, video) => { // Analytics tracking if (window.gtag) { window.gtag('event', 'video_view', { video_id: video.id, video_title: video.title, }); } }} /> ); }; /** * Example 8: Next.js App Router Integration */ export const NextJsExample = () => { const playerRef = useRef(null); return ( <PortraitPlayerView videos={sampleVideos} playerRef={playerRef} enableUrlRouting={true} urlPattern="path" baseUrl="/shorts" onVideoChange={(index, video) => { // Update page metadata if (typeof window !== 'undefined') { document.title = `${video.title} - My App`; // Update meta tags for social sharing const metaDescription = document.querySelector('meta[name="description"]'); if (metaDescription) { metaDescription.setAttribute('content', video.description || ''); } } }} /> ); };