80 lines
2.7 KiB
Python
Raw Permalink Normal View History

2025-03-18 00:17:27 +05:30
import xmltodict
import asyncio
import base64
import json
import math
import os
import re
import urllib.parse
import uuid
from copy import copy
from hashlib import md5
import requests
from langcodes import Language
from langcodes.tag_parser import LanguageTagError
from vinetrimmer import config
from vinetrimmer.objects import AudioTrack, TextTrack, Track, Tracks, VideoTrack
2025-03-18 00:23:51 +05:30
from vinetrimmer.utils import Cdm
2025-03-18 00:17:27 +05:30
from vinetrimmer.utils.io import aria2c
2025-03-18 00:23:51 +05:30
from vinetrimmer.utils.xml import load_xml
2025-03-18 00:17:27 +05:30
from vinetrimmer.vendor.pymp4.parser import Box
2025-03-18 00:23:51 +05:30
2025-03-18 00:17:27 +05:30
def parse(*, url=None, data=None, source, session=None, downloader=None):
"""
Convert an Smooth Streaming ISM (IIS Smooth Streaming Manifest) document to a Tracks object
with video, audio and subtitle track objects where available.
:param url: URL of the ISM document.
:param data: The ISM document as a string.
:param source: Source tag for the returned tracks.
:param session: Used for any remote calls, e.g. getting the MPD document from an URL.
Can be useful for setting custom headers, proxies, etc.
:param downloader: Downloader to use. Accepted values are None (use requests to download)
and aria2c.
Don't forget to manually handle the addition of any needed or extra information or values
like `encrypted`, `pssh`, `hdr10`, `dv`, etc. Essentially anything that is per-service
should be looked at. Some of these values like `pssh` will be attempted to be set automatically
if possible but if you definitely have the values in the service, then set them.
Examples:
url = "https://test.playready.microsoft.com/media/profficialsite/tearsofsteel_4k.ism.smoothstreaming/manifest" # https://testweb.playready.microsoft.com/Content/Content2X
session = requests.Session(headers={"X-Example": "foo"})
tracks = Tracks.from_ism(
url,
session=session,
source="MICROSOFT",
)
url = "https://test.playready.microsoft.com/media/profficialsite/tearsofsteel_4k.ism.smoothstreaming/manifest"
session = requests.Session(headers={"X-Example": "foo"})
tracks = Tracks.from_ism(url=url, data=session.get(url).text, source="MICROSOFT")
"""
2025-03-18 00:23:51 +05:30
tracks = []
2025-03-18 00:17:27 +05:30
if not data:
if not url:
raise ValueError("Neither a URL nor a document was provided to Tracks.from_ism")
base_url = url.rsplit('/', 1)[0] + '/'
if downloader is None:
data = (session or requests).get(url).text
elif downloader == "aria2c":
out = os.path.join(config.directories.temp, url.split("/")[-1])
asyncio.run(aria2c(url, out))
with open(out, encoding="utf-8") as fd:
data = fd.read()
try:
os.unlink(out)
except FileNotFoundError:
pass
else:
raise ValueError(f"Unsupported downloader: {downloader}")
2025-03-18 00:23:51 +05:30
root = load_xml(data)
if root.tag != "SmoothStreamingMedia":
2025-03-18 00:17:27 +05:30
raise ValueError("Non-ISM document provided to Tracks.from_ism")