Compare commits

..

No commits in common. "253017fefcfd68127531264ea978d9ca647b1776" and "12918042b7bbaa7831aa17ada867a0deb01b2515" have entirely different histories.

12 changed files with 114061 additions and 107503 deletions

File diff suppressed because it is too large Load diff

215984
M3U8/TV.xml

File diff suppressed because one or more lines are too long

View file

@ -4,7 +4,7 @@
http://41.205.93.154/AandE/index.m3u8
#EXTINF:-1 tvg-chno="2" tvg-id="ABC.National.Feed.us2" tvg-name="ABC" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s10003_dark_360w_270h.png" group-title="TV",ABC
https://restream-live.realiptv.to/Lucas123/Lucas123/112234
http://stream.cammonitorplus.net/1740/index.m3u8?token=MnE3ZWg1YkgxdFdWZlo2c2hLMkltWnJhcFo1OHhxcXVyb2pKazZXaWxZRERxNEduaVp1UnBxU2VlWmF0ZnRlRGxaMm1zNStDbnJOOXFZMlhtcStybmc9PQ==
#EXTINF:-1 tvg-chno="3" tvg-id="ACC.Network.us2" tvg-name="ACC Network" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s111871_dark_360w_270h.png" group-title="TV",ACC Network
http://23.239.31.26:8989/accnetwork/index.m3u8
@ -52,7 +52,7 @@ http://23.237.104.106:8080/USA_BOOMERANG/index.m3u8
http://212.102.60.231/BOUNCE_TV/index.m3u8
#EXTINF:-1 tvg-chno="18" tvg-id="Bravo.HD.us2" tvg-name="Bravo TV" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s10057_dark_360w_270h.png" group-title="TV",Bravo TV
http://104.255.88.155/bravo/index.m3u8
http://41.205.93.154/BRAVO/index.m3u8
#EXTINF:-1 tvg-chno="19" tvg-id="BUZZR.Stream.us2" tvg-name="Buzzr" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s93430_dark_360w_270h.png" group-title="TV",Buzzr
https://buzzrota-web.amagi.tv/playlist.m3u8
@ -64,7 +64,7 @@ http://mytvstream.net:8080/live/30550113/30550113/136589.m3u8
http://23.237.104.106:8080/USA_CARTOON_NETWORK/index.m3u8
#EXTINF:-1 tvg-chno="22" tvg-id="CBS.Streaming.SD.East.feed.us2" tvg-name="CBS" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s10098_dark_360w_270h.png" group-title="TV",CBS
https://restream-live.realiptv.to/Lucas123/Lucas123/2631
http://stream.cammonitorplus.net/1810/index.m3u8?token=MnE3ZWg1YkgxdFdWZlo2c2hLMkltWnJhcFo1OHhxcXVyb2pKazZXaWxZRERxNEduaVp1UnBxU2VlWmF0ZnRlRGxaMm1zNStDbnJOOXFZMlhtcStybmc9PQ==
#EXTINF:-1 tvg-chno="23" tvg-id="CBS.News.National.Stream.us2" tvg-name="CBS News 24/7" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s104846_dark_360w_270h.png" group-title="TV",CBS News 24/7
https://cbsn-us.cbsnstream.cbsnews.com/out/v1/55a8648e8f134e82a470f83d562deeca/master.m3u8
@ -85,7 +85,7 @@ http://hardcoremedia.xyz/live/rabdsbmz/3731346838/129849.ts
http://23.237.104.106:8080/USA_CMT/index.m3u8
#EXTINF:-1 tvg-chno="29" tvg-id="CNBC.HD.us2" tvg-name="CNBC" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s10139_dark_360w_270h.png" group-title="TV",CNBC
http://mytvstream.net:8080/live/30550113/30550113/9815.m3u8
http://41.205.93.154/CNBC/index.m3u8
#EXTINF:-1 tvg-chno="30" tvg-id="CNN.HD.us2" tvg-name="CNN" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s58646_dark_360w_270h.png" group-title="TV",CNN
https://turnerlive.warnermediacdn.com/hls/live/586495/cnngo/cnn_slate/VIDEO_0_3564000.m3u8
@ -190,7 +190,7 @@ https://jmp2.uk/stvp-IN270000230
http://23.237.104.106:8080/USA_FOOD_NETWORK/index.m3u8
#EXTINF:-1 tvg-chno="64" tvg-id="WJBK-DT.us_locals1" tvg-name="Fox" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s28719_dark_360w_270h.png" group-title="TV",Fox
https://restream-live.realiptv.to/Lucas123/Lucas123/2544
http://stream.cammonitorplus.net/1772/index.m3u8?token=MnE3ZWg1YkgxdFdWZlo2c2hLMkltWnJhcFo1OHhxcXVyb2pKazZXaWxZRERxNEduaVp1UnBxU2VlWmF0ZnRlRGxaMm1zNStDbnJOOXFZMlhtcStybmc9PQ==
#EXTINF:-1 tvg-chno="65" tvg-id="Fox.Business.HD.us2" tvg-name="Fox Business" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s58649_dark_360w_270h.png" group-title="TV",Fox Business
http://mytvstream.net:8080/live/30550113/30550113/17639.m3u8
@ -283,7 +283,7 @@ http://23.237.104.106:8080/USA_LMN/index.m3u8
http://mytvstream.net:8080/live/30550113/30550113/13379.m3u8
#EXTINF:-1 tvg-chno="95" tvg-id="MLB.Network.HD.us2" tvg-name="MLB Network" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s62081_dark_360w_270h.png" group-title="TV",MLB Network
http://89.105.221.127/MLBNetwork/mpegts?token=test
http://stream.cammonitorplus.net/337626/index.m3u8?token=MnE3ZWg1YkgxdFdWZlo2c2hLMkltWnJhcFo1OHhxcXVyb2pKazZXaWxZRERxNEduaVp1UnBxU2VlWmF0ZnRlRGxaMm1zNStDbnJOOXFZMlhtcStybmc9PQ==
#EXTINF:-1 tvg-chno="96" tvg-id="MOTORTREND.HD.us2" tvg-name="MotorTrend TV" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s31046_dark_360w_270h.png" group-title="TV",MotorTrend TV
http://mytvstream.net:8080/live/30550113/30550113/10399.m3u8
@ -304,7 +304,7 @@ http://23.237.104.106:8080/USA_NAT_GEO/index.m3u8
http://212.102.60.231/NBA_TV/index.m3u8
#EXTINF:-1 tvg-chno="102" tvg-id="NBC.East.Stream.us2" tvg-name="NBC" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s10991_dark_360w_270h.png" group-title="TV",NBC
https://restream-live.realiptv.to/Lucas123/Lucas123/89714
http://stream.cammonitorplus.net/1765/index.m3u8?token=MnE3ZWg1YkgxdFdWZlo2c2hLMkltWnJhcFo1OHhxcXVyb2pKazZXaWxZRERxNEduaVp1UnBxU2VlWmF0ZnRlRGxaMm1zNStDbnJOOXFZMlhtcStybmc9PQ==
#EXTINF:-1 tvg-chno="103" tvg-id="NBC.Sports.Bay.Area.HD.us2" tvg-name="NBC Sports Bay Area" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s63138_dark_360w_270h.png" group-title="TV",NBC Sports Bay Area
http://mytvstream.net:8080/live/30550113/30550113/9900.m3u8
@ -334,7 +334,7 @@ https://stream.decentdoubts.net/6128524/index.m3u8?token=Mm9QYnQ1ZkpyYWllaEoydWh
https://starshare.st/live/P4B9TB9xR8/humongous2tonight/23550.ts
#EXTINF:-1 tvg-chno="112" tvg-id="NHL.Network.HD.us2" tvg-name="NHL Network" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s58570_dark_360w_270h.png" group-title="TV",NHL Network
https://restream-live.realiptv.to/Lucas123/Lucas123/3672
http://mytvstream.net:8080/live/30550113/30550113/20179.m3u8
#EXTINF:-1 tvg-chno="113" tvg-id="Nick.Jr.HD.us2" tvg-name="Nick Jr" tvg-logo="https://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s19211_dark_360w_270h.png" group-title="TV",Nick Jr
http://mytvstream.net:8080/live/30550113/30550113/46710.m3u8
@ -430,7 +430,7 @@ http://23.237.104.106:8080/USA_STARZ/index.m3u8
http://212.102.60.231/STARZ_ENCORE_CLASSIC/index.m3u8
#EXTINF:-1 tvg-chno="144" tvg-id="Syfy.HD.us2" tvg-name="Syfy" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s11097_dark_360w_270h.png" group-title="TV",Syfy
http://23.237.104.106:8080/USA_SYFY/index.m3u8
http://41.205.93.154/SYFY/index.m3u8
#EXTINF:-1 tvg-chno="145" tvg-id="TBS.HD.us2" tvg-name="TBS" tvg-logo="http://schedulesdirect-api20141201-logos.s3.dualstack.us-east-1.amazonaws.com/stationLogos/s11867_dark_360w_270h.png" group-title="TV",TBS
https://turnerlive.warnermediacdn.com/hls/live/2023172/tbseast/slate/VIDEO_0_3564000.m3u8

File diff suppressed because it is too large Load diff

View file

@ -16,7 +16,7 @@ from scrapers import (
ppv,
roxie,
shark,
sportzone,
sport9,
streambtw,
streamcenter,
streamhub,
@ -70,7 +70,7 @@ async def main() -> None:
asyncio.create_task(pixel.scrape(hdl_brwsr)),
asyncio.create_task(ppv.scrape(xtrnl_brwsr)),
asyncio.create_task(roxie.scrape(hdl_brwsr)),
asyncio.create_task(sportzone.scrape(xtrnl_brwsr)),
asyncio.create_task(sport9.scrape(xtrnl_brwsr)),
asyncio.create_task(streamcenter.scrape(hdl_brwsr)),
# asyncio.create_task(streamhub.scrape(xtrnl_brwsr)),
asyncio.create_task(streamsgate.scrape(xtrnl_brwsr)),
@ -117,7 +117,7 @@ async def main() -> None:
| ppv.urls
| roxie.urls
| shark.urls
| sportzone.urls
| sport9.urls
| streambtw.urls
| streamcenter.urls
| streamhub.urls

View file

@ -44,10 +44,7 @@ async def get_events(cached_keys: list[str]) -> list[dict[str, str]]:
event_info = api_data[sport]
for event in event_info:
t1, t2 = event.get("awayTeam"), event.get("homeTeam")
if not (t1 and t2):
continue
t1, t2 = event["awayTeam"], event["homeTeam"]
name = f"{t1} vs {t2}"

148
M3U8/scrapers/sport9.py Normal file
View file

@ -0,0 +1,148 @@
import asyncio
from functools import partial
from urllib.parse import urljoin
from playwright.async_api import Browser
from selectolax.parser import HTMLParser
from .utils import Cache, Time, get_logger, leagues, network
log = get_logger(__name__)
urls: dict[str, dict[str, str | float]] = {}
TAG = "SPORT9"
CACHE_FILE = Cache(TAG, exp=5_400)
BASE_URL = "https://sport9.ru"
async def get_events(cached_keys: list[str]) -> list[dict[str, str]]:
now = Time.now()
tasks = [
network.request(
BASE_URL,
log=log,
params={"date": d.date()},
)
for d in [
now.delta(days=-1),
now,
now.delta(days=1),
]
]
results = await asyncio.gather(*tasks)
events = []
if not (soups := [HTMLParser(html.content) for html in results if html]):
return events
for soup in soups:
for card in soup.css("a.match-card"):
live_badge = card.css_first(".live-badge")
if not live_badge or live_badge.text(strip=True).lower() != "live":
continue
if not (sport_node := card.css_first(".tournament-name")):
continue
sport = sport_node.text(strip=True)
team_1_node = card.css_first(".team1 .team-name")
team_2_node = card.css_first(".team2 .team-name")
if team_1_node and team_2_node:
event = event = (
f"{team_1_node.text(strip=True)} vs {team_2_node.text(strip=True)}"
)
elif team_1_node:
event = team_1_node.text(strip=True)
elif team_2_node:
event = team_2_node.text(strip=True)
else:
continue
if f"[{sport}] {event} ({TAG})" in cached_keys:
continue
if not (href := card.attributes.get("href")):
continue
events.append(
{
"sport": sport,
"event": event,
"link": urljoin(BASE_URL, href),
}
)
return events
async def scrape(browser: Browser) -> None:
cached_urls = CACHE_FILE.load()
cached_count = len(cached_urls)
urls.update(cached_urls)
log.info(f"Loaded {cached_count} event(s) from cache")
log.info(f'Scraping from "{BASE_URL}"')
if events := await get_events(cached_urls.keys()):
log.info(f"Processing {len(events)} new URL(s)")
now = Time.clean(Time.now())
async with network.event_context(browser, stealth=False) as context:
for i, ev in enumerate(events, start=1):
async with network.event_page(context) as page:
handler = partial(
network.process_event,
url=(link := ev["link"]),
url_num=i,
page=page,
log=log,
)
url = await network.safe_process(
handler,
url_num=i,
semaphore=network.PW_S,
log=log,
)
if url:
sport, event = ev["sport"], ev["event"]
key = f"[{sport}] {event} ({TAG})"
tvg_id, logo = leagues.get_tvg_info(sport, event)
entry = {
"url": url,
"logo": logo,
"base": "https://vividmosaica.com/",
"timestamp": now.timestamp(),
"id": tvg_id or "Live.Event.us",
"link": link,
}
urls[key] = cached_urls[key] = entry
log.info(f"Collected and cached {len(cached_urls) - cached_count} new event(s)")
else:
log.info("No new events found")
CACHE_FILE.write(cached_urls)

View file

@ -1,154 +0,0 @@
from functools import partial
from typing import Any
from playwright.async_api import Browser
from .utils import Cache, Time, get_logger, leagues, network
log = get_logger(__name__)
urls: dict[str, dict[str, str | float]] = {}
TAG = "SPRTZONE"
CACHE_FILE = Cache(TAG, exp=5_400)
API_FILE = Cache(f"{TAG}-api", exp=28_800)
API_URL = "https://sportzone.su/data.json"
async def refresh_api_cache(now_ts: float) -> list[dict[str, Any]]:
api_data = [{"timestamp": now_ts}]
if r := await network.request(API_URL, log=log):
api_data: list[dict] = r.json().get("matches", [])
if api_data:
for event in api_data:
event["ts"] = event.pop("timestamp")
api_data[-1]["timestamp"] = now_ts
return api_data
async def get_events(cached_keys: list[str]) -> list[dict[str, str]]:
now = Time.clean(Time.now())
if not (api_data := API_FILE.load(per_entry=False, index=-1)):
log.info("Refreshing API cache")
api_data = await refresh_api_cache(now.timestamp())
API_FILE.write(api_data)
events = []
start_dt = now.delta(hours=-3)
end_dt = now.delta(minutes=30)
for stream_group in api_data:
sport = stream_group.get("league")
team_1, team_2 = stream_group.get("team1"), stream_group.get("team2")
if not (sport and team_1 and team_2):
continue
event_name = f"{team_1} vs {team_2}"
if f"[{sport}] {event_name} ({TAG})" in cached_keys:
continue
if not (event_ts := stream_group.get("ts")):
continue
event_dt = Time.from_ts(int(f"{event_ts}"[:-3]))
if not start_dt <= event_dt <= end_dt:
continue
if not (event_channels := stream_group.get("channels")):
continue
if not (event_links := event_channels[0].get("links")):
continue
event_url: str = event_links[0]
events.append(
{
"sport": sport,
"event": event_name,
"link": event_url,
}
)
return events
async def scrape(browser: Browser) -> None:
cached_urls = CACHE_FILE.load()
valid_urls = {k: v for k, v in cached_urls.items() if v["url"]}
valid_count = cached_count = len(valid_urls)
urls.update(valid_urls)
log.info(f"Loaded {cached_count} event(s) from cache")
log.info('Scraping from "https://sportzone.su"')
if events := await get_events(cached_urls.keys()):
log.info(f"Processing {len(events)} new URL(s)")
now = Time.clean(Time.now())
async with network.event_context(browser, stealth=False) as context:
for i, ev in enumerate(events, start=1):
async with network.event_page(context) as page:
handler = partial(
network.process_event,
url=(link := ev["link"]),
url_num=i,
page=page,
log=log,
)
url = await network.safe_process(
handler,
url_num=i,
semaphore=network.PW_S,
log=log,
)
sport, event = ev["sport"], ev["event"]
key = f"[{sport}] {event} ({TAG})"
tvg_id, logo = leagues.get_tvg_info(sport, event)
entry = {
"url": url,
"logo": logo,
"base": "https://vividmosaica.com/",
"timestamp": now.timestamp(),
"id": tvg_id or "Live.Event.us",
"link": link,
}
cached_urls[key] = entry
if url:
valid_count += 1
urls[key] = entry
log.info(f"Collected and cached {valid_count - cached_count} new event(s)")
else:
log.info("No new events found")
CACHE_FILE.write(cached_urls)

View file

@ -59,7 +59,7 @@ async def refresh_api_cache(now_ts: float) -> list[dict[str, Any]]:
for ev in data:
ev["ts"] = ev.pop("timestamp")
data[-1]["timestamp"] = now_ts
data[-1]["timestamp"] = now_ts
return data

View file

@ -99,7 +99,7 @@ async def process_event(
try:
try:
async with page.expect_response(strm_handler, timeout=3_250) as strm_resp:
async with page.expect_response(strm_handler, timeout=2_500) as strm_resp:
resp = await page.goto(
url,
wait_until="domcontentloaded",

View file

@ -1,7 +1,6 @@
#!/bin/bash
UA="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36 Edg/134.0.0.0"
MAX_JOBS=10
base_file="./M3U8/base.m3u8"
MAX_JOBS=10
README="./readme.md"
STATUSLOG=$(mktemp)
@ -24,7 +23,7 @@ get_status() {
-select_streams v:0 \
-show_entries stream=codec_name \
-of csv=p=0 \
-headers "User-Agent: $UA" \
-headers "User-Agent: curl/8.5.0" \
"$url" 2>&1
)

View file

@ -1,13 +1,21 @@
## Base Log @ 2026-03-06 09:02 UTC
## Base Log @ 2026-03-05 09:05 UTC
### ✅ Working Streams: 157<br>❌ Dead Streams: 4
### ✅ Working Streams: 149<br>❌ Dead Streams: 12
| Channel | Error (Code) | Link |
| ------- | ------------ | ---- |
| Altitude Sports | HTTP Error (403) | `http://mytvstream.net:8080/live/30550113/30550113/79545.m3u8` |
| Lifetime | HTTP Error (404) | `http://41.205.93.154/LIFETIME/index.m3u8` |
| NBC Sports Bay Area | HTTP Error (403) | `http://mytvstream.net:8080/live/30550113/30550113/9900.m3u8` |
| NBC Sports California | HTTP Error (403) | `http://mytvstream.net:8080/live/30550113/30550113/20940.m3u8` |
| CNBC | HTTP Error (404) | `http://41.205.93.154/CNBC/index.m3u8` |
| Cozi TV | HTTP Error (403) | `http://mytvstream.net:8080/live/30550113/30550113/11868.m3u8` |
| Discovery Family Channel | HTTP Error (403) | `http://mytvstream.net:8080/live/30550113/30550113/57347.m3u8` |
| FDSN Florida | HTTP Error (403) | `http://mytvstream.net:8080/live/30550113/30550113/46794.m3u8` |
| FDSN Oklahoma | HTTP Error (403) | `http://mytvstream.net:8080/live/30550113/30550113/20934.m3u8` |
| FDSN SoCal | HTTP Error (403) | `http://mytvstream.net:8080/live/30550113/30550113/221151.m3u8` |
| FDSN Wisconsin | HTTP Error (403) | `http://mytvstream.net:8080/live/30550113/30550113/78599.m3u8` |
| NHL Network | HTTP Error (000) | `http://mytvstream.net:8080/live/30550113/30550113/20179.m3u8` |
| Smithsonian Channel | HTTP Error (403) | `http://mytvstream.net:8080/live/30550113/30550113/31150.m3u8` |
| Space City Home Network | HTTP Error (403) | `http://mytvstream.net:8080/live/30550113/30550113/213668.m3u8` |
| SportsNet Pittsburgh | HTTP Error (403) | `http://mytvstream.net:8080/live/30550113/30550113/108178.m3u8` |
---
#### Base Channels URL
```