diff options
| -rw-r--r-- | assets/js/watch.js | 54 | ||||
| -rw-r--r-- | src/invidious.cr | 22 | ||||
| -rw-r--r-- | src/invidious/views/watch.ecr | 22 |
3 files changed, 30 insertions, 68 deletions
diff --git a/assets/js/watch.js b/assets/js/watch.js index 37ca4e43..7a68c30c 100644 --- a/assets/js/watch.js +++ b/assets/js/watch.js @@ -50,57 +50,3 @@ function hide_youtube_replies(target, inner_text, sub_text) { target.innerHTML = sub_text; target.setAttribute("onclick", "show_youtube_replies(this, \'" + inner_text + "\', \'" + sub_text + "\')"); } - -function download_video(target) { - var title = target.getAttribute("data-title"); - var children = document.getElementById("download_widget").children; - var progress = document.getElementById("download-progress"); - var url = ""; - - document.getElementById("progress-container").style.display = ""; - - for (i = 0; i < children.length; i++) { - if (children[i].selected) { - url = children[i].getAttribute("data-url"); - } - } - - var xhr = new XMLHttpRequest(); - xhr.open("GET", url); - xhr.responseType = "arraybuffer"; - - xhr.onprogress = function(event) { - if (event.lengthComputable) { - progress.style.width = "" + (event.loaded / event.total)*100 + "%"; - } - }; - - xhr.onload = function(event) { - if (event.currentTarget.status != 200) { - console.log("Downloading " + title + " failed.") - document.getElementById("progress-container").style.display = "none"; - progress.style.width = "0%"; - - return; - } - - var data = new Blob([xhr.response], {'type' : 'video/mp4'}); - var videoFile = window.URL.createObjectURL(data); - - var link = document.createElement('a'); - link.href = videoFile; - link.setAttribute('download', title); - document.body.appendChild(link); - - window.requestAnimationFrame(function() { - var event = new MouseEvent('click'); - link.dispatchEvent(event); - document.body.removeChild(link); - }); - - document.getElementById("progress-container").style.display = "none"; - progress.style.width = "0%"; - }; - - xhr.send(null); -}
\ No newline at end of file diff --git a/src/invidious.cr b/src/invidious.cr index cbb36742..9f0f6a3f 100644 --- a/src/invidious.cr +++ b/src/invidious.cr @@ -3904,12 +3904,20 @@ end # YouTube /videoplayback links expire after 6 hours, # so we have a mechanism here to redirect to the latest version get "/latest_version" do |env| - id = env.params.query["id"]? - itag = env.params.query["itag"]? + if env.params.query["download_widget"]? + download_widget = JSON.parse(env.params.query["download_widget"]) + id = download_widget["id"].as_s + itag = download_widget["itag"].as_s + title = download_widget["title"].as_s + local = "true" + end + + id ||= env.params.query["id"]? + itag ||= env.params.query["itag"]? region = env.params.query["region"]? - local = env.params.query["local"]? + local ||= env.params.query["local"]? local ||= "false" local = local == "true" @@ -3934,6 +3942,10 @@ get "/latest_version" do |env| url = URI.parse(url).full_path.not_nil! end + if title + url += "&title=#{title}" + end + env.redirect url end @@ -4038,6 +4050,10 @@ get "/videoplayback" do |env| client.get(url, headers) do |response| env.response.status_code = response.status_code + if title = env.params.query["title"]? + env.response.headers["Content-Disposition"] = "attachment; filename=#{title}" + end + response.headers.each do |key, value| env.response.headers[key] = value end diff --git a/src/invidious/views/watch.ecr b/src/invidious/views/watch.ecr index 9432eb4e..3949245d 100644 --- a/src/invidious/views/watch.ecr +++ b/src/invidious/views/watch.ecr @@ -54,29 +54,29 @@ <div class="h-box"> <p><a href="https://www.youtube.com/watch?v=<%= video.id %>"><%= translate(locale, "Watch video on Youtube") %></a></p> - <form class="pure-form pure-form-stacked"> + <form class="pure-form pure-form-stacked" action="/latest_version" method="get" rel="noopener" target="_blank"> <div class="pure-control-group"> <label for="download_widget"><%= translate(locale, "Download as: ") %></label> <select style="width:100%" name="download_widget" id="download_widget"> <% video_streams.each do |option| %> - <option data-url="/latest_version?id=<%= video.id %>&itag=<%= option["itag"] %>&local=true"><%= option["quality_label"] %> - <%= option["type"].split(";")[0] %> @ <%= option["fps"] %>fps - video only</option> + <option value='{"id":"<%= video.id %>","itag":"<%= option["itag"] %>","title":"<%= video.title.dump_unquoted %>-<%= video.id %>.mp4"}'> + <%= option["quality_label"] %> - <%= option["type"].split(";")[0] %> @ <%= option["fps"] %>fps - video only + </option> <% end %> <% audio_streams.each do |option| %> - <option data-url="/latest_version?id=<%= video.id %>&itag=<%= option["itag"] %>&local=true"><%= option["type"].split(";")[0] %> @ <%= option["bitrate"] %>k - audio only</option> + <option value='{"id":"<%= video.id %>","itag":"<%= option["itag"] %>","title":"<%= video.title.dump_unquoted %>-<%= video.id %>.mp4"}'> + <%= option["type"].split(";")[0] %> @ <%= option["bitrate"] %>k - audio only + </option> <% end %> <% fmt_stream.each do |option| %> - <option data-url="/latest_version?id=<%= video.id %>&itag=<%= option["itag"] %>&local=true"><%= itag_to_metadata?(option["itag"]).try &.["height"]? || "~240" %>p - <%= option["type"].split(";")[0] %></option> + <option value='{"id":"<%= video.id %>","itag":"<%= option["itag"] %>","title":"<%= video.title.dump_unquoted %>-<%= video.id %>.mp4"}'> + <%= itag_to_metadata?(option["itag"]).try &.["height"]? || "~240" %>p - <%= option["type"].split(";")[0] %> + </option> <% end %> </select> </div> - <div id="progress-container" style="width:100%; display:none"> - <div id="download-progress"> - </div> - </div> - - <button type="button" data-title="<%= video.title.dump_unquoted %>-<%= video.id %>.mp4" onclick="download_video(this)" - class="pure-button pure-button-primary"> + <button type="submit" class="pure-button pure-button-primary"> <b><%= translate(locale, "Download") %></b> </button> </form> |
