UNPKG

sysrot-hub

Version:

CLI de nueva generaciΓ³n para proyectos Next.js 14+ con IA multi-modelo, Web3 integration, internacionalizaciΓ³n completa y roadmap realista 2025-2026

982 lines (839 loc) β€’ 26.4 kB
# πŸ“Ί Video Streaming Platform A comprehensive video streaming and media platform with multi-channel support, video transcoding, analytics, and monetization features. Built for content creators and viewers with enterprise-level capabilities. ## πŸš€ Quick Start ### Prerequisites - Node.js 18+ - PostgreSQL database - Video storage service (Cloudinary, AWS S3, etc.) - FFmpeg for video processing (optional) ### Setup 1. **Install dependencies** ```bash npm install ``` 2. **Configure environment variables** ```bash # Add to your .env.local DATABASE_URL="postgresql://user:password@localhost:5432/videosdb" NEXTAUTH_SECRET="your-secret-key" NEXTAUTH_URL="http://localhost:3000" # Video storage and processing CLOUDINARY_CLOUD_NAME="your-cloud-name" CLOUDINARY_API_KEY="your-api-key" CLOUDINARY_API_SECRET="your-api-secret" # Optional: Video transcoding FFMPEG_PATH="/usr/local/bin/ffmpeg" VIDEO_PROCESSING_WEBHOOK="http://localhost:3000/api/webhooks/video-processing" # Optional: Analytics GOOGLE_ANALYTICS_ID="GA-MEASUREMENT-ID" ``` 3. **Setup database and seed** ```bash npm run setup:videos ``` 4. **Start development server** ```bash npm run dev ``` 5. **Access video platform** Navigate to `http://localhost:3000/videos` ## πŸ”‘ Test Credentials | Email | Password | Channel | Subscribers | Content Focus | |-------|----------|---------|-------------|---------------| | techguru@creators.com | video123 | Tech Tutorials Pro | 125K | Programming & Web Dev | | gamequeen@creators.com | video123 | Gaming Central Hub | 89K | Gaming & Esports | | cookmaster@creators.com | video123 | Chef Secrets Kitchen | 45K | Cooking & Recipes | | fitnesscoach@creators.com | video123 | Fitness Revolution | 67K | Workouts & Wellness | | musicproducer@creators.com | video123 | Beats Studio Official | 34K | Music Production | | artcreator@creators.com | video123 | Art Masterclass Studio | 28K | Digital Art | | viewer1@watchers.com | video123 | - | - | Active Video Viewer | | viewer2@watchers.com | video123 | - | - | Video Consumer | ## ✨ Features ### πŸ“Ί **Multi-Channel Platform** - **Channel Creation**: Create unlimited channels with custom branding - **Channel Verification**: Verified badge system for trusted creators - **Channel Analytics**: Comprehensive analytics and insights - **Channel Monetization**: Revenue tracking and payment integration ### πŸŽ₯ **Advanced Video Management** - **Video Upload**: Support for multiple video formats and sizes - **Video Processing**: Automatic transcoding to multiple qualities (360p-1080p) - **Video Metadata**: Rich metadata support with tags, categories, descriptions - **Video Scheduling**: Schedule videos for future publication ### πŸ”„ **Video Transcoding System** - **Multi-Quality Support**: 360p, 480p, 720p, 1080p, 1440p, 2160p - **Adaptive Streaming**: Automatic quality selection based on bandwidth - **Processing Status**: Real-time processing progress tracking - **Quality Optimization**: Optimized bitrates for each resolution ### πŸ‘₯ **Community Features** - **Subscription System**: Follow favorite channels with notifications - **Like/Dislike System**: Video engagement and feedback - **Comment System**: Threaded comments with moderation tools - **Watch History**: Personalized viewing history and progress tracking ### πŸ“‹ **Playlist Management** - **Custom Playlists**: Create and organize video collections - **Collaborative Playlists**: Allow multiple users to contribute - **Auto-Generated Playlists**: Algorithm-based recommendations - **Playlist Analytics**: Track playlist performance and engagement ### πŸ“Š **Advanced Analytics** - **Video Analytics**: Views, watch time, engagement metrics - **Channel Analytics**: Subscriber growth, revenue tracking - **Audience Insights**: Demographics, traffic sources, device types - **Performance Reports**: Detailed reports with exportable data ### πŸ”΄ **Live Streaming** - **RTMP Support**: Standard streaming protocol integration - **HLS Delivery**: HTTP Live Streaming for broad compatibility - **Live Chat**: Real-time chat with moderation features - **Stream Recording**: Automatic VOD creation from live streams ### πŸ›‘οΈ **Content Moderation** - **Report System**: Community-driven content reporting - **Automated Moderation**: AI-powered content filtering - **Manual Review**: Admin review workflow for reported content - **Age Restrictions**: Content rating and access controls ## πŸ—οΈ Architecture ### Database Models The system includes 15 comprehensive models: ```prisma // Core video streaming models model VideoChannel { id String @id @default(cuid()) name String handle String @unique category ChannelCategory isVerified Boolean isMonetized Boolean subscriberCount Int videos Video[] subscribers ChannelSubscription[] analytics ChannelAnalytics[] } model Video { id String @id @default(cuid()) title String slug String @unique videoUrl String duration Int status VideoStatus visibility VideoVisibility qualities VideoQuality[] comments VideoComment[] analytics VideoAnalytics[] watchHistory WatchHistory[] } model VideoQuality { id String @id @default(cuid()) quality String // 360p, 720p, 1080p, etc. videoUrl String fileSize Int bitrate Int processingStatus String } ``` ### API Structure ``` /api/channels/ β”œβ”€β”€ index.ts # Channel CRUD and subscriptions β”œβ”€β”€ [channelId]/ β”‚ β”œβ”€β”€ videos.ts # Channel video management β”‚ β”œβ”€β”€ analytics.ts # Channel analytics β”‚ └── collaborators.ts # Channel collaboration /api/videos/ β”œβ”€β”€ index.ts # Video CRUD and interactions β”œβ”€β”€ [videoId]/ β”‚ β”œβ”€β”€ comments.ts # Video comments β”‚ β”œβ”€β”€ analytics.ts # Video analytics β”‚ └── qualities.ts # Video quality management /api/playlists/ └── index.ts # Playlist management ``` ## πŸ“‘ API Reference ### Channels API (`/api/channels`) #### List Channels ```javascript GET /api/channels?category=GAMING&verified=true&sortBy=subscriberCount Response: { "channels": [ { "id": "gaming-central", "name": "Gaming Central Hub", "handle": "gamingcentral", "category": "GAMING", "isVerified": true, "subscriberCount": 89000, "isSubscribed": false, "stats": { "totalVideos": 45, "totalViews": 1800000, "recentVideos": 3 } } ], "pagination": { "page": 1, "total": 12, "pages": 1 } } ``` #### Create Channel ```javascript POST /api/channels { "name": "My Gaming Channel", "description": "Epic gaming content and tutorials", "handle": "mygaming", "category": "GAMING", "avatar": "https://example.com/avatar.jpg", "banner": "https://example.com/banner.jpg" } Response: { "channel": { "id": "new-channel-id", "name": "My Gaming Channel", "handle": "mygaming", "subscriberCount": 1 }, "message": "Channel created successfully" } ``` #### Subscribe to Channel ```javascript POST /api/channels?action=subscribe { "channelId": "gaming-central", "enableNotifications": true } Response: { "subscription": { "channelId": "gaming-central", "userId": "user-id", "isNotificationsEnabled": true }, "message": "Successfully subscribed to channel" } ``` ### Videos API (`/api/videos`) #### List Videos ```javascript GET /api/videos?category=TUTORIAL&sortBy=viewCount&limit=10 Response: { "videos": [ { "id": "next-js-tutorial", "title": "Complete Next.js 14 Tutorial", "slug": "complete-nextjs-14-tutorial", "duration": 3420, "viewCount": 45600, "likeCount": 2340, "channel": { "name": "Tech Tutorials Pro", "handle": "techtutorials", "isVerified": true }, "qualities": [ { "quality": "1080p", "videoUrl": "https://video.com/1080p.mp4" } ], "userInteraction": { "hasLiked": false, "watchProgress": 1200, "isCompleted": false } } ] } ``` #### Upload Video ```javascript POST /api/videos { "title": "How to Build a React App", "description": "Complete React tutorial from beginner to advanced", "channelId": "tech-channel-id", "videoUrl": "https://storage.com/video.mp4", "duration": 2400, "fileSize": 180000000, "category": "TUTORIAL", "tags": ["react", "javascript", "tutorial"], "visibility": "PUBLIC", "thumbnail": "https://storage.com/thumb.jpg" } Response: { "video": { "id": "new-video-id", "title": "How to Build a React App", "slug": "how-to-build-react-app", "status": "PROCESSING", "uploadProgress": 100 }, "message": "Video uploaded successfully" } ``` #### Like/Dislike Video ```javascript POST /api/videos?action=like { "videoId": "next-js-tutorial", "isLike": true } Response: { "action": "created", "message": "Video liked" } ``` #### Add Comment ```javascript POST /api/videos?action=comment { "videoId": "next-js-tutorial", "content": "Great tutorial! Really helped me understand Next.js", "parentId": "parent-comment-id" // Optional for replies } Response: { "comment": { "id": "comment-id", "content": "Great tutorial!", "author": { "name": "John Doe", "image": "https://avatar.com/john.jpg" }, "createdAt": "2024-01-15T14:30:00Z" }, "message": "Comment added successfully" } ``` #### Record Watch Progress ```javascript POST /api/videos?action=watch { "videoId": "next-js-tutorial", "watchDuration": 1200, "lastPosition": 1200, "quality": "720p", "deviceType": "desktop" } Response: { "watchHistory": { "watchedAt": "2024-01-15T15:00:00Z", "lastPosition": 1200, "isCompleted": false }, "message": "Watch progress recorded" } ``` ## 🎨 Frontend Integration ### Video Player Component ```jsx import { useState, useRef, useEffect } from 'react'; function VideoPlayer({ video, onProgressUpdate }) { const videoRef = useRef(null); const [currentTime, setCurrentTime] = useState(0); const [duration, setDuration] = useState(0); const [quality, setQuality] = useState('720p'); const handleTimeUpdate = () => { const current = videoRef.current.currentTime; setCurrentTime(current); // Record watch progress every 30 seconds if (Math.floor(current) % 30 === 0) { onProgressUpdate({ watchDuration: current, lastPosition: current, quality, deviceType: 'desktop' }); } }; const getVideoSource = (quality) => { const videoQuality = video.qualities.find(q => q.quality === quality); return videoQuality?.videoUrl || video.videoUrl; }; return ( <div className="video-player"> <video ref={videoRef} src={getVideoSource(quality)} onTimeUpdate={handleTimeUpdate} onLoadedMetadata={() => setDuration(videoRef.current.duration)} controls className="w-full aspect-video" > Your browser does not support the video tag. </video> <div className="video-controls"> <div className="progress-bar"> <div className="progress-fill" style={{ width: `${(currentTime / duration) * 100}%` }} /> </div> <div className="quality-selector"> <select value={quality} onChange={(e) => setQuality(e.target.value)} > {video.qualities.map(q => ( <option key={q.quality} value={q.quality}> {q.quality} </option> ))} </select> </div> </div> </div> ); } ``` ### Channel Dashboard ```jsx function ChannelDashboard({ channelId }) { const [analytics, setAnalytics] = useState(null); const [videos, setVideos] = useState([]); useEffect(() => { async function fetchChannelData() { const [analyticsRes, videosRes] = await Promise.all([ fetch(`/api/channels/${channelId}/analytics`), fetch(`/api/videos?channelId=${channelId}`) ]); setAnalytics(await analyticsRes.json()); setVideos(await videosRes.json()); } fetchChannelData(); }, [channelId]); return ( <div className="channel-dashboard"> <div className="stats-grid"> <div className="stat-card"> <h3>Subscribers</h3> <p className="text-3xl font-bold">{analytics?.subscriberCount}</p> </div> <div className="stat-card"> <h3>Total Views</h3> <p className="text-3xl font-bold">{analytics?.totalViews}</p> </div> <div className="stat-card"> <h3>Watch Time</h3> <p className="text-3xl font-bold">{analytics?.totalWatchTime}h</p> </div> <div className="stat-card"> <h3>Revenue</h3> <p className="text-3xl font-bold">${analytics?.revenue}</p> </div> </div> <div className="recent-videos"> <h2>Recent Videos</h2> <div className="video-grid"> {videos.map(video => ( <VideoCard key={video.id} video={video} /> ))} </div> </div> </div> ); } ``` ### Video Upload Component ```jsx function VideoUpload({ channelId, onUploadComplete }) { const [uploading, setUploading] = useState(false); const [progress, setProgress] = useState(0); const [videoData, setVideoData] = useState({ title: '', description: '', category: 'GENERAL', tags: [], visibility: 'PRIVATE' }); const handleUpload = async (file) => { setUploading(true); // First upload video file const formData = new FormData(); formData.append('file', file); const uploadRes = await fetch('/api/upload/video', { method: 'POST', body: formData, onUploadProgress: (progressEvent) => { const progress = Math.round( (progressEvent.loaded * 100) / progressEvent.total ); setProgress(progress); } }); const { videoUrl, duration, fileSize } = await uploadRes.json(); // Create video record const createRes = await fetch('/api/videos', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ ...videoData, channelId, videoUrl, duration, fileSize }) }); const video = await createRes.json(); setUploading(false); onUploadComplete(video); }; return ( <form className="video-upload"> <div className="upload-area"> <input type="file" accept="video/*" onChange={(e) => handleUpload(e.target.files[0])} disabled={uploading} /> {uploading && ( <div className="upload-progress"> <div className="progress-bar"> <div className="progress-fill" style={{ width: `${progress}%` }} /> </div> <p>Uploading... {progress}%</p> </div> )} </div> <div className="video-metadata"> <input type="text" placeholder="Video title" value={videoData.title} onChange={(e) => setVideoData({ ...videoData, title: e.target.value })} /> <textarea placeholder="Video description" value={videoData.description} onChange={(e) => setVideoData({ ...videoData, description: e.target.value })} /> <select value={videoData.category} onChange={(e) => setVideoData({ ...videoData, category: e.target.value })} > <option value="GENERAL">General</option> <option value="TUTORIAL">Tutorial</option> <option value="GAMING">Gaming</option> <option value="MUSIC">Music</option> </select> </div> </form> ); } ``` ## πŸ“Š Analytics Dashboard ### View Analytics Chart ```jsx import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip } from 'recharts'; function ViewAnalyticsChart({ videoId }) { const [analyticsData, setAnalyticsData] = useState([]); useEffect(() => { fetch(`/api/videos/${videoId}/analytics`) .then(res => res.json()) .then(data => setAnalyticsData(data.analytics)); }, [videoId]); return ( <div className="analytics-chart"> <h3>Views Over Time</h3> <LineChart width={800} height={400} data={analyticsData}> <CartesianGrid strokeDasharray="3 3" /> <XAxis dataKey="date" /> <YAxis /> <Tooltip /> <Line type="monotone" dataKey="views" stroke="#8884d8" strokeWidth={2} /> <Line type="monotone" dataKey="uniqueViews" stroke="#82ca9d" strokeWidth={2} /> </LineChart> </div> ); } ``` ### Engagement Metrics ```jsx function EngagementMetrics({ video }) { const engagementRate = ((video.likeCount + video.dislikeCount + video.commentCount) / video.viewCount * 100).toFixed(2); const likeRatio = (video.likeCount / (video.likeCount + video.dislikeCount) * 100).toFixed(1); return ( <div className="engagement-metrics"> <div className="metric"> <h4>Engagement Rate</h4> <p className="text-2xl font-bold">{engagementRate}%</p> </div> <div className="metric"> <h4>Like Ratio</h4> <p className="text-2xl font-bold">{likeRatio}%</p> </div> <div className="metric"> <h4>Average View Duration</h4> <p className="text-2xl font-bold">{video.averageViewDuration}s</p> </div> <div className="engagement-breakdown"> <div className="bar-chart"> <div className="bar likes" style={{ width: `${(video.likeCount / video.viewCount) * 100}%` }}> πŸ‘ {video.likeCount} </div> <div className="bar comments" style={{ width: `${(video.commentCount / video.viewCount) * 100}%` }}> πŸ’¬ {video.commentCount} </div> <div className="bar shares" style={{ width: `${(video.shareCount / video.viewCount) * 100}%` }}> πŸ“€ {video.shareCount} </div> </div> </div> </div> ); } ``` ## πŸ”§ Advanced Configuration ### Video Processing Pipeline ```javascript // Video processing workflow const videoProcessingPipeline = { upload: { maxFileSize: '2GB', supportedFormats: ['mp4', 'mov', 'avi', 'mkv', 'webm'], chunkSize: '10MB' }, transcoding: { qualities: [ { name: '360p', resolution: '640x360', bitrate: '800k' }, { name: '480p', resolution: '854x480', bitrate: '1200k' }, { name: '720p', resolution: '1280x720', bitrate: '2500k' }, { name: '1080p', resolution: '1920x1080', bitrate: '4500k' } ], thumbnails: { count: 3, times: ['10%', '50%', '90%'], resolution: '1280x720' } }, delivery: { cdn: 'cloudflare', adaptiveStreaming: true, hls: true, dash: true } }; ``` ### Monetization Settings ```javascript const monetizationConfig = { adPlacements: ['preroll', 'midroll', 'postroll'], minimumWatchTime: 30, // seconds before counting monetized view revenueShare: { creator: 70, platform: 30 }, eligibility: { minimumSubscribers: 1000, minimumWatchHours: 4000, contentGuidelines: true, monetizationAgreement: true }, payoutThreshold: 100, // minimum earnings before payout payoutSchedule: 'monthly' }; ``` ## πŸš€ Deployment ### Environment Variables ```bash # Production settings NODE_ENV=production DATABASE_URL="postgresql://..." NEXTAUTH_SECRET="secure-secret" NEXTAUTH_URL="https://yourdomain.com" # Video storage and CDN CLOUDINARY_CLOUD_NAME="your-cloud" CLOUDINARY_API_KEY="your-key" CLOUDINARY_API_SECRET="your-secret" CDN_URL="https://cdn.yourdomain.com" # Video processing FFMPEG_PATH="/usr/bin/ffmpeg" VIDEO_PROCESSING_WEBHOOK="https://yourdomain.com/api/webhooks/video" MAX_UPLOAD_SIZE="2GB" # Live streaming RTMP_SERVER="rtmp://live.yourdomain.com/live" HLS_ENDPOINT="https://hls.yourdomain.com" # Analytics and monitoring GOOGLE_ANALYTICS_ID="GA-MEASUREMENT-ID" SENTRY_DSN="https://sentry.io/..." # Monetization STRIPE_PUBLISHABLE_KEY="pk_live_..." STRIPE_SECRET_KEY="sk_live_..." PAYPAL_CLIENT_ID="your-paypal-client-id" ``` ### Performance Optimization ```javascript // Video delivery optimization const deliveryOptimization = { // CDN configuration cdn: { provider: 'cloudflare', regions: ['global'], caching: { videos: '30d', thumbnails: '7d', metadata: '1h' } }, // Adaptive bitrate streaming adaptiveStreaming: { enabled: true, bufferLength: 30, // seconds qualityLevels: ['360p', '480p', '720p', '1080p'], autoSwitch: true }, // Progressive loading progressiveLoading: { enabled: true, chunkSize: '1MB', preloadNext: true } }; ``` ## πŸ”’ Security & Privacy ### Content Protection ```javascript const contentProtection = { // DRM for premium content drm: { enabled: false, // Can be enabled for premium tiers providers: ['widevine', 'playready', 'fairplay'] }, // Geo-blocking geoBlocking: { enabled: true, blockedCountries: [], allowedCountries: ['*'] }, // Domain restriction domainRestriction: { enabled: false, allowedDomains: ['yourdomain.com'] }, // Watermarking watermark: { enabled: false, position: 'bottom-right', opacity: 0.3 } }; ``` ### Privacy Controls ```javascript const privacyControls = { visibility: { public: 'Anyone can view', unlisted: 'Only people with link can view', private: 'Only you can view', scheduled: 'Will be public at scheduled time' }, ageRestriction: { enabled: true, minimumAge: 13, explicitContent: false }, dataRetention: { analytics: '2 years', watchHistory: '3 years', comments: 'indefinite', uploadedContent: 'indefinite' } }; ``` ## πŸ“± Mobile Support ### Progressive Web App ```json { "name": "Video Streaming Platform", "short_name": "VideoHub", "description": "Professional video streaming platform", "start_url": "/videos", "display": "standalone", "background_color": "#000000", "theme_color": "#FF0000", "icons": [ { "src": "/icons/icon-192.png", "sizes": "192x192", "type": "image/png" } ] } ``` ### Mobile-Optimized Player ```jsx function MobileVideoPlayer({ video }) { const [isFullscreen, setIsFullscreen] = useState(false); const [showControls, setShowControls] = useState(true); return ( <div className={`mobile-player ${isFullscreen ? 'fullscreen' : ''}`}> <video controls={showControls} playsInline preload="metadata" onTouchStart={() => setShowControls(!showControls)} > <source src={video.videoUrl} type="video/mp4" /> </video> <div className="mobile-controls"> <button onClick={() => setIsFullscreen(!isFullscreen)}> {isFullscreen ? '⊞' : 'β›Ά'} </button> </div> </div> ); } ``` ## πŸ“š Resources - [Video Streaming Best Practices](https://developer.mozilla.org/en-US/docs/Web/Guide/Audio_and_video_delivery) - [HLS Streaming Guide](https://developer.apple.com/streaming/) - [DASH Streaming Specification](https://dashif.org/) - [Content Creator Guidelines](https://support.google.com/youtube/topic/9282364) - [Video SEO Best Practices](https://developers.google.com/search/docs/advanced/guidelines/video) ## 🀝 Contributing 1. Fork the repository 2. Create a feature branch (`git checkout -b feature/amazing-feature`) 3. Add comprehensive tests for video functionality 4. Update documentation 5. Submit a pull request ## πŸ“„ License This video streaming platform is part of the sysrot-hub template and follows the same license terms. --- ## 🎯 Next Steps Consider implementing these advanced features: 1. **Live Streaming** - RTMP/HLS live broadcasting 2. **AI-Powered Recommendations** - Machine learning content discovery 3. **Advanced Analytics** - Heat maps, retention curves, A/B testing 4. **Content Delivery Network** - Global video distribution 5. **Mobile Apps** - Native iOS and Android applications 6. **VR/360Β° Video Support** - Immersive video experiences 7. **Advanced Monetization** - Subscriptions, pay-per-view, donations 8. **Content Creator Tools** - Video editor, thumbnail generator 9. **Enterprise Features** - White-label solutions, API marketplace 10. **Blockchain Integration** - NFT videos, creator tokens The video streaming platform provides a solid foundation for building the next generation of video content platforms with all the features content creators and viewers expect from modern video services.