@ -148,7 +148,6 @@ statistics = {
}
}
if config . statistics_enabled
if config . statistics_enabled
spawn do
spawn do
loop do
statistics = {
statistics = {
" version " = > " 2.0 " ,
" version " = > " 2.0 " ,
" software " = > SOFTWARE ,
" software " = > SOFTWARE ,
@ -162,12 +161,19 @@ if config.statistics_enabled
} ,
} ,
" metadata " = > {
" metadata " = > {
" updatedAt " = > Time . utc . to_unix ,
" updatedAt " = > Time . utc . to_unix ,
" lastChannelRefreshedAt " = > PG_DB . query_one? ( " SELECT updated FROM channels ORDER BY updated DESC LIMIT 1 " , as : Time ) . try & . to_unix || 0 ,
" lastChannelRefreshedAt " = > PG_DB . query_one? ( " SELECT updated FROM channels ORDER BY updated DESC LIMIT 1 " , as : Time ) . try & . to_unix || 0 _i64 ,
} ,
} ,
}
}
loop do
sleep 1 . minute
sleep 1 . minute
Fiber . yield
Fiber . yield
statistics [ " usage " ] . as ( Hash ) [ " users " ] . as ( Hash ) [ " total " ] = PG_DB . query_one ( " SELECT count(*) FROM users " , as : Int64 )
statistics [ " usage " ] . as ( Hash ) [ " users " ] . as ( Hash ) [ " activeHalfyear " ] = PG_DB . query_one ( " SELECT count(*) FROM users WHERE CURRENT_TIMESTAMP - updated < '6 months' " , as : Int64 )
statistics [ " usage " ] . as ( Hash ) [ " users " ] . as ( Hash ) [ " activeMonth " ] = PG_DB . query_one ( " SELECT count(*) FROM users WHERE CURRENT_TIMESTAMP - updated < '1 month' " , as : Int64 )
statistics [ " metadata " ] . as ( Hash ( String , Int64 ) ) [ " updatedAt " ] = Time . utc . to_unix
statistics [ " metadata " ] . as ( Hash ( String , Int64 ) ) [ " lastChannelRefreshedAt " ] = PG_DB . query_one? ( " SELECT updated FROM channels ORDER BY updated DESC LIMIT 1 " , as : Time ) . try & . to_unix || 0 _i64
end
end
end
end
end
end
@ -3223,7 +3229,8 @@ get "/api/v1/storyboards/:id" do |env|
storyboard = storyboard [ 0 ]
storyboard = storyboard [ 0 ]
end
end
webvtt = << - END_VTT
String . build do | str |
str << << - END_VTT
WEBVTT
WEBVTT
@ -3238,7 +3245,7 @@ get "/api/v1/storyboards/:id" do |env|
storyboard [ :storyboard_height ] . times do | j |
storyboard [ :storyboard_height ] . times do | j |
storyboard [ :storyboard_width ] . times do | k |
storyboard [ :storyboard_width ] . times do | k |
webvtt += << - END_CUE
str << << - END_CUE
#{start_time}.000 --> #{end_time}.000
#{start_time}.000 --> #{end_time}.000
#{url}#xywh=#{storyboard[:width] * k},#{storyboard[:height] * j},#{storyboard[:width]},#{storyboard[:height]}
#{url}#xywh=#{storyboard[:width] * k},#{storyboard[:height] * j},#{storyboard[:width]},#{storyboard[:height]}
@ -3250,8 +3257,7 @@ get "/api/v1/storyboards/:id" do |env|
end
end
end
end
end
end
end
webvtt
end
end
get " /api/v1/captions/:id " do | env |
get " /api/v1/captions/:id " do | env |
@ -3321,7 +3327,7 @@ get "/api/v1/captions/:id" do |env|
caption = caption [ 0 ]
caption = caption [ 0 ]
end
end
url = caption . baseUrl + " &tlang= #{ tlang } "
url = " #{ caption . baseUrl } &tlang= #{ tlang } "
# Auto-generated captions often have cues that aren't aligned properly with the video,
# Auto-generated captions often have cues that aren't aligned properly with the video,
# as well as some other markup that makes it cumbersome, so we try to fix that here
# as well as some other markup that makes it cumbersome, so we try to fix that here
@ -3329,7 +3335,8 @@ get "/api/v1/captions/:id" do |env|
caption_xml = client . get ( url ) . body
caption_xml = client . get ( url ) . body
caption_xml = XML . parse ( caption_xml )
caption_xml = XML . parse ( caption_xml )
webvtt = << - END_VTT
webvtt = String . build do | str |
str << << - END_VTT
WEBVTT
WEBVTT
Kind : captions
Kind : captions
Language : #{tlang || caption.languageCode}
Language : #{tlang || caption.languageCode}
@ -3359,16 +3366,16 @@ get "/api/v1/captions/:id" do |env|
text = " <v #{ md [ " name " ] } > #{ md [ " text " ] } </v> "
text = " <v #{ md [ " name " ] } > #{ md [ " text " ] } </v> "
end
end
webvtt += << - END_CUE
str << << - END_CUE
#{start_time} --> #{end_time}
#{start_time} --> #{end_time}
#{text}
#{text}
END_CUE
END_CUE
end
end
end
else
else
url += " &format=vtt "
webvtt = client . get ( " #{ url } &format=vtt " ) . body
webvtt = client . get ( url ) . body
end
end
if title = env . params . query [ " title " ]?
if title = env . params . query [ " title " ]?
@ -4833,43 +4840,6 @@ get "/videoplayback" do |env|
end
end
end
end
response = HTTP :: Client :: Response . new ( 403 )
5 . times do
begin
client = make_client ( URI . parse ( host ) , region )
response = client . head ( url , headers )
break
rescue Socket :: Addrinfo :: Error
if ! mns . empty?
mn = mns . pop
end
fvip = " 3 "
host = " https://r #{ fvip } --- #{ mn } .googlevideo.com "
rescue ex
end
end
if response . headers [ " Location " ]?
url = URI . parse ( response . headers [ " Location " ] )
host = url . host
env . response . headers [ " Access-Control-Allow-Origin " ] = " * "
url = url . full_path
url += " &host= #{ host } "
if region
url += " ®ion= #{ region } "
end
next env . redirect url
end
if response . status_code >= 400
env . response . status_code = response . status_code
next
end
if url . includes? " &file=seg.ts "
if url . includes? " &file=seg.ts "
if CONFIG . disabled? ( " livestreams " )
if CONFIG . disabled? ( " livestreams " )
env . response . status_code = 403
env . response . status_code = 403
@ -4957,11 +4927,7 @@ get "/videoplayback" do |env|
if location = response . headers [ " Location " ]?
if location = response . headers [ " Location " ]?
location = URI . parse ( location )
location = URI . parse ( location )
location = " #{ location . full_path } &host= #{ location . host } "
location = " #{ location . full_path } &host= #{ location . host } #{ region ? " ®ion= #{ region } " : " " } "
if region
location += " ®ion= #{ region } "
end
env . redirect location
env . redirect location
break
break