@@ -203,96 +203,59 @@ class BinTVProvider : MainAPI() {
203203
204204 // Fetch PPV matches
205205 val ppvMatches = mutableListOf<EventLoadData >()
206- try {
207- val ppvText = app.get(" https://old.ppv.to/api/streams" , timeout = 15L ).text
208- val ppvResponse = parseJson<PpvStreamsResponse >(ppvText)
209- if (ppvResponse.success && ! ppvResponse.streams.isNullOrEmpty()) {
210- val now = System .currentTimeMillis()
211- ppvResponse.streams.forEach { group ->
212- if (group.category == " 24/7 Streams" ) return @forEach
213- group.streams?.forEach { stream ->
214- val name = stream.name ? : " "
215- if (name.isBlank()) return @forEach
216- val startMs = (stream.starts_at ? : 0 ) * 1000L
217- val endMs = (stream.ends_at ? : 0 ) * 1000L
218- // Filter ended matches
219- if (stream.ends_at != null && endMs < now - 600000L ) return @forEach
220-
221- val iframes = mutableListOf<MatchSource >()
222- if (! stream.iframe.isNullOrBlank()) {
223- // Get stream name
224- val mainName = stream.source_tag?.takeIf { it.isNotBlank() } ? : " Main"
225- iframes.add(MatchSource (mainName, stream.iframe))
226- }
227- stream.substreams?.forEachIndexed { subIdx, sub ->
228- if (! sub.iframe.isNullOrBlank() && iframes.none { it.url == sub.iframe }) {
229- // Get fallback name
230- val rawName = sub.uri_name?.takeIf { it.isNotBlank() }
231- ? : sub.source_tag?.takeIf { it.isNotBlank() }
232- ? : sub.name?.takeIf { it.isNotBlank() }
233- ? : " Server ${subIdx + 1 } "
234- // Normalize name
235- val prettyName = rawName
236- .split(" -" ).joinToString(" " ) { part ->
237- if (part.length <= 3 ) part.uppercase()
238- else part.replaceFirstChar { it.uppercase() }
239- }
240- iframes.add(MatchSource (prettyName, sub.iframe))
241- }
242- }
243-
244- if (iframes.isEmpty()) return @forEach
245-
246- val numberedSources = iframes.mapIndexed { idx, src ->
247- MatchSource (
248- name = " ${src.name} [${idx + 1 } ]" ,
249- url = src.url
250- )
251- }
206+ val ppvUrls = listOf (
207+ " https://old.ppv.to/api/streams" ,
208+ " https://api.ppv.to/api/streams" ,
209+ " https://api.ppv.cx/api/streams"
210+ )
211+ val ppvHeaders = mapOf (
212+ " User-Agent" to " Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Mobile Safari/537.36" ,
213+ " Referer" to " https://www.bintv.net/" ,
214+ " Origin" to " https://www.bintv.net"
215+ )
252216
253- ppvMatches.add(
254- EventLoadData (
255- title = name,
256- poster = stream.poster,
257- date = startMs,
258- endsAt = endMs,
259- category = stream.category_name ? : group.category ? : " Other" ,
260- sources = numberedSources,
261- isPPV = true ,
262- isBinTV = false
263- )
264- )
265- }
217+ var ppvText = " "
218+ for (url in ppvUrls) {
219+ try {
220+ val res = app.get(url, headers = ppvHeaders, timeout = 15L )
221+ if (res.code == 200 && res.text.isNotBlank()) {
222+ ppvText = res.text
223+ break
266224 }
225+ } catch (e: Exception ) {
226+ println (" BinTV: failed to load PPV matches from $url - ${e.message} " )
267227 }
268- } catch (e : Exception ) {
269- println ( " BinTV: failed to load PPV matches - ${e.message} " )
270- // Fallback API
228+ }
229+
230+ if (ppvText.isNotBlank()) {
271231 try {
272- val fallbackText = app.get(" https://api.ppv.to/api/streams" , timeout = 15L ).text
273- val fallbackResponse = parseJson<PpvStreamsResponse >(fallbackText)
274- if (fallbackResponse.success && ! fallbackResponse.streams.isNullOrEmpty()) {
232+ val ppvResponse = parseJson<PpvStreamsResponse >(ppvText)
233+ if (ppvResponse.success && ! ppvResponse.streams.isNullOrEmpty()) {
275234 val now = System .currentTimeMillis()
276- fallbackResponse .streams.forEach { group ->
235+ ppvResponse .streams.forEach { group ->
277236 if (group.category == " 24/7 Streams" ) return @forEach
278237 group.streams?.forEach { stream ->
279238 val name = stream.name ? : " "
280239 if (name.isBlank()) return @forEach
281240 val startMs = (stream.starts_at ? : 0 ) * 1000L
282241 val endMs = (stream.ends_at ? : 0 ) * 1000L
242+ // Filter ended matches
283243 if (stream.ends_at != null && endMs < now - 600000L ) return @forEach
284244
285245 val iframes = mutableListOf<MatchSource >()
286246 if (! stream.iframe.isNullOrBlank()) {
247+ // Get stream name
287248 val mainName = stream.source_tag?.takeIf { it.isNotBlank() } ? : " Main"
288249 iframes.add(MatchSource (mainName, stream.iframe))
289250 }
290251 stream.substreams?.forEachIndexed { subIdx, sub ->
291252 if (! sub.iframe.isNullOrBlank() && iframes.none { it.url == sub.iframe }) {
253+ // Get fallback name
292254 val rawName = sub.uri_name?.takeIf { it.isNotBlank() }
293255 ? : sub.source_tag?.takeIf { it.isNotBlank() }
294256 ? : sub.name?.takeIf { it.isNotBlank() }
295257 ? : " Server ${subIdx + 1 } "
258+ // Normalize name
296259 val prettyName = rawName
297260 .split(" -" ).joinToString(" " ) { part ->
298261 if (part.length <= 3 ) part.uppercase()
@@ -301,10 +264,16 @@ class BinTVProvider : MainAPI() {
301264 iframes.add(MatchSource (prettyName, sub.iframe))
302265 }
303266 }
267+
304268 if (iframes.isEmpty()) return @forEach
269+
305270 val numberedSources = iframes.mapIndexed { idx, src ->
306- MatchSource (name = " ${src.name} [${idx + 1 } ]" , url = src.url)
271+ MatchSource (
272+ name = " ${src.name} [${idx + 1 } ]" ,
273+ url = src.url
274+ )
307275 }
276+
308277 ppvMatches.add(
309278 EventLoadData (
310279 title = name,
@@ -320,8 +289,8 @@ class BinTVProvider : MainAPI() {
320289 }
321290 }
322291 }
323- } catch (fallbackErr : Exception ) {
324- println (" BinTV: PPV fallback also failed - ${fallbackErr .message} " )
292+ } catch (e : Exception ) {
293+ println (" BinTV: failed to parse PPV JSON - ${e .message} " )
325294 }
326295 }
327296
0 commit comments