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 80% 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 @@ +
+ VIDEO +
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"