ISM Atmos fix for Amazon
This commit is contained in:
parent
999c73d1e6
commit
11108223bc
Binary file not shown.
BIN
binaries/ffmpeg-6.1.1-essentials_build.7z
Normal file
BIN
binaries/ffmpeg-6.1.1-essentials_build.7z
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
linux_binaries/ffmpeg-n6.1-latest-linux64-gpl-6.1.tar.xz
Normal file
BIN
linux_binaries/ffmpeg-n6.1-latest-linux64-gpl-6.1.tar.xz
Normal file
Binary file not shown.
@ -405,17 +405,6 @@ def result(ctx, service, quality, closest_resolution, range_, wanted, alang, sla
|
||||
log.warning(f" - No {quality}p resolution available, using closest available: {closest_res}p")
|
||||
quality = closest_res
|
||||
|
||||
# Modified video track selection to choose lowest bitrate if vbitrate == min
|
||||
if isinstance(vbitrate, str) and vbitrate.lower() == "min":
|
||||
if not quality:
|
||||
quality = 1080
|
||||
available_bitrate = [int(track.bitrate) for track in title.tracks.videos if track.height == quality]
|
||||
if available_bitrate == []:
|
||||
log.error(" - No video tracks available")
|
||||
continue
|
||||
vbitrate = min(available_bitrate) / 1000
|
||||
log.warning(f" - Choosing minimum bitrate: {vbitrate}")
|
||||
|
||||
title.tracks.select_videos(by_quality=quality, by_vbitrate=vbitrate, by_range=range_, one_only=True)
|
||||
title.tracks.select_audios(by_language=alang, by_bitrate=abitrate, with_descriptive=audio_description)
|
||||
title.tracks.select_subtitles(by_language=slang, with_forced=True)
|
||||
@ -639,7 +628,9 @@ def result(ctx, service, quality, closest_resolution, range_, wanted, alang, sla
|
||||
if not executable:
|
||||
raise log.exit(" - Unable to find mp4decrypt binary")
|
||||
dec = os.path.splitext(track.locate())[0] + ".dec.mp4"
|
||||
os.makedirs(directories.temp, exist_ok=True)
|
||||
try:
|
||||
os.makedirs(directories.temp, exist_ok=True)
|
||||
subprocess.run([
|
||||
executable,
|
||||
"--show-progress",
|
||||
@ -657,6 +648,24 @@ def result(ctx, service, quality, closest_resolution, range_, wanted, alang, sla
|
||||
if keys:
|
||||
continue
|
||||
|
||||
if isinstance(track, AudioTrack) and track.descriptor == Track.Descriptor.ISM and track.atmos:
|
||||
#--enable-libmfx is the only difference between 6.1.1 and 7.X.
|
||||
#FFMPEG 6.1.1 is necessary as that version correctly puts in place an init.mp4 for EAC-3-JOC ie Atmos
|
||||
#https://github.com/GyanD/codexffmpeg/releases/tag/6.1.1
|
||||
#https://github.com/BtbN/FFmpeg-Builds/releases/tag/latest
|
||||
executable = shutil.which("ffmpeg")
|
||||
if not executable:
|
||||
raise log.exit(" - Unable to find ffmpeg binary")
|
||||
eac3 = os.path.splitext(track.locate())[0] + ".eac3"
|
||||
os.makedirs(directories.temp, exist_ok=True)
|
||||
try:
|
||||
os.makedirs(directories.temp, exist_ok=True)
|
||||
exec_string = f"{executable} -i {track.locate()} -hide_banner -loglevel error -map 0 -c:a copy {eac3}"
|
||||
subprocess.run(exec_string)
|
||||
except subprocess.CalledProcessError:
|
||||
raise log.exit(" - Failed!")
|
||||
track.swap(eac3)
|
||||
log.info(" + Fixed ISM Atmos")
|
||||
|
||||
if track.needs_repack or (config.decrypter == "mp4decrypt" and isinstance(track, (VideoTrack, AudioTrack))):
|
||||
log.info("Repackaging stream with FFmpeg (to fix malformed streams)")
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@ -237,21 +237,17 @@ class Track:
|
||||
self.psshPR = str(x).split("\"")[1].split(",")[-1]
|
||||
break
|
||||
|
||||
try:
|
||||
xml_str = base64.b64decode(self.psshPR).decode("utf-16-le", "ignore")
|
||||
xml_str = xml_str[xml_str.index("<"):]
|
||||
xml_str = base64.b64decode(self.psshPR).decode("utf-16-le", "ignore")
|
||||
xml_str = xml_str[xml_str.index("<"):]
|
||||
xml = load_xml(xml_str).find("DATA") # root: WRMHEADER
|
||||
|
||||
xml = load_xml(xml_str).find("DATA") # root: WRMHEADER
|
||||
self.kid = xml.findtext("KID") # v4.0.0.0
|
||||
if not self.kid: # v4.1.0.0
|
||||
self.kid = next(iter(xml.xpath("PROTECTINFO/KID/@VALUE")), None)
|
||||
if not self.kid: # v4.3.0.0
|
||||
self.kid = next(iter(xml.xpath("PROTECTINFO/KIDS/KID/@VALUE")), None) # can be multiple?
|
||||
|
||||
self.kid = xml.findtext("KID") # v4.0.0.0
|
||||
if not self.kid: # v4.1.0.0
|
||||
self.kid = next(iter(xml.xpath("PROTECTINFO/KID/@VALUE")), None)
|
||||
if not self.kid: # v4.3.0.0
|
||||
self.kid = next(iter(xml.xpath("PROTECTINFO/KIDS/KID/@VALUE")), None) # can be multiple?
|
||||
|
||||
self.kid = uuid.UUID(base64.b64decode(self.kid).hex()).bytes_le.hex()
|
||||
|
||||
except: pass
|
||||
self.kid = uuid.UUID(base64.b64decode(self.kid).hex()).bytes_le.hex()
|
||||
|
||||
if self.source == "NF":
|
||||
self.kid = "{}{}{}".format(
|
||||
@ -367,9 +363,11 @@ class Track:
|
||||
if not Path(save_path).is_file():
|
||||
save_path = save_path_orig.replace(".mp4", f".{str(self.language)[:2]}.m4a")
|
||||
if not Path(save_path).is_file():
|
||||
save_path = save_path_orig
|
||||
save_path = save_path_orig.replace(".mp4", f".eng.m4a") # This is a hack as only english atmos audio is available in Amazon
|
||||
if not Path(save_path).is_file():
|
||||
raise
|
||||
save_path = save_path_orig
|
||||
if not Path(save_path).is_file():
|
||||
raise
|
||||
else:
|
||||
asyncio.run(aria2c(
|
||||
self.url,
|
||||
@ -1134,8 +1132,17 @@ class Tracks:
|
||||
if not videos_quality:
|
||||
raise ValueError(f"There's no {by_quality}p resolution video track. Aborting.")
|
||||
self.videos = videos_quality
|
||||
if by_vbitrate:
|
||||
|
||||
# Modified video track selection to choose lowest bitrate if by_vbitrate == min
|
||||
if isinstance(by_vbitrate, str) and by_vbitrate.lower() == "min":
|
||||
available_bitrate = [int(track.bitrate) for track in self.videos]
|
||||
bitrate = min(available_bitrate) / 1001
|
||||
#if bitrate < 99999:
|
||||
# bitrate = bitrate / 1000
|
||||
self.videos = [x for x in self.videos if int(x.bitrate) <= int(bitrate * 1001)]
|
||||
elif by_vbitrate:
|
||||
self.videos = [x for x in self.videos if int(x.bitrate) <= int(by_vbitrate * 1001)]
|
||||
|
||||
if by_codec:
|
||||
codec_videos = list(filter(lambda x: any(y for y in self.VIDEO_CODEC_MAP[by_codec] if y in x.codec), self.videos))
|
||||
if not codec_videos and not should_fallback:
|
||||
|
||||
@ -217,28 +217,28 @@ def parse(*, url=None, data=None, source, session=None, downloader=None):
|
||||
# extra
|
||||
extra=(list(quality_level), list(stream_info),) # Either set size as a attribute of VideoTrack or append to extra here.
|
||||
))
|
||||
"""
|
||||
elif type_info == 'audio':
|
||||
atmos = ( str( quality_level.get('@HasAtmos', 'N/A') ).lower() == "true" ) or ( "ATM" in stream_info.get('@Name', 'N/A') )
|
||||
tracks.append(AudioTrack(
|
||||
id_=track_id,
|
||||
source=source,
|
||||
url=url,
|
||||
# metadata
|
||||
codec="E-AC3" if codec == "EC-3" else (codec or "").split(".")[0],
|
||||
language=lang,
|
||||
bitrate=bitrate,
|
||||
channels=quality_level.get('@Channels', 'N/A'),
|
||||
atmos=atmos,
|
||||
# switches/options
|
||||
descriptor=Track.Descriptor.ISM,
|
||||
# decryption
|
||||
needs_repack=True, # Necessary
|
||||
encrypted=encrypted,
|
||||
pssh=pssh,
|
||||
kid=kid,
|
||||
# extra
|
||||
extra=(dict(quality_level), dict(stream_info),)
|
||||
))
|
||||
"""
|
||||
if atmos: # Only appending Atmos streams -> Other audios can be obtained from Amazon MPD
|
||||
tracks.append(AudioTrack(
|
||||
id_=track_id,
|
||||
source=source,
|
||||
url=url,
|
||||
# metadata
|
||||
codec="E-AC3" if codec == "EC-3" else (codec or "").split(".")[0],
|
||||
language=lang,
|
||||
bitrate=bitrate,
|
||||
channels=quality_level.get('@Channels', 'N/A'),
|
||||
atmos=atmos,
|
||||
# switches/options
|
||||
descriptor=Track.Descriptor.ISM,
|
||||
# decryption
|
||||
needs_repack=True, # Necessary
|
||||
encrypted=encrypted,
|
||||
psshPR=pssh,
|
||||
kid=kid,
|
||||
# extra
|
||||
extra=(dict(quality_level), dict(stream_info),)
|
||||
))
|
||||
|
||||
return tracks
|
||||
|
||||
@ -296,8 +296,8 @@ async def m3u8dl(uri, out, track, headers=None, proxy=None):
|
||||
"-dv", "all",
|
||||
"-ds", "all",
|
||||
])
|
||||
if track.source != "HS":
|
||||
arguments.extend(["-M", "format=mp4"])
|
||||
#if track.source != "HS":
|
||||
# arguments.extend(["-M", "format=mp4"])
|
||||
else:
|
||||
raise ValueError(f"{track.__class__.__name__} not supported yet!")
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user