mirror of
				https://gitlab.com/foxixus/neomovies-api.git
				synced 2025-10-29 02:18:50 +05:00 
			
		
		
		
	🎬 New Streaming Players Added:
- RgShows player for movies and TV shows via TMDB ID
- IframeVideo player using Kinopoisk ID and IMDB ID
- Unified players manager for multiple streaming providers
- JSON API endpoints for programmatic access
📡 RgShows Player Features:
- Direct movie streaming: /api/v1/players/rgshows/{tmdb_id}
- TV show episodes: /api/v1/players/rgshows/{tmdb_id}/{season}/{episode}
- HTTP API integration with rgshows.com
- 40-second timeout for reliability
- Proper error handling and logging
🎯 IframeVideo Player Features:
- Two-step authentication process (search + token extraction)
- Support for both Kinopoisk and IMDB IDs
- HTML iframe parsing for token extraction
- Multipart form data for video URL requests
- Endpoint: /api/v1/players/iframevideo/{kinopoisk_id}/{imdb_id}
🔧 Technical Implementation:
- Clean Go architecture with pkg/players package
- StreamResult interface for consistent responses
- Proper HTTP headers mimicking browser requests
- Comprehensive error handling and logging
- RESTful API design following existing patterns
🌐 New API Endpoints:
- /api/v1/players/rgshows/{tmdb_id} - RgShows movie player
- /api/v1/players/rgshows/{tmdb_id}/{season}/{episode} - RgShows TV player
- /api/v1/players/iframevideo/{kinopoisk_id}/{imdb_id} - IframeVideo player
- /api/v1/stream/{provider}/{tmdb_id} - JSON API for stream info
✅ Quality Assurance:
- All code passes go vet without issues
- Proper Go formatting applied
- Modular design for easy extension
- Built from commit 70febe5 'Merge branch feature/jwt-refresh-and-favorites-fix'
Ready for production deployment! 🚀
		
	
		
			
				
	
	
		
			100 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			100 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package players
 | |
| 
 | |
| // StreamResult represents the result of a streaming request
 | |
| type StreamResult struct {
 | |
| 	Success   bool   `json:"success"`
 | |
| 	StreamURL string `json:"stream_url,omitempty"`
 | |
| 	Provider  string `json:"provider"`
 | |
| 	Type      string `json:"type"` // "direct", "iframe", "hls", etc.
 | |
| 	Error     string `json:"error,omitempty"`
 | |
| }
 | |
| 
 | |
| // Player interface defines methods for streaming providers
 | |
| type Player interface {
 | |
| 	GetMovieStream(tmdbID string) (*StreamResult, error)
 | |
| 	GetTVStream(tmdbID string, season, episode int) (*StreamResult, error)
 | |
| }
 | |
| 
 | |
| // PlayersManager manages all available streaming players
 | |
| type PlayersManager struct {
 | |
| 	rgshows     *RgShowsPlayer
 | |
| 	iframevideo *IframeVideoPlayer
 | |
| }
 | |
| 
 | |
| // NewPlayersManager creates a new players manager
 | |
| func NewPlayersManager() *PlayersManager {
 | |
| 	return &PlayersManager{
 | |
| 		rgshows:     NewRgShowsPlayer(),
 | |
| 		iframevideo: NewIframeVideoPlayer(),
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // GetMovieStreams tries to get movie streams from all available providers
 | |
| func (pm *PlayersManager) GetMovieStreams(tmdbID string) []*StreamResult {
 | |
| 	var results []*StreamResult
 | |
| 
 | |
| 	// Try RgShows
 | |
| 	if stream, err := pm.rgshows.GetMovieStream(tmdbID); err == nil {
 | |
| 		results = append(results, stream)
 | |
| 	} else {
 | |
| 		results = append(results, &StreamResult{
 | |
| 			Success:  false,
 | |
| 			Provider: "RgShows",
 | |
| 			Error:    err.Error(),
 | |
| 		})
 | |
| 	}
 | |
| 
 | |
| 	return results
 | |
| }
 | |
| 
 | |
| // GetTVStreams tries to get TV show streams from all available providers
 | |
| func (pm *PlayersManager) GetTVStreams(tmdbID string, season, episode int) []*StreamResult {
 | |
| 	var results []*StreamResult
 | |
| 
 | |
| 	// Try RgShows
 | |
| 	if stream, err := pm.rgshows.GetTVStream(tmdbID, season, episode); err == nil {
 | |
| 		results = append(results, stream)
 | |
| 	} else {
 | |
| 		results = append(results, &StreamResult{
 | |
| 			Success:  false,
 | |
| 			Provider: "RgShows",
 | |
| 			Error:    err.Error(),
 | |
| 		})
 | |
| 	}
 | |
| 
 | |
| 	return results
 | |
| }
 | |
| 
 | |
| // GetMovieStreamByProvider gets movie stream from specific provider
 | |
| func (pm *PlayersManager) GetMovieStreamByProvider(provider, tmdbID string) (*StreamResult, error) {
 | |
| 	switch provider {
 | |
| 	case "rgshows":
 | |
| 		return pm.rgshows.GetMovieStream(tmdbID)
 | |
| 	default:
 | |
| 		return &StreamResult{
 | |
| 			Success:  false,
 | |
| 			Provider: provider,
 | |
| 			Error:    "provider not found",
 | |
| 		}, nil
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // GetTVStreamByProvider gets TV stream from specific provider
 | |
| func (pm *PlayersManager) GetTVStreamByProvider(provider, tmdbID string, season, episode int) (*StreamResult, error) {
 | |
| 	switch provider {
 | |
| 	case "rgshows":
 | |
| 		return pm.rgshows.GetTVStream(tmdbID, season, episode)
 | |
| 	default:
 | |
| 		return &StreamResult{
 | |
| 			Success:  false,
 | |
| 			Provider: provider,
 | |
| 			Error:    "provider not found",
 | |
| 		}, nil
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // GetStreamWithKinopoisk gets stream using Kinopoisk ID and IMDB ID (for IframeVideo)
 | |
| func (pm *PlayersManager) GetStreamWithKinopoisk(kinopoiskID, imdbID string) (*StreamResult, error) {
 | |
| 	return pm.iframevideo.GetStream(kinopoiskID, imdbID)
 | |
| }
 |