commit
2166acfc0b
@ -0,0 +1,2 @@ |
||||
# Virtual Environment |
||||
venv/ |
@ -0,0 +1,35 @@ |
||||
# IPTV Network Extract |
||||
|
||||
Extracts m3u8 links for multiple IPTVs. |
||||
|
||||
## Channels Supported |
||||
|
||||
+ Italy 🇮🇹 |
||||
+ Discovery Network |
||||
+ realtime |
||||
+ nove |
||||
+ dmax |
||||
+ giallo |
||||
+ k-2 |
||||
+ frisbee |
||||
+ motor-trend |
||||
+ food-network |
||||
+ home-and-garden-tv |
||||
+ eurosport1\* |
||||
+ eurosport2\* |
||||
|
||||
\* the service is irregular/occasional |
||||
|
||||
## Use |
||||
|
||||
To extract the link for `dmax` and put it in `stdout`: |
||||
|
||||
```sh |
||||
./iptv_network_extract.py -c dmax |
||||
``` |
||||
|
||||
You can pipe the link to a player like `mpv`: |
||||
|
||||
```sh |
||||
./iptv_network_extract.py | mpv --playlist=- |
||||
``` |
@ -0,0 +1,68 @@ |
||||
{ |
||||
"realtime":{ |
||||
"url":"https://it.dplay.com/ajax/playbackjson/channel/2", |
||||
"data":{ |
||||
"referer":"https://it.dplay.com/realtime/" |
||||
} |
||||
}, |
||||
"nove":{ |
||||
"url":"https://it.dplay.com/ajax/playbackjson/channel/3", |
||||
"data":{ |
||||
"referer":"https://it.dplay.com/nove/" |
||||
} |
||||
}, |
||||
"dmax":{ |
||||
"url":"https://it.dplay.com/ajax/playbackjson/channel/5", |
||||
"data":{ |
||||
"referer":"https://it.dplay.com/dmax/" |
||||
} |
||||
}, |
||||
"giallo":{ |
||||
"url":"https://it.dplay.com/ajax/playbackjson/channel/6", |
||||
"data":{ |
||||
"referer":"https://it.dplay.com/giallo/" |
||||
} |
||||
}, |
||||
"k-2":{ |
||||
"url":"https://it.dplay.com/ajax/playbackjson/channel/7", |
||||
"data":{ |
||||
"referer":"https://it.dplay.com/k-2/" |
||||
} |
||||
}, |
||||
"frisbee":{ |
||||
"url":"https://it.dplay.com/ajax/playbackjson/channel/8", |
||||
"data":{ |
||||
"referer":"https://it.dplay.com/frisbee/" |
||||
} |
||||
}, |
||||
"motor-trend":{ |
||||
"url":"https://it.dplay.com/ajax/playbackjson/channel/19", |
||||
"data":{ |
||||
"referer":"https://it.dplay.com/motor-trend/" |
||||
} |
||||
}, |
||||
"food-network":{ |
||||
"url":"https://it.dplay.com/ajax/playbackjson/channel/21", |
||||
"data":{ |
||||
"referer":"https://it.dplay.com/food-network/" |
||||
} |
||||
}, |
||||
"home-and-garden-tv":{ |
||||
"url":"https://it.dplay.com/ajax/playbackjson/channel/36", |
||||
"data":{ |
||||
"referer":"https://it.dplay.com/home-and-garden-tv/" |
||||
} |
||||
}, |
||||
"eurosport1":{ |
||||
"url":"https://it.dplay.com/ajax/playbackjson/channel/49", |
||||
"data":{ |
||||
"referer":"https://it.dplay.com/eurosport1/" |
||||
} |
||||
}, |
||||
"eurosport2":{ |
||||
"url":"https://it.dplay.com/ajax/playbackjson/channel/50", |
||||
"data":{ |
||||
"referer":"https://it.dplay.com/eurosport2/" |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,80 @@ |
||||
#!/usr/bin/env python3 |
||||
|
||||
import sys |
||||
import json |
||||
import argparse |
||||
import requests |
||||
|
||||
|
||||
with open('channels.json', 'r') as myfile: |
||||
channelsDict = json.loads(myfile.read()) |
||||
|
||||
parser = argparse.ArgumentParser( |
||||
prog='IPTV Network Extract', |
||||
description='Extracts m3u8 links for multiple IPTVs' |
||||
) |
||||
parser.add_argument( |
||||
"-c", "--channel", |
||||
nargs=1, |
||||
choices=list(channelsDict.keys()), |
||||
required=True, |
||||
help="TV channel name" |
||||
) |
||||
parser.add_argument( |
||||
"--version", |
||||
action="version", |
||||
version="%(prog)s 0.1" |
||||
) |
||||
args = parser.parse_args() |
||||
|
||||
channel = args.channel[0] |
||||
|
||||
HEADERS: dict = { |
||||
"User-Agent": ("Mozilla/5.0 (Windows NT 10.0; rv:75.0) " |
||||
"Gecko/20100101 Firefox/75.0"), |
||||
"Accept-Language": "en-US;q=0.9,en;q=0.8,en-GB;q=0.7", |
||||
"X-Requested-With": "XMLHttpRequest", |
||||
"Connection": "keep-alive", |
||||
"Referer": str(channelsDict[channel]["data"]["referer"]), |
||||
"cb-enabled": "enabled", |
||||
"DNT": "1", |
||||
"Pragma": "no-cache", |
||||
"Cache-Control": "no-cache" |
||||
} |
||||
|
||||
content = requests.get( |
||||
channelsDict[channel]["url"], |
||||
headers=HEADERS, |
||||
timeout=(3, 300) |
||||
) |
||||
|
||||
content = { |
||||
"status_code": content.status_code, |
||||
"content": content.content, |
||||
"encoding": content.encoding, |
||||
"cookies": content.cookies, |
||||
"request": content.request, |
||||
"url": content.url, |
||||
"reason": content.reason, |
||||
"headers": content.headers, |
||||
"elapsed": content.elapsed, |
||||
"history": content.history |
||||
} |
||||
|
||||
if content["status_code"] == 200: |
||||
uglyPayload = json.loads(content["content"].decode('unicode_escape')[1:-1]) |
||||
print( |
||||
uglyPayload["data"]["attributes"]["streaming"]["hls"]["url"], |
||||
sep='', |
||||
end='', |
||||
file=sys.stdout, |
||||
flush=False |
||||
) |
||||
else: |
||||
print( |
||||
"[ERROR] Http status code: " + str(content["status_code"]), |
||||
sep='', |
||||
end='\n', |
||||
file=sys.stderr, |
||||
) |
||||
sys.exit(1) |
@ -0,0 +1,2 @@ |
||||
pylint>=2.6.0 |
||||
flake8>=3.8.3 |
@ -0,0 +1 @@ |
||||
requests>=2.24.0 |
Loading…
Reference in new issue