DISNEY-4K-SCRIPT/pydisney/disneyplus_parser.py

231 lines
6.3 KiB
Python

import os, clipboard, uuid, requests, re, sys, pycountry
from pydisney.m3u8_formater import M3U8
languageCodes = {
"zh-Hans": "zhoS",
"zh-Hant": "zhoT",
"pt-BR": "brPor",
"es-ES": "euSpa",
"en-GB": "enGB",
"en-PH": "enPH",
"nl-BE": "nlBE",
"fil": "enPH",
"yue": "zhoS",
'fr-CA':'caFra'
}
class Parser(object):
def __init__(self, m3u8, atmos_m3u8, is2ch=False):
self.m3u8 = m3u8
self.base = self.m3u8.rsplit('/', 1)[0] + '/'
if atmos_m3u8 is not None:
self.isAtmos = True
self.atmos_m3u8 = atmos_m3u8
self.atmos_base = self.atmos_m3u8.rsplit('/', 1)[0] + '/'
else:
self.isAtmos=False
self.is2ch = is2ch
def countrycode(self, code):
if code == 'cmn-Hans':
return 'Mandarin Chinese (Simplified)', 'zh-Hans'
elif code == 'cmn-Hant':
return 'Mandarin Chinese (Traditional)', 'zh-Hant'
elif code == 'es-419':
return 'Spanish', 'spa'
elif code == 'es-ES':
return 'European Spanish', 'euSpa'
elif code == 'pt-BR':
return 'Brazilian Portuguese', 'brPor'
elif code == 'pt-PT':
return 'Portuguese', 'por'
elif code == 'fr-CA':
return 'French Canadian', 'caFra'
elif code == 'fr-FR':
return 'French', 'fra'
lang_code = code[:code.index('-')] if '-' in code else code
lang = pycountry.languages.get(alpha_2=lang_code)
if lang is None:
lang = pycountry.languages.get(alpha_3=lang_code)
try:
languagecode = languageCodes[code]
except KeyError:
languagecode = lang.alpha_3
return lang.name, languagecode
def getCodec(self, codecs):
if ishevc or ishdr or ishdrdv:
search = 'hvc'
else:
search = 'avc'
l = []
for c in codecs.split(','):
if search in c:
l.append(c)
return l[-1]
def Parser(self):
AudioCodecs = None
AudioExtension = None
AudioList = []
subtitleList = []
forcedlist = []
videoList = []
added = set()
manifest_req = requests.get(self.m3u8)
video_manifest = M3U8(manifest_req.text)
if self.isAtmos:
atmos_req = requests.get(self.atmos_m3u8)
try:
audio_manifest = M3U8(atmos_req.text)
audio_base = self.atmos_base
audio_text = atmos_req.text
except ValueError:
audio_manifest = video_manifest
audio_base = self.base
audio_text = manifest_req.text
else:
audio_manifest = video_manifest
audio_base = self.base
audio_text = manifest_req.text
if self.isAtmos:
if 'atmos' in str(audio_text):
AudioCodecs = 'atmos'
AudioExtension = '.eac3'
else:
print('this item has no atmos.')
print('trying ac3 6ch...')
if 'eac-3' in str(audio_text):
AudioCodecs = 'eac-3'
AudioExtension = '.eac3'
else:
print('this item has no ac3 6ch, trying aac 2ch')
if 'aac-128k' in str(audio_text):
AudioCodecs = 'aac-128k'
AudioExtension = '.aac'
else:
sys.exit(1)
else:
if self.is2ch:
if 'aac-128k' in str(audio_text):
AudioCodecs = 'aac-128k'
AudioExtension = '.aac'
else:
print('this item has no aac 2ch')
sys.exit(1)
else:
if 'eac-3' in str(audio_text):
AudioCodecs = 'eac-3'
AudioExtension = '.eac3'
else:
print('this item has no ac3 6ch, trying aac 2ch')
if 'aac-128k' in str(audio_text):
AudioCodecs = 'aac-128k'
AudioExtension = '.aac'
else:
print('this item has no aac 2ch')
sys.exit(1)
if AudioCodecs is None or AudioExtension is None:
print('error while search for audio codec in m3u8 streams.')
sys.exit(1)
video_streams = [x for x in video_manifest.master_playlist if x['TAG'] == 'EXT-X-STREAM-INF']
audio_streams = [x for x in audio_manifest.master_playlist if x['TAG'] == 'EXT-X-MEDIA']
subs_streams = [x for x in video_manifest.master_playlist if x['TAG'] == 'EXT-X-MEDIA']
for video in video_streams:
if not video["URI"] in added:
bitrate = 'None'
if re.search('([0-9]*)k_', video["URI"]):
bitrate = str(re.search('([0-9]*)k_', video["URI"])[1])
else:
if re.search('([0-9]*)_complete', video["URI"]):
bitrate = str(re.search('([0-9]*)_complete', video["URI"])[1])
videoList.append(
{
'resolution': video["RESOLUTION"],
'codec': str(video["CODECS"]),
'bandwidth': str(video["BANDWIDTH"]),
'bitrate': bitrate,
'height': video["RESOLUTION"].rsplit('x', 1)[1],
'url': self.base+video["URI"]
}
)
added.add(video["URI"])
for m in audio_streams:
if m['TYPE'] == 'AUDIO' and m['GROUP-ID'] == AudioCodecs and m.get('CHARACTERISTICS') is None:
bitrate = 'None'
if re.search('([0-9]*)k_', m["URI"]):
bitrate = str(re.search('([0-9]*)k_', m["URI"])[1])
else:
if re.search('([0-9]*)_complete', m["URI"]):
bitrate = str(re.search('([0-9]*)_complete', m["URI"])[1])
bitrate = '768' if str(m['CHANNELS']) == '16/JOC' and int(bitrate) > 768 else bitrate
language, code = self.countrycode(m['LANGUAGE'])
Profile = m['GROUP-ID']
Profile = "aac" if "aac" in m['GROUP-ID'].lower() else Profile
Profile = "eac-3" if "eac-3" in m['GROUP-ID'].lower() else Profile
Profile = "atmos" if "joc" in m['GROUP-ID'].lower() else Profile
AudioList.append(
{
'language': str(language),
'code': str(code),
'bitrate': bitrate,
'codec': Profile,
'channels': str(m['CHANNELS'].replace('"', "").replace("/JOC", "")),
'url': audio_base+m['URI']
}
)
for m in subs_streams:
if m['TYPE'] == 'SUBTITLES' and m['FORCED'] == 'NO':
language, code = self.countrycode(m['LANGUAGE'])
subtitleList.append(
{
'language': str(language),
'code': str(code),
'url': self.base+m['URI']
}
)
if m['TYPE'] == 'SUBTITLES' and m['FORCED'] == 'NO' and m['LANGUAGE'] == 'en':
language, code = self.countrycode(m['LANGUAGE'])
subtitleList.append(
{
'language': str(language),
'code': 'sdh-' + str(code),
'url': self.base+m['URI']
}
)
if m['TYPE'] == 'SUBTITLES' and m['FORCED'] == 'YES':
language, code = self.countrycode(m['LANGUAGE'])
forcedlist.append(
{
'language': str(language),
'code': str(code),
'url': self.base+m['URI']
}
)
videoList = sorted(videoList, key=lambda k: int(k['bandwidth']))
print(videoList)
return videoList, AudioList, subtitleList, forcedlist, AudioExtension