diff --git a/shard.lock b/shard.lock
index 2c867ae4..1e791997 100644
--- a/shard.lock
+++ b/shard.lock
@@ -6,7 +6,7 @@ shards:
kemal:
github: kemalcr/kemal
- commit: 8cb9770ec3c6cf5897e644229dad8d0b5c360941
+ version: 0.21.0
kilt:
github: jeromegn/kilt
diff --git a/shard.yml b/shard.yml
index c0be6d9b..dc5cb756 100644
--- a/shard.yml
+++ b/shard.yml
@@ -11,7 +11,6 @@ targets:
dependencies:
kemal:
github: kemalcr/kemal
- branch: master
pg:
github: will/crystal-pg
diff --git a/views/index.ecr b/src/views/index.ecr
similarity index 100%
rename from views/index.ecr
rename to src/views/index.ecr
diff --git a/views/layout.ecr b/src/views/layout.ecr
similarity index 79%
rename from views/layout.ecr
rename to src/views/layout.ecr
index a0b9813d..611cf691 100644
--- a/views/layout.ecr
+++ b/src/views/layout.ecr
@@ -11,6 +11,9 @@
+
diff --git a/views/listen.ecr b/src/views/listen.ecr
similarity index 100%
rename from views/listen.ecr
rename to src/views/listen.ecr
diff --git a/views/watch.ecr b/src/views/watch.ecr
similarity index 100%
rename from views/watch.ecr
rename to src/views/watch.ecr
diff --git a/src/visor.cr b/src/visor.cr
index 1b9a9b2d..1a484c38 100644
--- a/src/visor.cr
+++ b/src/visor.cr
@@ -3,20 +3,143 @@ require "json"
require "kemal"
require "pg"
require "xml"
-require "./url_encoded"
+
+class AdaptiveFmts
+ JSON.mapping(
+ clen: Int32,
+ url: String,
+ lmt: Int64,
+ index: String,
+ fps: Int32,
+ itag: Int32,
+ projection_type: Int32,
+ size: String,
+ init: String,
+ quality_label: String,
+ bitrate: Int32,
+ type: String
+ )
+end
+
+class URLEncodedFmtStreamMap
+ JSON.mapping(
+ url: String,
+ itag: Int32,
+ fallback_host: String,
+ quality: String,
+ type: String
+ )
+end
+
+class CaptionTracks
+ JSON.mapping(
+ v: String,
+ lc: String,
+ t: String,
+ u: String
+ )
+end
+
+class CaptionTranslationLanguages
+ JSON.mapping(
+ lc: String,
+ n: String
+ )
+end
+
+class VideoInfo
+ JSON.mapping(
+ cver: String,
+ length_seconds: Int32,
+ iurlhq720: String,
+ vm: String,
+ ypc_ad_indicator: Int32,
+ hash_cc: Bool,
+ dashmpd: String,
+ iv3_module: Int32,
+ iurlmq: String,
+ no_get_video_log: Int32,
+ cc_font: Int32,
+ allowed_ads: String,
+ oid: String,
+ iv_invideo_url: String,
+ cc_asr: Int32,
+ relative_loudness: Float64,
+ video_verticals: String,
+ default_audio_track_index: Int32,
+ loudness: Float64,
+ ptchn: String,
+ csn: String,
+ pltype: String,
+ author: String,
+ # caption_audio_tracks:
+ videostats_playback_base_url: String,
+ root_ve_type: String,
+ muted: Int32,
+ cc3_module: Int32,
+ adaptive_fmts: AdaptiveFmts,
+ fmt_list: Array(String),
+ allow_embed: Int32,
+ iurlhq: String,
+ use_cipher_signature: Bool,
+ status: String,
+ video_id: String,
+ idpj: Int32,
+ iurlhmaxres: String,
+ short_view_count_text: String,
+ iv_load_policy: Int32,
+ plid: String,
+ vss_host: String,
+ ttsurl: String,
+ token: String,
+ account_playback_token: String,
+ of: String,
+ iurl: String,
+ iurlsd: String,
+ c: String,
+ timestamp: Int32,
+ url_encoded_fmt_stream_map: URLEncodedFmtStreamMap,
+ allow_ratings: Int32,
+ view_count: Int64,
+ title: String,
+ caption_tracks: CaptionTracks,
+ fexp: Array(String),
+ storyboard_spec: String,
+ keywords: Array(String),
+ ucid: String,
+ remarketing_url: String,
+ caption_translation_languages: CaptionTranslationLanguages,
+ avg_rating: Float64,
+ is_listed: Int32,
+ ptk: String,
+ cl: Int32,
+ watermark: Array(String),
+ ldpj: Int32,
+ tmi: Int32,
+ eventid: String,
+ thumbnail_url: String
+ )
+end
+
macro templated(filename)
- render "views/#{{{filename}}}.ecr", "views/layout.ecr"
+ render "src/views/#{{{filename}}}.ecr", "src/views/layout.ecr"
end
context = OpenSSL::SSL::Context::Client.insecure
-fmt_file = File.open("temp/fmt_stream")
+client = HTTP::Client.new("www.youtube.com", 443, context)
+
+
+video_id = "Vufba_ZcoR0"
+video_info = client.get("/get_video_info?video_id=#{video_id}&el=info&ps=default&eurl=&gl=US&hl=en").body
+
+p VideoInfo.from_json(video_info)
+
get "/" do |env|
templated "index"
end
-
get "/watch/:video_id" do |env|
video_id = env.params.url["video_id"]
@@ -31,12 +154,6 @@ get "/watch/:video_id" do |env|
fmt_stream << HTTP::Params.parse(string)
end
- File.write("temp/#{video_id}", video_info)
- File.write("temp/#{video_id}_manifest", video_info["dashmpd"])
- File.open("temp/#{video_id}_fmt_stream_0", "a+").puts fmt_stream[0]["url"]
- File.open("temp/#{video_id}_fmt_stream_1", "a+").puts fmt_stream[1]["url"]
- File.open("temp/#{video_id}_fmt_stream_2", "a+").puts fmt_stream[2]["url"]
- File.open("temp/#{video_id}_fmt_stream_3", "a+").puts fmt_stream[3]["url"]
fmt_stream.reverse! # We want lowest quality first
# css query [title="I like this"] > span
likes = doc.xpath_node(%q(//button[@title="I like this"]/span))
@@ -54,7 +171,7 @@ get "/watch/:video_id" do |env|
dislikes = 1
end
- engagement = ((dislikes.to_f32 + likes.to_f32)*100 / video_info["view_count"].to_i).to_i
+ engagement = ((dislikes.to_f32 + likes.to_f32)*100 / video_info["view_count"].to_f32).significant(2)
calculated_rating = likes.to_f32/(likes.to_f32 + dislikes.to_f32)*4 + 1
templated "watch"