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