diff --git a/assets/js/player.js b/assets/js/player.js index a461c53d..0cc4bab9 100644 --- a/assets/js/player.js +++ b/assets/js/player.js @@ -38,6 +38,8 @@ embed_url.searchParams.delete('v'); short_url = location.origin + '/' + video_data.id + embed_url.search; embed_url = location.origin + '/embed/' + video_data.id + embed_url.search; +var save_player_pos_key = "save_player_pos"; + var shareOptions = { socials: ['fbFeed', 'tw', 'reddit', 'email'], @@ -199,6 +201,32 @@ if (video_data.premiere_timestamp && Math.round(new Date() / 1000) < video_data. player.getChild('bigPlayButton').hide(); } +if (video_data.params.save_player_pos) { + const url = new URL(location); + const hasTimeParam = url.searchParams.has("t"); + const remeberedTime = get_video_time(); + let lastUpdated = 0; + + if(!hasTimeParam) { + set_seconds_after_start(remeberedTime); + } + + const updateTime = () => { + const raw = player.currentTime(); + const time = Math.floor(raw); + + if(lastUpdated !== time) { + save_video_time(time); + lastUpdated = time; + } + }; + + player.on("timeupdate", updateTime); +} +else { + remove_all_video_times(); +} + if (video_data.params.autoplay) { var bpb = player.getChild('bigPlayButton'); bpb.hide(); @@ -330,6 +358,55 @@ function skip_seconds(delta) { player.currentTime(newTime); } +function set_seconds_after_start(delta) { + const start = video_data.params.video_start; + player.currentTime(start + delta); +} + +function save_video_time(seconds) { + const videoId = video_data.id; + const all_video_times = get_all_video_times(); + + all_video_times[videoId] = seconds; + + set_all_video_times(all_video_times); +} + +function get_video_time() { + try { + const videoId = video_data.id; + const all_video_times = get_all_video_times(); + const timestamp = all_video_times[videoId]; + + return timestamp || 0; + } + catch { + return 0; + } +} + +function set_all_video_times(times) { + const json = JSON.stringify(times); + + localStorage.setItem(save_player_pos_key, json); +} + +function get_all_video_times() { + try { + const raw = localStorage.getItem(save_player_pos_key); + const times = JSON.parse(raw); + + return times || {}; + } + catch { + return {}; + } +} + +function remove_all_video_times() { + localStorage.removeItem(save_player_pos_key); +} + function set_time_percent(percent) { const duration = player.duration(); const newTime = duration * (percent / 100); diff --git a/locales/en-US.json b/locales/en-US.json index 8bdf719b..94aac89e 100644 --- a/locales/en-US.json +++ b/locales/en-US.json @@ -461,5 +461,6 @@ "download_subtitles": "Subtitles - `x` (.vtt)", "user_created_playlists": "`x` created playlists", "user_saved_playlists": "`x` saved playlists", - "Video unavailable": "Video unavailable" + "Video unavailable": "Video unavailable", + "preferences_save_player_pos_label": "Save the current video time: " } diff --git a/src/invidious/config.cr b/src/invidious/config.cr index 578e31fd..c4a8bf83 100644 --- a/src/invidious/config.cr +++ b/src/invidious/config.cr @@ -42,6 +42,7 @@ struct ConfigPreferences property volume : Int32 = 100 property vr_mode : Bool = true property show_nick : Bool = true + property save_player_pos : Bool = false def to_tuple {% begin %} diff --git a/src/invidious/routes/preferences.cr b/src/invidious/routes/preferences.cr index edf9e1e7..15c00700 100644 --- a/src/invidious/routes/preferences.cr +++ b/src/invidious/routes/preferences.cr @@ -70,6 +70,10 @@ module Invidious::Routes::PreferencesRoute vr_mode ||= "off" vr_mode = vr_mode == "on" + save_player_pos = env.params.body["save_player_pos"]?.try &.as(String) + save_player_pos ||= "off" + save_player_pos = save_player_pos == "on" + show_nick = env.params.body["show_nick"]?.try &.as(String) show_nick ||= "off" show_nick = show_nick == "on" @@ -165,6 +169,7 @@ module Invidious::Routes::PreferencesRoute extend_desc: extend_desc, vr_mode: vr_mode, show_nick: show_nick, + save_player_pos: save_player_pos, }.to_json).to_json if user = env.get? "user" diff --git a/src/invidious/user/preferences.cr b/src/invidious/user/preferences.cr index c15876f5..bf7ea401 100644 --- a/src/invidious/user/preferences.cr +++ b/src/invidious/user/preferences.cr @@ -53,6 +53,7 @@ struct Preferences property video_loop : Bool = CONFIG.default_user_preferences.video_loop property extend_desc : Bool = CONFIG.default_user_preferences.extend_desc property volume : Int32 = CONFIG.default_user_preferences.volume + property save_player_pos : Bool = CONFIG.default_user_preferences.save_player_pos module BoolToString def self.to_json(value : String, json : JSON::Builder) diff --git a/src/invidious/videos.cr b/src/invidious/videos.cr index 621ff386..d4ef0900 100644 --- a/src/invidious/videos.cr +++ b/src/invidious/videos.cr @@ -246,6 +246,7 @@ struct VideoPreferences property video_start : Float64 | Int32 property volume : Int32 property vr_mode : Bool + property save_player_pos : Bool end struct Video @@ -1090,6 +1091,7 @@ def process_video_params(query, preferences) extend_desc = query["extend_desc"]?.try { |q| (q == "true" || q == "1").to_unsafe } volume = query["volume"]?.try &.to_i? vr_mode = query["vr_mode"]?.try { |q| (q == "true" || q == "1").to_unsafe } + save_player_pos = query["save_player_pos"]?.try { |q| (q == "true" || q == "1").to_unsafe } if preferences # region ||= preferences.region @@ -1110,6 +1112,7 @@ def process_video_params(query, preferences) extend_desc ||= preferences.extend_desc.to_unsafe volume ||= preferences.volume vr_mode ||= preferences.vr_mode.to_unsafe + save_player_pos ||= preferences.save_player_pos.to_unsafe end annotations ||= CONFIG.default_user_preferences.annotations.to_unsafe @@ -1129,6 +1132,7 @@ def process_video_params(query, preferences) extend_desc ||= CONFIG.default_user_preferences.extend_desc.to_unsafe volume ||= CONFIG.default_user_preferences.volume vr_mode ||= CONFIG.default_user_preferences.vr_mode.to_unsafe + save_player_pos ||= CONFIG.default_user_preferences.save_player_pos.to_unsafe annotations = annotations == 1 autoplay = autoplay == 1 @@ -1140,6 +1144,7 @@ def process_video_params(query, preferences) video_loop = video_loop == 1 extend_desc = extend_desc == 1 vr_mode = vr_mode == 1 + save_player_pos = save_player_pos == 1 if CONFIG.disabled?("dash") && quality == "dash" quality = "high" @@ -1190,6 +1195,7 @@ def process_video_params(query, preferences) video_start: video_start, volume: volume, vr_mode: vr_mode, + save_player_pos: save_player_pos, }) return params diff --git a/src/invidious/views/preferences.ecr b/src/invidious/views/preferences.ecr index 6bd9e348..96904259 100644 --- a/src/invidious/views/preferences.ecr +++ b/src/invidious/views/preferences.ecr @@ -116,6 +116,11 @@ checked<% end %>> +