Linux support WIP
This commit is contained in:
parent
f8c4accd54
commit
13a9a72b80
38
README.md
38
README.md
@ -6,15 +6,45 @@ Modified to remove Playready DRM instead of Widevine.
|
|||||||
- Progress Bars for decryption ([mp4decrypt](https://github.com/chu23465/bentoOldFork), Shaka)
|
- Progress Bars for decryption ([mp4decrypt](https://github.com/chu23465/bentoOldFork), Shaka)
|
||||||
- Refresh Token fixed for Amazon service
|
- Refresh Token fixed for Amazon service
|
||||||
- Reprovision .prd after a week
|
- Reprovision .prd after a week
|
||||||
- ISM manifest support (Microsoft Smooth Streaming) (Few features to be added)
|
- ISM manifest support (Microsoft Smooth Streaming) (WIP/Experimental)
|
||||||
- N_m3u8DL-RE downloader support
|
- N_m3u8DL-RE downloader support
|
||||||
|
|
||||||
|
## Broken
|
||||||
|
- `--bitrate CVBR+CBR` is currently broken
|
||||||
|
- Atmos audio with ISM manifest (Amazon) is currently broken (Needs a working init.mp4). If the title has the atmos audio in MPD then it should work.
|
||||||
|
- ATVP service is currently broken in dev branch
|
||||||
|
- Netflix service is currently broken (will probably be fixed Soon™)
|
||||||
|
|
||||||
|
If anyone has any idea how to fix above issues, feel free to open a pull request.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
1. Run `install.bat`
|
1. Make sure git is installed in your system by running `git --version`. If not refer to [link](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
|
||||||
|
|
||||||
2. Activate venv using `venv.cmd`.
|
2. Choose a branch, either `dev` or `main`. Use below command to download. (Recommended instead of downloading zip)
|
||||||
|
```bash
|
||||||
|
git clone -b <branch-name> --single-branch https://github.com/chu23465/VT-PR
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Navigate and find `install.bat`
|
||||||
|
|
||||||
|
4. Run `install.bat`
|
||||||
|
|
||||||
|
5. Activate venv using `venv.cmd`.
|
||||||
|
|
||||||
|
6. Run desired command using poetry.
|
||||||
|
|
||||||
|
|
||||||
|
## Updating
|
||||||
|
|
||||||
|
1. Backup your `vinetrimmer/Cookies/`, `vinetrimmer/Cache/`, `/Downloads` directories just in case.
|
||||||
|
|
||||||
|
2. Open a command prompt and navigate your `VT-PR` directory.
|
||||||
|
|
||||||
|
3. Recall the branch you downloaded and modify below command accordingly:
|
||||||
|
```bash
|
||||||
|
git pull origin <branch-name>
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
### Config
|
### Config
|
||||||
@ -124,7 +154,7 @@ Below flags to be passed after the `AMZN` or `Amazon` keyword in command.
|
|||||||
| -ism, --ism | Set manifest override to SmoothStreaming. Defaults to DASH w/o this flag. |
|
| -ism, --ism | Set manifest override to SmoothStreaming. Defaults to DASH w/o this flag. |
|
||||||
| -?, -h, --help | Show this message and exit. |
|
| -?, -h, --help | Show this message and exit. |
|
||||||
|
|
||||||
To get UHD/4k with Amazon, navigate to -
|
To get Atmos/UHD/4k with Amazon, navigate to -
|
||||||
|
|
||||||
```
|
```
|
||||||
https://www.primevideo.com/region/eu/ontv/code?ref_=atv_auth_red_aft
|
https://www.primevideo.com/region/eu/ontv/code?ref_=atv_auth_red_aft
|
||||||
|
BIN
linux_binaries/N_m3u8DL-RE
Normal file
BIN
linux_binaries/N_m3u8DL-RE
Normal file
Binary file not shown.
BIN
linux_binaries/mkvtoolnix.AppImage
Normal file
BIN
linux_binaries/mkvtoolnix.AppImage
Normal file
Binary file not shown.
BIN
linux_binaries/mp4decrypt
Normal file
BIN
linux_binaries/mp4decrypt
Normal file
Binary file not shown.
BIN
linux_binaries/mp4dump
Normal file
BIN
linux_binaries/mp4dump
Normal file
Binary file not shown.
BIN
linux_binaries/packager
Normal file
BIN
linux_binaries/packager
Normal file
Binary file not shown.
@ -98,7 +98,7 @@ def get_cdm(log, service, profile=None, cdm_name=None):
|
|||||||
device = Device.load(os.path.join(directories.devices, f"{cdm_name}.wvd"))
|
device = Device.load(os.path.join(directories.devices, f"{cdm_name}.wvd"))
|
||||||
except:
|
except:
|
||||||
device_path = os.path.abspath(os.path.join(directories.devices, f"{cdm_name}.prd"))
|
device_path = os.path.abspath(os.path.join(directories.devices, f"{cdm_name}.prd"))
|
||||||
if ( int( time.time() ) - int( os.path.getmtime( device_path ) ) ) > 600000: #roughly a week
|
if ( int( time.time() ) - int( os.path.getmtime( device_path ) ) ) > 160000: #roughly 2 days
|
||||||
try:
|
try:
|
||||||
reprovision_device(device_path)
|
reprovision_device(device_path)
|
||||||
log.info(f" + Reprovisioned Playready Device (.prd) file, {cdm_name}")
|
log.info(f" + Reprovisioned Playready Device (.prd) file, {cdm_name}")
|
||||||
|
@ -217,6 +217,7 @@ def parse(*, url=None, data=None, source, session=None, downloader=None):
|
|||||||
# extra
|
# extra
|
||||||
extra=(list(quality_level), list(stream_info),) # Either set size as a attribute of VideoTrack or append to extra here.
|
extra=(list(quality_level), list(stream_info),) # Either set size as a attribute of VideoTrack or append to extra here.
|
||||||
))
|
))
|
||||||
|
"""
|
||||||
elif type_info == 'audio':
|
elif type_info == 'audio':
|
||||||
atmos = ( str( quality_level.get('@HasAtmos', 'N/A') ).lower() == "true" ) or ( "ATM" in stream_info.get('@Name', 'N/A') )
|
atmos = ( str( quality_level.get('@HasAtmos', 'N/A') ).lower() == "true" ) or ( "ATM" in stream_info.get('@Name', 'N/A') )
|
||||||
tracks.append(AudioTrack(
|
tracks.append(AudioTrack(
|
||||||
@ -224,7 +225,7 @@ def parse(*, url=None, data=None, source, session=None, downloader=None):
|
|||||||
source=source,
|
source=source,
|
||||||
url=url,
|
url=url,
|
||||||
# metadata
|
# metadata
|
||||||
codec=(codec or "").split(".")[0],
|
codec="E-AC3" if codec == "EC-3" else (codec or "").split(".")[0],
|
||||||
language=lang,
|
language=lang,
|
||||||
bitrate=bitrate,
|
bitrate=bitrate,
|
||||||
channels=quality_level.get('@Channels', 'N/A'),
|
channels=quality_level.get('@Channels', 'N/A'),
|
||||||
@ -232,11 +233,12 @@ def parse(*, url=None, data=None, source, session=None, downloader=None):
|
|||||||
# switches/options
|
# switches/options
|
||||||
descriptor=Track.Descriptor.ISM,
|
descriptor=Track.Descriptor.ISM,
|
||||||
# decryption
|
# decryption
|
||||||
needs_repack=False, # Necessary
|
needs_repack=True, # Necessary
|
||||||
encrypted=encrypted,
|
encrypted=encrypted,
|
||||||
pssh=pssh,
|
pssh=pssh,
|
||||||
kid=kid,
|
kid=kid,
|
||||||
# extra
|
# extra
|
||||||
extra=(dict(quality_level), dict(stream_info),)
|
extra=(dict(quality_level), dict(stream_info),)
|
||||||
))
|
))
|
||||||
|
"""
|
||||||
return tracks
|
return tracks
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from sys import platform
|
||||||
|
|
||||||
import base64
|
import base64
|
||||||
import hashlib
|
import hashlib
|
||||||
import json
|
import json
|
||||||
@ -75,7 +77,7 @@ class Amazon(BaseService):
|
|||||||
@click.option("-c", "--cdn", default=None, type=str,
|
@click.option("-c", "--cdn", default=None, type=str,
|
||||||
help="CDN to download from, defaults to the CDN with the highest weight set by Amazon.")
|
help="CDN to download from, defaults to the CDN with the highest weight set by Amazon.")
|
||||||
# UHD, HD, SD. UHD only returns HEVC, ever, even for <=HD only content
|
# UHD, HD, SD. UHD only returns HEVC, ever, even for <=HD only content
|
||||||
@click.option("-vq", "--vquality", default="UHD",
|
@click.option("-vq", "--vquality", default="HD",
|
||||||
type=click.Choice(["SD", "HD", "UHD"], case_sensitive=False),
|
type=click.Choice(["SD", "HD", "UHD"], case_sensitive=False),
|
||||||
help="Manifest quality to request.")
|
help="Manifest quality to request.")
|
||||||
@click.option("-s", "--single", is_flag=True, default=False,
|
@click.option("-s", "--single", is_flag=True, default=False,
|
||||||
@ -83,7 +85,7 @@ class Amazon(BaseService):
|
|||||||
@click.option("-am", "--amanifest", default="H265",
|
@click.option("-am", "--amanifest", default="H265",
|
||||||
type=click.Choice(["CVBR", "CBR", "H265"], case_sensitive=False),
|
type=click.Choice(["CVBR", "CBR", "H265"], case_sensitive=False),
|
||||||
help="Manifest to use for audio. Defaults to H265 if the video manifest is missing 640k audio.")
|
help="Manifest to use for audio. Defaults to H265 if the video manifest is missing 640k audio.")
|
||||||
@click.option("-aq", "--aquality", default="SD",
|
@click.option("-aq", "--aquality", default="HD",
|
||||||
type=click.Choice(["SD", "HD", "UHD"], case_sensitive=False),
|
type=click.Choice(["SD", "HD", "UHD"], case_sensitive=False),
|
||||||
help="Manifest quality to request for audio. Defaults to the same as --quality.")
|
help="Manifest quality to request for audio. Defaults to the same as --quality.")
|
||||||
@click.option("-ism", "--ism", is_flag=True, default=False,
|
@click.option("-ism", "--ism", is_flag=True, default=False,
|
||||||
@ -115,7 +117,11 @@ class Amazon(BaseService):
|
|||||||
|
|
||||||
self.cdm = ctx.obj.cdm
|
self.cdm = ctx.obj.cdm
|
||||||
self.profile = ctx.obj.profile
|
self.profile = ctx.obj.profile
|
||||||
|
if "linux" in platform:
|
||||||
|
import yaml
|
||||||
|
#Read YAML file
|
||||||
|
with open("/content/vinetrimmer/config/Services/amazon.yml", 'r') as stream:
|
||||||
|
self.config = yaml.safe_load(stream)
|
||||||
self.region: dict[str, str] = {}
|
self.region: dict[str, str] = {}
|
||||||
self.endpoints: dict[str, str] = {}
|
self.endpoints: dict[str, str] = {}
|
||||||
self.device: dict[str, str] = {}
|
self.device: dict[str, str] = {}
|
||||||
@ -411,6 +417,7 @@ class Amazon(BaseService):
|
|||||||
video_codec="H265" if manifest_type == "H265" else "H264",
|
video_codec="H265" if manifest_type == "H265" else "H264",
|
||||||
bitrate_mode="CVBR" if manifest_type != "CBR" else "CBR",
|
bitrate_mode="CVBR" if manifest_type != "CBR" else "CBR",
|
||||||
quality=self.aquality or self.vquality,
|
quality=self.aquality or self.vquality,
|
||||||
|
manifest_type="DASH",
|
||||||
hdr=None,
|
hdr=None,
|
||||||
ignore_errors=True
|
ignore_errors=True
|
||||||
)
|
)
|
||||||
@ -506,6 +513,7 @@ class Amazon(BaseService):
|
|||||||
|
|
||||||
# replace the audio tracks with DV manifest version if atmos is present
|
# replace the audio tracks with DV manifest version if atmos is present
|
||||||
if any(x for x in uhd_audio_mpd.audios if x.atmos):
|
if any(x for x in uhd_audio_mpd.audios if x.atmos):
|
||||||
|
print("Hello")
|
||||||
tracks.audios = uhd_audio_mpd.audios
|
tracks.audios = uhd_audio_mpd.audios
|
||||||
|
|
||||||
for video in tracks.videos:
|
for video in tracks.videos:
|
||||||
|
@ -62,6 +62,7 @@ class Max(BaseService):
|
|||||||
self.acodec = ctx.parent.params["acodec"]
|
self.acodec = ctx.parent.params["acodec"]
|
||||||
self.range = ctx.parent.params["range_"]
|
self.range = ctx.parent.params["range_"]
|
||||||
self.alang = ctx.parent.params["alang"]
|
self.alang = ctx.parent.params["alang"]
|
||||||
|
self.quality = ctx.parent.params["quality"] or 1080
|
||||||
# self.api_region = self.config.get(ctx.obj.profile, {}).get('api_region', 'comet-latam')
|
# self.api_region = self.config.get(ctx.obj.profile, {}).get('api_region', 'comet-latam')
|
||||||
|
|
||||||
# self.license_api = None
|
# self.license_api = None
|
||||||
|
@ -15,6 +15,7 @@ import yaml
|
|||||||
from vinetrimmer import config
|
from vinetrimmer import config
|
||||||
from vinetrimmer.utils.collections import as_list
|
from vinetrimmer.utils.collections import as_list
|
||||||
|
|
||||||
|
from sys import platform
|
||||||
|
|
||||||
def load_yaml(path):
|
def load_yaml(path):
|
||||||
if not os.path.isfile(path):
|
if not os.path.isfile(path):
|
||||||
@ -239,12 +240,11 @@ async def saldl(uri, out, headers=None, proxy=None):
|
|||||||
|
|
||||||
|
|
||||||
async def m3u8dl(uri: str, out: str, track):
|
async def m3u8dl(uri: str, out: str, track):
|
||||||
executable = shutil.which("N_m3u8DL-RE") or shutil.which("m3u8DL")
|
executable = shutil.which("N_m3u8DL-RE") or shutil.which("m3u8DL") or "/usr/bin/N_m3u8DL-RE"
|
||||||
if not executable:
|
if not executable:
|
||||||
raise EnvironmentError("N_m3u8DL-RE executable not found...")
|
raise EnvironmentError("N_m3u8DL-RE executable not found...")
|
||||||
|
|
||||||
ffmpeg_binary = shutil.which("ffmpeg")
|
ffmpeg_binary = shutil.which("ffmpeg") or "/usr/bin/ffmpeg"
|
||||||
|
|
||||||
arguments = [
|
arguments = [
|
||||||
executable,
|
executable,
|
||||||
uri,
|
uri,
|
||||||
@ -257,11 +257,10 @@ async def m3u8dl(uri: str, out: str, track):
|
|||||||
"--download-retry-count", "8",
|
"--download-retry-count", "8",
|
||||||
"--ffmpeg-binary-path", ffmpeg_binary,
|
"--ffmpeg-binary-path", ffmpeg_binary,
|
||||||
"--binary-merge",
|
"--binary-merge",
|
||||||
"--decryption-engine", "SHAKA_PACKAGER",
|
|
||||||
"--http-request-timeout", "8",
|
|
||||||
"--live-real-time-merge"
|
|
||||||
]
|
]
|
||||||
|
if not ("linux" in platform):
|
||||||
|
arguments.append("--http-request-timeout")
|
||||||
|
arguments.append("8")
|
||||||
if track.__class__.__name__ == "VideoTrack":
|
if track.__class__.__name__ == "VideoTrack":
|
||||||
if track.height:
|
if track.height:
|
||||||
arguments.extend([
|
arguments.extend([
|
||||||
|
Loading…
x
Reference in New Issue
Block a user