summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/invidious/videos.cr69
1 files changed, 69 insertions, 0 deletions
diff --git a/src/invidious/videos.cr b/src/invidious/videos.cr
index fcc23894..ab67004c 100644
--- a/src/invidious/videos.cr
+++ b/src/invidious/videos.cr
@@ -262,6 +262,75 @@ class Video
self.info["adaptive_fmts"].split(",") do |string|
adaptive_fmts << HTTP::Params.parse(string)
end
+ elsif self.info.has_key?("dashmpd")
+ client = make_client(YT_URL)
+ response = client.get(self.info["dashmpd"])
+ document = XML.parse_html(response.body)
+
+ document.xpath_nodes(%q(//adaptationset)).each do |adaptation_set|
+ mime_type = adaptation_set["mimetype"]
+
+ document.xpath_nodes(%q(.//representation)).each do |representation|
+ codecs = representation["codecs"]
+ itag = representation["id"]
+ bandwidth = representation["bandwidth"]
+ url = representation.xpath_node(%q(.//baseurl)).not_nil!.content
+
+ clen = url.match(/clen\/(?<clen>\d+)/).try &.["clen"]
+ clen ||= "0"
+ lmt = url.match(/lmt\/(?<lmt>\d+)/).not_nil!["lmt"]
+
+ segment_list = representation.xpath_node(%q(.//segmentlist)).not_nil!
+ init = segment_list.xpath_node(%q(.//initialization)).not_nil!["sourceurl"]
+ index = segment_list.xpath_node(%q(.//segmenturl)).not_nil!["media"]
+
+ # TODO: Replace with sane defaults when byteranges are absent
+ if init.starts_with? "sq"
+ init = "0-0"
+ index = "1-1"
+ else
+ init = init.lchop("range/")
+ index = index.lchop("range/")
+ index = "#{init.split("-")[1].to_i + 1}-#{index.split("-")[0].to_i}"
+ end
+
+ params = {
+ "type" => ["#{mime_type}; codecs=\"#{codecs}\""],
+ "url" => [url],
+ "projection_type" => ["1"],
+ "index" => [index],
+ "init" => [init],
+ "xtags" => [] of String,
+ "lmt" => [lmt],
+ "clen" => [clen],
+ "bitrate" => [bandwidth],
+ "itag" => [itag],
+ }
+
+ if mime_type == "video/mp4"
+ width = representation["width"]?
+ height = representation["height"]?
+ fps = representation["framerate"]?
+
+ metadata = itag_to_metadata?(itag)
+ if metadata
+ width ||= metadata["width"]?
+ height ||= metadata["height"]?
+ fps ||= metadata["fps"]?
+ end
+
+ if width && height
+ params["size"] = ["#{width}x#{height}"]
+ end
+
+ if width
+ params["quality_label"] = ["#{height}p"]
+ end
+ end
+
+ adaptive_fmts << HTTP::Params.new(params)
+ end
+ end
end
if adaptive_fmts[0]? && adaptive_fmts[0]["s"]?