diff --git a/api/index.go b/api/index.go index fa71980..81b0980 100644 --- a/api/index.go +++ b/api/index.go @@ -100,6 +100,11 @@ func Handler(w http.ResponseWriter, r *http.Request) { api.HandleFunc("/players/vidsrc/{media_type}/{imdb_id}", playersHandler.GetVidsrcPlayer).Methods("GET") api.HandleFunc("/players/vidlink/movie/{imdb_id}", playersHandler.GetVidlinkMoviePlayer).Methods("GET") api.HandleFunc("/players/vidlink/tv/{tmdb_id}", playersHandler.GetVidlinkTVPlayer).Methods("GET") + + // Client-side parsing players (custom player with HLS support) + api.HandleFunc("/players/vidsrc-parse/{media_type}/{imdb_id}", playersHandler.GetVidsrcParserPlayer).Methods("GET") + api.HandleFunc("/players/vidlink-parse/movie/{imdb_id}", playersHandler.GetVidlinkParserMoviePlayer).Methods("GET") + api.HandleFunc("/players/vidlink-parse/tv/{tmdb_id}", playersHandler.GetVidlinkParserTVPlayer).Methods("GET") api.HandleFunc("/players/rgshows/{tmdb_id}", playersHandler.GetRgShowsPlayer).Methods("GET") api.HandleFunc("/players/rgshows/{tmdb_id}/{season}/{episode}", playersHandler.GetRgShowsTVPlayer).Methods("GET") api.HandleFunc("/players/iframevideo/{kinopoisk_id}/{imdb_id}", playersHandler.GetIframeVideoPlayer).Methods("GET") diff --git a/main.go b/main.go index dec7ab7..c900e7c 100644 --- a/main.go +++ b/main.go @@ -81,6 +81,11 @@ func main() { api.HandleFunc("/players/vidsrc/{media_type}/{imdb_id}", playersHandler.GetVidsrcPlayer).Methods("GET") api.HandleFunc("/players/vidlink/movie/{imdb_id}", playersHandler.GetVidlinkMoviePlayer).Methods("GET") api.HandleFunc("/players/vidlink/tv/{tmdb_id}", playersHandler.GetVidlinkTVPlayer).Methods("GET") + + // Client-side parsing players (custom player with HLS support) + api.HandleFunc("/players/vidsrc-parse/{media_type}/{imdb_id}", playersHandler.GetVidsrcParserPlayer).Methods("GET") + api.HandleFunc("/players/vidlink-parse/movie/{imdb_id}", playersHandler.GetVidlinkParserMoviePlayer).Methods("GET") + api.HandleFunc("/players/vidlink-parse/tv/{tmdb_id}", playersHandler.GetVidlinkParserTVPlayer).Methods("GET") api.HandleFunc("/torrents/search/{imdbId}", torrentsHandler.SearchTorrents).Methods("GET") api.HandleFunc("/torrents/movies", torrentsHandler.SearchMovies).Methods("GET") diff --git a/pkg/handlers/client_parser.go b/pkg/handlers/client_parser.go new file mode 100644 index 0000000..da74f8b --- /dev/null +++ b/pkg/handlers/client_parser.go @@ -0,0 +1,419 @@ +package handlers + +import ( + "fmt" + "log" + "net/http" + + "github.com/gorilla/mux" +) + +// GetVidsrcParserPlayer handles Vidsrc.to player with client-side parsing +func (h *PlayersHandler) GetVidsrcParserPlayer(w http.ResponseWriter, r *http.Request) { + log.Printf("GetVidsrcParserPlayer called: %s %s", r.Method, r.URL.Path) + + vars := mux.Vars(r) + imdbId := vars["imdb_id"] + mediaType := vars["media_type"] // "movie" or "tv" + + if imdbId == "" || mediaType == "" { + http.Error(w, "imdb_id and media_type are required", http.StatusBadRequest) + return + } + + var embedURL string + if mediaType == "movie" { + embedURL = fmt.Sprintf("https://vidsrc.to/embed/movie/%s", imdbId) + } else if mediaType == "tv" { + season := r.URL.Query().Get("season") + episode := r.URL.Query().Get("episode") + if season == "" || episode == "" { + http.Error(w, "season and episode are required for TV shows", http.StatusBadRequest) + return + } + embedURL = fmt.Sprintf("https://vidsrc.to/embed/tv/%s/%s/%s", imdbId, season, episode) + } else { + http.Error(w, "Invalid media_type. Use 'movie' or 'tv'", http.StatusBadRequest) + return + } + + log.Printf("Generated Vidsrc embed URL: %s", embedURL) + + htmlDoc := generateClientParserHTML(embedURL, "Vidsrc Player") + + w.Header().Set("Content-Type", "text/html; charset=utf-8") + w.Write([]byte(htmlDoc)) + + log.Printf("Successfully served Vidsrc parser player for %s: %s", mediaType, imdbId) +} + +// GetVidlinkParserMoviePlayer handles Vidlink.pro parser for movies +func (h *PlayersHandler) GetVidlinkParserMoviePlayer(w http.ResponseWriter, r *http.Request) { + log.Printf("GetVidlinkParserMoviePlayer called: %s %s", r.Method, r.URL.Path) + + vars := mux.Vars(r) + imdbId := vars["imdb_id"] + + if imdbId == "" { + http.Error(w, "imdb_id is required", http.StatusBadRequest) + return + } + + embedURL := fmt.Sprintf("https://vidlink.pro/movie/%s", imdbId) + + log.Printf("Generated Vidlink movie embed URL: %s", embedURL) + + htmlDoc := generateClientParserHTML(embedURL, "Vidlink Player") + + w.Header().Set("Content-Type", "text/html; charset=utf-8") + w.Write([]byte(htmlDoc)) + + log.Printf("Successfully served Vidlink parser movie player: %s", imdbId) +} + +// GetVidlinkParserTVPlayer handles Vidlink.pro parser for TV shows +func (h *PlayersHandler) GetVidlinkParserTVPlayer(w http.ResponseWriter, r *http.Request) { + log.Printf("GetVidlinkParserTVPlayer called: %s %s", r.Method, r.URL.Path) + + vars := mux.Vars(r) + tmdbId := vars["tmdb_id"] + + if tmdbId == "" { + http.Error(w, "tmdb_id is required", http.StatusBadRequest) + return + } + + season := r.URL.Query().Get("season") + episode := r.URL.Query().Get("episode") + if season == "" || episode == "" { + http.Error(w, "season and episode are required for TV shows", http.StatusBadRequest) + return + } + + embedURL := fmt.Sprintf("https://vidlink.pro/tv/%s/%s/%s", tmdbId, season, episode) + + log.Printf("Generated Vidlink TV embed URL: %s", embedURL) + + htmlDoc := generateClientParserHTML(embedURL, "Vidlink Player") + + w.Header().Set("Content-Type", "text/html; charset=utf-8") + w.Write([]byte(htmlDoc)) + + log.Printf("Successfully served Vidlink parser TV player: %s S%sE%s", tmdbId, season, episode) +} + +func generateClientParserHTML(embedURL, title string) string { + return fmt.Sprintf(` + +
+ + +