mirror of
https://github.com/iv-org/invidious.git
synced 2024-11-25 06:57:22 +00:00
Add qualityselector
This commit is contained in:
parent
1a6c28735c
commit
e37e9a0b8e
25
assets/css/quality-selector.css
Normal file
25
assets/css/quality-selector.css
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
.vjs-quality-selector .vjs-menu-button {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.vjs-quality-selector .vjs-icon-placeholder {
|
||||||
|
font-family: "VideoJS";
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
.vjs-quality-selector .vjs-icon-placeholder:before {
|
||||||
|
content: "\f110";
|
||||||
|
}
|
||||||
|
.vjs-quality-changing .vjs-big-play-button {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.vjs-quality-changing .vjs-control-bar {
|
||||||
|
display: -webkit-box;
|
||||||
|
display: -webkit-flex;
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: flex;
|
||||||
|
visibility: visible;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
1981
assets/js/silvermine-videojs-quality-selector.js
Normal file
1981
assets/js/silvermine-videojs-quality-selector.js
Normal file
File diff suppressed because it is too large
Load Diff
@ -189,14 +189,6 @@ get "/watch" do |env|
|
|||||||
fmt_stream << HTTP::Params.parse(string)
|
fmt_stream << HTTP::Params.parse(string)
|
||||||
end
|
end
|
||||||
|
|
||||||
signature = false
|
|
||||||
if fmt_stream[0]? && fmt_stream[0]["s"]?
|
|
||||||
signature = true
|
|
||||||
end
|
|
||||||
|
|
||||||
# We want lowest quality first
|
|
||||||
fmt_stream.reverse!
|
|
||||||
|
|
||||||
adaptive_fmts = [] of HTTP::Params
|
adaptive_fmts = [] of HTTP::Params
|
||||||
if video.info.has_key?("adaptive_fmts")
|
if video.info.has_key?("adaptive_fmts")
|
||||||
video.info["adaptive_fmts"].split(",") do |string|
|
video.info["adaptive_fmts"].split(",") do |string|
|
||||||
@ -204,6 +196,11 @@ get "/watch" do |env|
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
signature = false
|
||||||
|
if adaptive_fmts[0]? && adaptive_fmts[0]["s"]?
|
||||||
|
signature = true
|
||||||
|
end
|
||||||
|
|
||||||
if signature
|
if signature
|
||||||
adaptive_fmts.each do |fmt|
|
adaptive_fmts.each do |fmt|
|
||||||
fmt["url"] += "&signature=" + decrypt_signature(fmt["s"])
|
fmt["url"] += "&signature=" + decrypt_signature(fmt["s"])
|
||||||
@ -214,6 +211,19 @@ get "/watch" do |env|
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# 3gpp doesn't appear to play correclty in Chrome, so here we remove it
|
||||||
|
fmt_stream = fmt_stream.compact_map { |s| !s["type"].starts_with?("video/3gpp") ? s : nil }
|
||||||
|
fmt_stream = fmt_stream.uniq { |s| s["quality"] }
|
||||||
|
|
||||||
|
video_streams = adaptive_fmts.compact_map { |s| s["type"].starts_with?("video") ? s : nil }
|
||||||
|
video_streams = video_streams.uniq { |s| s["size"] }
|
||||||
|
|
||||||
|
audio_streams = adaptive_fmts.compact_map { |s| s["type"].starts_with?("audio") ? s : nil }
|
||||||
|
audio_streams.sort_by! { |s| s["bitrate"].to_i }.reverse!
|
||||||
|
audio_streams.each do |fmt|
|
||||||
|
fmt["bitrate"] = (fmt["bitrate"].to_f64/1000).to_i.to_s
|
||||||
|
end
|
||||||
|
|
||||||
rvs = [] of Hash(String, String)
|
rvs = [] of Hash(String, String)
|
||||||
if video.info.has_key?("rvs")
|
if video.info.has_key?("rvs")
|
||||||
video.info["rvs"].split(",").each do |rv|
|
video.info["rvs"].split(",").each do |rv|
|
||||||
@ -358,7 +368,7 @@ get "/api/manifest/dash/id/:id" do |env|
|
|||||||
end
|
end
|
||||||
|
|
||||||
if signature
|
if signature
|
||||||
adaptive_fmts.each do |fmt|
|
adaptive_fmts.each do |fmt|
|
||||||
fmt["url"] += "&signature=" + decrypt_signature(fmt["s"])
|
fmt["url"] += "&signature=" + decrypt_signature(fmt["s"])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -379,20 +389,20 @@ get "/api/manifest/dash/id/:id" do |env|
|
|||||||
xml.element("AdaptationSet", id: 0, mimeType: "audio/mp4", subsegmentAlignment: true) do
|
xml.element("AdaptationSet", id: 0, mimeType: "audio/mp4", subsegmentAlignment: true) do
|
||||||
xml.element("Role", schemeIdUri: "urn:mpeg:DASH:role:2011", value: "main")
|
xml.element("Role", schemeIdUri: "urn:mpeg:DASH:role:2011", value: "main")
|
||||||
video_streams.each do |fmt|
|
video_streams.each do |fmt|
|
||||||
mimetype, codecs = fmt["type"].split(";")
|
mimetype, codecs = fmt["type"].split(";")
|
||||||
codecs = codecs[9..-2]
|
codecs = codecs[9..-2]
|
||||||
fmt_type = mimetype.split("/")[0]
|
fmt_type = mimetype.split("/")[0]
|
||||||
bandwidth = fmt["bitrate"]
|
bandwidth = fmt["bitrate"]
|
||||||
itag = fmt["itag"]
|
itag = fmt["itag"]
|
||||||
url = URI.unescape(fmt["url"])
|
url = URI.unescape(fmt["url"])
|
||||||
|
|
||||||
xml.element("Representation", id: fmt["itag"], codecs: codecs, bandwidth: bandwidth) do
|
xml.element("Representation", id: fmt["itag"], codecs: codecs, bandwidth: bandwidth) do
|
||||||
xml.element("BaseURL") { xml.cdata url }
|
xml.element("BaseURL") { xml.cdata url }
|
||||||
xml.element("SegmentBase", indexRange: fmt["init"]) do
|
xml.element("SegmentBase", indexRange: fmt["init"]) do
|
||||||
xml.element("Initialization", range: fmt["index"])
|
xml.element("Initialization", range: fmt["index"])
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
xml.element("AdaptationSet", id: 1, mimeType: "video/mp4", subsegmentAlignment: true) do
|
xml.element("AdaptationSet", id: 1, mimeType: "video/mp4", subsegmentAlignment: true) do
|
||||||
@ -408,15 +418,15 @@ get "/api/manifest/dash/id/:id" do |env|
|
|||||||
|
|
||||||
xml.element("Representation", id: itag, codecs: codecs, width: width, height: height, bandwidth: bandwidth, frameRate: fmt["fps"]) do
|
xml.element("Representation", id: itag, codecs: codecs, width: width, height: height, bandwidth: bandwidth, frameRate: fmt["fps"]) do
|
||||||
xml.element("BaseURL") { xml.cdata url }
|
xml.element("BaseURL") { xml.cdata url }
|
||||||
xml.element("SegmentBase", indexRange: fmt["init"]) do
|
xml.element("SegmentBase", indexRange: fmt["init"]) do
|
||||||
xml.element("Initialization", range: fmt["index"])
|
xml.element("Initialization", range: fmt["index"])
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
manifest = manifest.gsub(%(<?xml version="1.0" encoding="UTF-8U"?>), %(<?xml version="1.0" encoding="UTF-8"?>))
|
manifest = manifest.gsub(%(<?xml version="1.0" encoding="UTF-8U"?>), %(<?xml version="1.0" encoding="UTF-8"?>))
|
||||||
manifest = manifest.gsub(%(<?xml version="1.0" encoding="UTF-8V"?>), %(<?xml version="1.0" encoding="UTF-8"?>))
|
manifest = manifest.gsub(%(<?xml version="1.0" encoding="UTF-8V"?>), %(<?xml version="1.0" encoding="UTF-8"?>))
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
<audio poster="<%= thumbnail %>" title="<%= HTML.escape(video.title) %>" id="player" class="video-js" data-setup="{}" style="width:100%;" controls>
|
<audio poster="<%= thumbnail %>" title="<%= HTML.escape(video.title) %>" id="player" class="video-js" data-setup="{}" style="width:100%;" controls>
|
||||||
<% adaptive_fmts.each do |fmt| %>
|
<% audio_streams.each do |fmt| %>
|
||||||
<% if fmt["type"].starts_with?("audio") %>
|
<source src="<%= fmt["url"] %>" type='<%= fmt["type"] %>' label="<%= fmt["bitrate"] %>k" selected="<%= audio_streams[0]["url"] == fmt["url"] ? true : false %>">
|
||||||
<source src="<%= fmt["url"] %>" type='<%= fmt["type"] %>'>
|
|
||||||
<% end %>
|
|
||||||
<% end %>
|
<% end %>
|
||||||
</audio>
|
</audio>
|
@ -1,5 +1,5 @@
|
|||||||
<video poster="<%= thumbnail %>" title="<%= HTML.escape(video.title) %>" id="player" class="video-js" data-setup="{}" style="width:100%;" controls>
|
<video poster="<%= thumbnail %>" title="<%= HTML.escape(video.title) %>" id="player" class="video-js" data-setup="{}" style="width:100%;" controls>
|
||||||
<% fmt_stream.each do |fmt| %>
|
<% fmt_stream.each do |fmt| %>
|
||||||
<source src="<%= fmt["url"]? %>" type='<%= fmt["type"]? %>'>
|
<source src="<%= fmt["url"] %>" type='<%= fmt["type"] %>' label="<%= fmt["quality"] %>" selected="<%= fmt_stream[0]["url"] == fmt["url"] ? true : false %>">
|
||||||
<% end %>
|
<% end %>
|
||||||
</video>
|
</video>
|
@ -1,24 +1,37 @@
|
|||||||
<% content_for "header" do %>
|
<% content_for "header" do %>
|
||||||
<meta name="thumbnail" content="<%= thumbnail %>">
|
<meta name="thumbnail" content="<%= thumbnail %>">
|
||||||
<link rel="stylesheet" href="https://vjs.zencdn.net/6.6.3/video-js.css">
|
<link rel="stylesheet" href="https://vjs.zencdn.net/6.6.3/video-js.css">
|
||||||
|
<link rel="stylesheet" href="/css/quality-selector.css">
|
||||||
<script src="https://vjs.zencdn.net/6.6.3/video.js"></script>
|
<script src="https://vjs.zencdn.net/6.6.3/video.js"></script>
|
||||||
<script src="https://cdn.sc.gl/videojs-hotkeys/latest/videojs.hotkeys.min.js"></script>
|
<script src="https://cdn.sc.gl/videojs-hotkeys/latest/videojs.hotkeys.min.js"></script>
|
||||||
|
<script src="/js/silvermine-videojs-quality-selector.js"></script>
|
||||||
<title><%= video.title %> - Invidious</title>
|
<title><%= video.title %> - Invidious</title>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<div class="h-box">
|
<div class="h-box">
|
||||||
<% if listen %>
|
<% if listen %>
|
||||||
<%= render "src/views/player/audio.ecr" %>
|
<%= render "src/views/player/audio.ecr" %>
|
||||||
<% else %>
|
<% else %>
|
||||||
<%= render "src/views/player/video.ecr" %>
|
<%= render "src/views/player/video.ecr" %>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
var options = {
|
var options = {
|
||||||
aspectRatio: "16:9",
|
aspectRatio: "16:9",
|
||||||
preload: "auto",
|
preload: "auto",
|
||||||
playbackRates: [0.5, 1, 1.5, 2]
|
playbackRates: [0.5, 1, 1.5, 2],
|
||||||
|
controlBar: {
|
||||||
|
children: [
|
||||||
|
'playToggle',
|
||||||
|
'volumePanel',
|
||||||
|
'progressControl',
|
||||||
|
'remainingTimeDisplay',
|
||||||
|
'qualitySelector',
|
||||||
|
'playbackRateMenuButton',
|
||||||
|
'fullscreenToggle',
|
||||||
|
],
|
||||||
|
},
|
||||||
};
|
};
|
||||||
var player = videojs('player', options, function() {
|
var player = videojs('player', options, function() {
|
||||||
this.hotkeys({
|
this.hotkeys({
|
||||||
@ -81,7 +94,7 @@ function toggle_comments(target) {
|
|||||||
} else {
|
} else {
|
||||||
target.innerHTML = '[ - ]';
|
target.innerHTML = '[ - ]';
|
||||||
body.style.display = '';
|
body.style.display = '';
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -128,21 +141,21 @@ function toggle_comments(target) {
|
|||||||
<hr style="margin-left:1em; margin-right:1em;">
|
<hr style="margin-left:1em; margin-right:1em;">
|
||||||
<% if reddit_thread && !reddit_html.empty? %>
|
<% if reddit_thread && !reddit_html.empty? %>
|
||||||
<div>
|
<div>
|
||||||
<div style="overflow-wrap:break-word; word-wrap:break-word;">
|
<div style="overflow-wrap:break-word; word-wrap:break-word;">
|
||||||
<h3>
|
<h3>
|
||||||
<a href="javascript:void(0)" onclick="toggle_comments(this)">[ - ]</a>
|
<a href="javascript:void(0)" onclick="toggle_comments(this)">[ - ]</a>
|
||||||
<%= reddit_thread.data.title %>
|
<%= reddit_thread.data.title %>
|
||||||
</h3>
|
</h3>
|
||||||
<b>
|
<b>
|
||||||
<a target="_blank" href="https://reddit.com<%= reddit_thread.data.permalink %>">View more comments on Reddit</a>
|
<a target="_blank" href="https://reddit.com<%= reddit_thread.data.permalink %>">View more comments on Reddit</a>
|
||||||
</b>
|
</b>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<%= reddit_html %>
|
<%= reddit_html %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="pure-u-1 pure-u-md-1-5">
|
<div class="pure-u-1 pure-u-md-1-5">
|
||||||
|
Loading…
Reference in New Issue
Block a user