|
|
@ -316,10 +316,10 @@ struct Video
|
|
|
|
json.field "premiereTimestamp", self.premiere_timestamp.not_nil!.to_unix
|
|
|
|
json.field "premiereTimestamp", self.premiere_timestamp.not_nil!.to_unix
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
if self.player_response["streamingData"]?.try &.["hlsManifestUrl"]?
|
|
|
|
if player_response["streamingData"]?.try &.["hlsManifestUrl"]?
|
|
|
|
host_url = make_host_url(config, kemal_config)
|
|
|
|
host_url = make_host_url(config, kemal_config)
|
|
|
|
|
|
|
|
|
|
|
|
hlsvp = self.player_response["streamingData"]["hlsManifestUrl"].as_s
|
|
|
|
hlsvp = player_response["streamingData"]["hlsManifestUrl"].as_s
|
|
|
|
hlsvp = hlsvp.gsub("https://manifest.googlevideo.com", host_url)
|
|
|
|
hlsvp = hlsvp.gsub("https://manifest.googlevideo.com", host_url)
|
|
|
|
|
|
|
|
|
|
|
|
json.field "hlsUrl", hlsvp
|
|
|
|
json.field "hlsUrl", hlsvp
|
|
|
@ -489,7 +489,7 @@ struct Video
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
def live_now
|
|
|
|
def live_now
|
|
|
|
live_now = self.player_response["videoDetails"]?.try &.["isLive"]?.try &.as_bool
|
|
|
|
live_now = player_response["videoDetails"]?.try &.["isLive"]?.try &.as_bool
|
|
|
|
|
|
|
|
|
|
|
|
if live_now.nil?
|
|
|
|
if live_now.nil?
|
|
|
|
return false
|
|
|
|
return false
|
|
|
@ -536,7 +536,7 @@ struct Video
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
def keywords
|
|
|
|
def keywords
|
|
|
|
keywords = self.player_response["videoDetails"]?.try &.["keywords"]?.try &.as_a
|
|
|
|
keywords = player_response["videoDetails"]?.try &.["keywords"]?.try &.as_a
|
|
|
|
keywords ||= [] of String
|
|
|
|
keywords ||= [] of String
|
|
|
|
|
|
|
|
|
|
|
|
return keywords
|
|
|
|
return keywords
|
|
|
@ -545,7 +545,7 @@ struct Video
|
|
|
|
def fmt_stream(decrypt_function)
|
|
|
|
def fmt_stream(decrypt_function)
|
|
|
|
streams = [] of HTTP::Params
|
|
|
|
streams = [] of HTTP::Params
|
|
|
|
|
|
|
|
|
|
|
|
if fmt_streams = self.player_response["streamingData"]?.try &.["formats"]?
|
|
|
|
if fmt_streams = player_response["streamingData"]?.try &.["formats"]?
|
|
|
|
fmt_streams.as_a.each do |fmt_stream|
|
|
|
|
fmt_streams.as_a.each do |fmt_stream|
|
|
|
|
if !fmt_stream.as_h?
|
|
|
|
if !fmt_stream.as_h?
|
|
|
|
next
|
|
|
|
next
|
|
|
@ -619,7 +619,7 @@ struct Video
|
|
|
|
def adaptive_fmts(decrypt_function)
|
|
|
|
def adaptive_fmts(decrypt_function)
|
|
|
|
adaptive_fmts = [] of HTTP::Params
|
|
|
|
adaptive_fmts = [] of HTTP::Params
|
|
|
|
|
|
|
|
|
|
|
|
if fmts = self.player_response["streamingData"]?.try &.["adaptiveFormats"]?
|
|
|
|
if fmts = player_response["streamingData"]?.try &.["adaptiveFormats"]?
|
|
|
|
fmts.as_a.each do |adaptive_fmt|
|
|
|
|
fmts.as_a.each do |adaptive_fmt|
|
|
|
|
if !adaptive_fmt.as_h?
|
|
|
|
if !adaptive_fmt.as_h?
|
|
|
|
next
|
|
|
|
next
|
|
|
@ -712,12 +712,12 @@ struct Video
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
def storyboards
|
|
|
|
def storyboards
|
|
|
|
storyboards = self.player_response["storyboards"]?
|
|
|
|
storyboards = player_response["storyboards"]?
|
|
|
|
.try &.as_h
|
|
|
|
.try &.as_h
|
|
|
|
.try &.["playerStoryboardSpecRenderer"]?
|
|
|
|
.try &.["playerStoryboardSpecRenderer"]?
|
|
|
|
|
|
|
|
|
|
|
|
if !storyboards
|
|
|
|
if !storyboards
|
|
|
|
storyboards = self.player_response["storyboards"]?
|
|
|
|
storyboards = player_response["storyboards"]?
|
|
|
|
.try &.as_h
|
|
|
|
.try &.as_h
|
|
|
|
.try &.["playerLiveStoryboardSpecRenderer"]?
|
|
|
|
.try &.["playerLiveStoryboardSpecRenderer"]?
|
|
|
|
|
|
|
|
|
|
|
@ -784,13 +784,8 @@ struct Video
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
def paid
|
|
|
|
def paid
|
|
|
|
reason = self.player_response["playabilityStatus"]?.try &.["reason"]?
|
|
|
|
reason = player_response["playabilityStatus"]?.try &.["reason"]?
|
|
|
|
|
|
|
|
paid = reason == "This video requires payment to watch." ? true : false
|
|
|
|
if reason == "This video requires payment to watch."
|
|
|
|
|
|
|
|
paid = true
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
paid = false
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return paid
|
|
|
|
return paid
|
|
|
|
end
|
|
|
|
end
|
|
|
@ -836,7 +831,7 @@ struct Video
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
def length_seconds
|
|
|
|
def length_seconds
|
|
|
|
self.player_response["videoDetails"]["lengthSeconds"].as_s.to_i
|
|
|
|
player_response["videoDetails"]["lengthSeconds"].as_s.to_i
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
db_mapping({
|
|
|
|
db_mapping({
|
|
|
@ -1210,6 +1205,11 @@ def fetch_video(id, region)
|
|
|
|
|
|
|
|
|
|
|
|
player_json = JSON.parse(info["player_response"])
|
|
|
|
player_json = JSON.parse(info["player_response"])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
reason = player_json["playabilityStatus"]?.try &.["reason"]?.try &.as_s
|
|
|
|
|
|
|
|
if reason == "This video is not available."
|
|
|
|
|
|
|
|
raise "This video is not available."
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
title = player_json["videoDetails"]["title"].as_s
|
|
|
|
title = player_json["videoDetails"]["title"].as_s
|
|
|
|
author = player_json["videoDetails"]["author"]?.try &.as_s || ""
|
|
|
|
author = player_json["videoDetails"]["author"]?.try &.as_s || ""
|
|
|
|
ucid = player_json["videoDetails"]["channelId"]?.try &.as_s || ""
|
|
|
|
ucid = player_json["videoDetails"]["channelId"]?.try &.as_s || ""
|
|
|
|