From b8c6a40a3626c26bd8e10e54b09bd9c9855e5fe3 Mon Sep 17 00:00:00 2001 From: Jason Henriquez Date: Sat, 19 Oct 2024 21:20:40 -0500 Subject: [PATCH 01/27] MHave fullscreen persist when videos autoplay --- .../ft-shaka-video-player/ft-shaka-video-player.js | 9 +++++++-- src/renderer/views/Watch/Watch.js | 4 +++- src/renderer/views/Watch/Watch.vue | 3 +++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js b/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js index 4c3c10f968b80..9424026eef4cb 100644 --- a/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js +++ b/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js @@ -106,6 +106,10 @@ export default defineComponent({ vrProjection: { type: String, default: null + }, + startInFullwindow: { + type: Boolean, + default: false } }, emits: [ @@ -139,7 +143,7 @@ export default defineComponent({ const isLive = ref(false) const useOverFlowMenu = ref(false) - const fullWindowEnabled = ref(false) + const fullWindowEnabled = ref(props.startInFullwindow) const forceAspectRatio = ref(false) const activeLegacyFormat = shallowRef(null) @@ -1042,7 +1046,7 @@ export default defineComponent({ navigator.mediaSession.playbackState = 'none' } - emit('ended') + emit('ended', fullWindowEnabled.value) } function updateVolume() { @@ -2350,6 +2354,7 @@ export default defineComponent({ registerLegacyQualitySelection() registerStatsButton() + if (ui.isMobile()) { useOverFlowMenu.value = true } else { diff --git a/src/renderer/views/Watch/Watch.js b/src/renderer/views/Watch/Watch.js index 71f0c454c2ca2..7a2c1c1d896fd 100644 --- a/src/renderer/views/Watch/Watch.js +++ b/src/renderer/views/Watch/Watch.js @@ -66,6 +66,7 @@ export default defineComponent({ }, data: function () { return { + isInFullwindow: false, isLoading: true, firstLoad: true, useTheatreMode: false, @@ -1181,7 +1182,8 @@ export default defineComponent({ this.activeFormat = 'audio' }, - handleVideoEnded: function () { + handleVideoEnded: function (isInFullwindow = false) { + this.isInFullwindow = isInFullwindow if ((!this.watchingPlaylist || !this.autoplayPlaylists) && !this.playNextVideo) { return } diff --git a/src/renderer/views/Watch/Watch.vue b/src/renderer/views/Watch/Watch.vue index e9c60192c8322..e51c8cb43256c 100644 --- a/src/renderer/views/Watch/Watch.vue +++ b/src/renderer/views/Watch/Watch.vue @@ -34,11 +34,14 @@ :theatre-possible="theatrePossible" :use-theatre-mode="useTheatreMode" :vr-projection="vrProjection" + :start-in-fullwindow="isInFullwindow" class="videoPlayer" @error="handlePlayerError" @loaded="handleVideoLoaded" @timeupdate="updateCurrentChapter" @ended="handleVideoEnded" + @set-fullscreen="e => isInFullscreen = e" + @set-fullwindow="e => isInFullwindow = e" @toggle-theatre-mode="useTheatreMode = !useTheatreMode" />
Date: Sun, 20 Oct 2024 10:40:19 -0500 Subject: [PATCH 02/27] Have fullscreen and PiP be re-requested on autoplay when they are open --- src/constants.js | 3 ++ src/main/index.js | 8 ++++ .../ft-shaka-video-player.js | 37 +++++++++++++++++-- .../ft-shaka-video-player.vue | 2 + src/renderer/views/Watch/Watch.js | 17 +++++++-- src/renderer/views/Watch/Watch.vue | 7 ++-- 6 files changed, 65 insertions(+), 9 deletions(-) diff --git a/src/constants.js b/src/constants.js index f45e30fb8211d..38e1e7a1e4c64 100644 --- a/src/constants.js +++ b/src/constants.js @@ -15,6 +15,9 @@ const IpcChannels = { APP_READY: 'app-ready', RELAUNCH_REQUEST: 'relaunch-request', + REQUEST_FULLSCREEN: 'request-fullscreen', + REQUEST_PIP: 'request_pip', + SEARCH_INPUT_HANDLING_READY: 'search-input-handling-ready', UPDATE_SEARCH_INPUT_TEXT: 'update-search-input-text', diff --git a/src/main/index.js b/src/main/index.js index 10ca46343829e..e98a9a3312d26 100644 --- a/src/main/index.js +++ b/src/main/index.js @@ -927,6 +927,14 @@ function runApp() { return app.getPath('pictures') }) + ipcMain.on(IpcChannels.REQUEST_FULLSCREEN, ({ sender }) => { + sender.executeJavaScript('document.getElementById("video").requestFullscreen({navigationUI: "hide"})', true) + }) + + ipcMain.on(IpcChannels.REQUEST_PIP, ({ sender }) => { + sender.executeJavaScript('document.getElementById("video").requestPictureInPicture()', true) + }) + ipcMain.handle(IpcChannels.SHOW_OPEN_DIALOG, async ({ sender }, options) => { const senderWindow = findSenderWindow(sender) if (senderWindow) { diff --git a/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js b/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js index 9424026eef4cb..c7d55ef748468 100644 --- a/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js +++ b/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js @@ -107,15 +107,24 @@ export default defineComponent({ type: String, default: null }, + startInFullscreen: { + type: Boolean, + default: false + }, startInFullwindow: { type: Boolean, default: false + }, + startInPip: { + type: Boolean, + default: false } }, emits: [ 'error', 'loaded', 'ended', + 'reset-start-in-viewing-mode', 'timeupdate', 'toggle-theatre-mode' ], @@ -143,11 +152,16 @@ export default defineComponent({ const isLive = ref(false) const useOverFlowMenu = ref(false) - const fullWindowEnabled = ref(props.startInFullwindow) const forceAspectRatio = ref(false) const activeLegacyFormat = shallowRef(null) + const fullWindowEnabled = ref(props.startInFullwindow) + let startInFullscreen = props.startInFullscreen + let startInPip = props.startInPip + + emit('reset-start-in-viewing-mode') + /** * @type {{ * url: string, @@ -1046,7 +1060,17 @@ export default defineComponent({ navigator.mediaSession.playbackState = 'none' } - emit('ended', fullWindowEnabled.value) + const controls = ui.getControls() + emit('ended', controls.isFullScreenEnabled(), fullWindowEnabled.value, controls.isPiPEnabled()) + } + + function handleCanPlay() { + // PiP can only be activated once the video's readState and video track are populated + if (startInPip && ui.getControls().isPiPAllowed() && process.env.IS_ELECTRON) { + startInPip = false + const { ipcRenderer } = require('electron') + ipcRenderer.send(IpcChannels.REQUEST_PIP) + } } function updateVolume() { @@ -1754,7 +1778,7 @@ export default defineComponent({ /** * As shaka-player doesn't let you unregister custom control factories, * overwrite them with `null` instead so the referenced objects - * (e.g. {@linkcode events}, {@linkcode fullWindowEnabled}) can get gargabe collected + * (e.g. {@linkcode events}, {@linkcode fullWindowEnabled}) can get garbage collected */ function cleanUpCustomPlayerControls() { shakaControls.registerElement('ft_audio_tracks', null) @@ -2543,6 +2567,12 @@ export default defineComponent({ if (props.chapters.length > 0) { createChapterMarkers() } + + if (startInFullscreen && process.env.IS_ELECTRON) { + startInFullscreen = false + const { ipcRenderer } = require('electron') + ipcRenderer.send(IpcChannels.REQUEST_FULLSCREEN) + } } watch( @@ -2781,6 +2811,7 @@ export default defineComponent({ handlePlay, handlePause, + handleCanPlay, handleEnded, updateVolume, handleTimeupdate, diff --git a/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.vue b/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.vue index 4b9519c772718..208a656fa0f3a 100644 --- a/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.vue +++ b/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.vue @@ -9,6 +9,7 @@ >
+ + + + + + - - - - -
Date: Sun, 20 Oct 2024 12:16:45 -0500 Subject: [PATCH 04/27] Implement external player default viewing mode Current limitations: does not work for the search bar, randomly encountered YT video links (e.g., in descriptions), or the video thumbnail link in the playlist list view. --- .../distraction-settings.js | 1 - .../ft-list-playlist/ft-list-playlist.js | 4 ++++ .../components/ft-list-video/ft-list-video.js | 13 +++++++++++++ .../components/ft-list-video/ft-list-video.vue | 18 ++++++++++++------ src/renderer/views/Watch/Watch.js | 1 - 5 files changed, 29 insertions(+), 8 deletions(-) diff --git a/src/renderer/components/distraction-settings/distraction-settings.js b/src/renderer/components/distraction-settings/distraction-settings.js index eb584eaff6b0f..002631739795b 100644 --- a/src/renderer/components/distraction-settings/distraction-settings.js +++ b/src/renderer/components/distraction-settings/distraction-settings.js @@ -203,7 +203,6 @@ export default defineComponent({ 'updateHideLiveChat', 'updateHideActiveSubscriptions', 'updatePlayNextVideo', - 'updateDefaultViewingMode', 'updateHideVideoDescription', 'updateHideComments', 'updateHideCommentPhotos', diff --git a/src/renderer/components/ft-list-playlist/ft-list-playlist.js b/src/renderer/components/ft-list-playlist/ft-list-playlist.js index 98747cef34c23..1642292fa0037 100644 --- a/src/renderer/components/ft-list-playlist/ft-list-playlist.js +++ b/src/renderer/components/ft-list-playlist/ft-list-playlist.js @@ -60,6 +60,10 @@ export default defineComponent({ return this.$store.getters.getExternalPlayer }, + externalPlayerIsDefaultViewingMode: function () { + return this.$store.getters.getDefaultViewingMode === 'external_player' + }, + defaultPlayback: function () { return this.$store.getters.getDefaultPlayback }, diff --git a/src/renderer/components/ft-list-video/ft-list-video.js b/src/renderer/components/ft-list-video/ft-list-video.js index 67acb17bb96a1..0963c6fd501df 100644 --- a/src/renderer/components/ft-list-video/ft-list-video.js +++ b/src/renderer/components/ft-list-video/ft-list-video.js @@ -376,6 +376,10 @@ export default defineComponent({ return this.$store.getters.getExternalPlayer }, + externalPlayerIsDefaultViewingMode: function () { + return this.$store.getters.getDefaultViewingMode === 'external_player' + }, + defaultPlayback: function () { return this.$store.getters.getDefaultPlayback }, @@ -478,6 +482,10 @@ export default defineComponent({ return this.isInQuickBookmarkPlaylist ? 'base favorite' : 'base' }, + watchPageLinkType() { + return this.externalPlayerIsDefaultViewingMode ? 'a' : 'router-link' + }, + watchPageLinkTo() { // For `router-link` attribute `to` return { @@ -530,6 +538,11 @@ export default defineComponent({ } }, methods: { + handleWatchPageLinkClick: function() { + if (this.externalPlayerIsDefaultViewingMode) { + this.handleExternalPlayer() + } + }, fetchDeArrowThumbnail: async function() { if (this.thumbnailPreference === 'hidden') { return } const videoId = this.id diff --git a/src/renderer/components/ft-list-video/ft-list-video.vue b/src/renderer/components/ft-list-video/ft-list-video.vue index 7d63dcf983228..a4a4adf6ab7c8 100644 --- a/src/renderer/components/ft-list-video/ft-list-video.vue +++ b/src/renderer/components/ft-list-video/ft-list-video.vue @@ -10,11 +10,14 @@ >
- + - +
-

{{ displayTitle }}

-
+
Date: Sun, 20 Oct 2024 12:39:51 -0500 Subject: [PATCH 05/27] Disable & hide 'External Player' default viewing mode when no external player is set This will prevent issues with users who accidentally change this setting and report that clicking on videos results in errors. --- .../ft-list-playlist/ft-list-playlist.js | 4 --- .../components/ft-list-video/ft-list-video.js | 2 +- .../player-settings/player-settings.js | 36 +++++++++++++------ static/locales/en-US.yaml | 1 + 4 files changed, 28 insertions(+), 15 deletions(-) diff --git a/src/renderer/components/ft-list-playlist/ft-list-playlist.js b/src/renderer/components/ft-list-playlist/ft-list-playlist.js index 1642292fa0037..98747cef34c23 100644 --- a/src/renderer/components/ft-list-playlist/ft-list-playlist.js +++ b/src/renderer/components/ft-list-playlist/ft-list-playlist.js @@ -60,10 +60,6 @@ export default defineComponent({ return this.$store.getters.getExternalPlayer }, - externalPlayerIsDefaultViewingMode: function () { - return this.$store.getters.getDefaultViewingMode === 'external_player' - }, - defaultPlayback: function () { return this.$store.getters.getDefaultPlayback }, diff --git a/src/renderer/components/ft-list-video/ft-list-video.js b/src/renderer/components/ft-list-video/ft-list-video.js index 0963c6fd501df..579fd0647d8e0 100644 --- a/src/renderer/components/ft-list-video/ft-list-video.js +++ b/src/renderer/components/ft-list-video/ft-list-video.js @@ -377,7 +377,7 @@ export default defineComponent({ }, externalPlayerIsDefaultViewingMode: function () { - return this.$store.getters.getDefaultViewingMode === 'external_player' + return this.externalPlayer !== '' && this.$store.getters.getDefaultViewingMode === 'external_player' }, defaultPlayback: function () { diff --git a/src/renderer/components/player-settings/player-settings.js b/src/renderer/components/player-settings/player-settings.js index 6428fb26438a3..118d34987638d 100644 --- a/src/renderer/components/player-settings/player-settings.js +++ b/src/renderer/components/player-settings/player-settings.js @@ -49,14 +49,6 @@ export default defineComponent({ 0.5, 1 ], - viewingModeValues: [ - 'default', - 'theatre', - 'fullscreen', - 'fullwindow', - 'pip', - 'external_player' - ], screenshotFormatNames: [ 'PNG', 'JPEG' @@ -68,6 +60,14 @@ export default defineComponent({ screenshotFolderPlaceholder: '', screenshotFilenameExample: '', screenshotDefaultPattern: '%Y%M%D-%H%N%S', + viewingModeValues: [ + 'default', + 'theatre', + 'fullscreen', + 'fullwindow', + 'pip', + 'external_player' + ] } }, computed: { @@ -128,9 +128,18 @@ export default defineComponent({ }, defaultViewingMode: function () { + const defaultViewingMode = this.$store.getters.getDefaultViewingMode + if (defaultViewingMode === 'external_player' && this.externalPlayer === '') { + return 'default' + } + return this.$store.getters.getDefaultViewingMode }, + externalPlayer: function () { + return this.$store.getters.getExternalPlayer + }, + hideRecommendedVideos: function () { return this.$store.getters.getHideRecommendedVideos }, @@ -186,14 +195,21 @@ export default defineComponent({ }, viewingModeNames: function () { - return [ + const viewingModeNames = [ this.$t('Settings.General Settings.Thumbnail Preference.Default'), this.$t('Video.Player.Theatre Mode'), this.$t('Settings.Player Settings.Default Viewing Mode.Fullscreen'), this.$t('Video.Player.Full Window'), this.$t('Settings.Player Settings.Default Viewing Mode.Picture in Picture'), - this.$t('Settings.External Player Settings.External Player'), ] + + if (this.externalPlayer !== '') { + viewingModeNames.push( + this.$t('Settings.Player Settings.Default Viewing Mode.External Player', { externalPlayerName: this.externalPlayer }) + ) + } + + return viewingModeNames }, enableScreenshot: function() { diff --git a/static/locales/en-US.yaml b/static/locales/en-US.yaml index b975201bdc81c..11794b3c3c258 100644 --- a/static/locales/en-US.yaml +++ b/static/locales/en-US.yaml @@ -406,6 +406,7 @@ Settings: Default Viewing Mode: Default Viewing Mode Fullscreen: Fullscreen Picture in Picture: Picture in Picture + External Player: External Player ({externalPlayerName}) Scroll Volume Over Video Player: Scroll Volume Over Video Player Scroll Playback Rate Over Video Player: Scroll Playback Rate Over Video Player Skip by Scrolling Over Video Player: Skip by Scrolling Over Video Player From 034733664773ee81cce0304d670a6ec6e1bb0663 Mon Sep 17 00:00:00 2001 From: Jason Henriquez Date: Sun, 20 Oct 2024 17:44:35 -0500 Subject: [PATCH 06/27] Fix fullscreen issue with icons by calling requestFullscreen on videoContainer element --- src/main/index.js | 2 +- .../components/ft-shaka-video-player/ft-shaka-video-player.vue | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/index.js b/src/main/index.js index e98a9a3312d26..9b233e4290059 100644 --- a/src/main/index.js +++ b/src/main/index.js @@ -928,7 +928,7 @@ function runApp() { }) ipcMain.on(IpcChannels.REQUEST_FULLSCREEN, ({ sender }) => { - sender.executeJavaScript('document.getElementById("video").requestFullscreen({navigationUI: "hide"})', true) + sender.executeJavaScript('document.getElementById("videoContainer").requestFullscreen({navigationUI: "hide"})', true) }) ipcMain.on(IpcChannels.REQUEST_PIP, ({ sender }) => { diff --git a/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.vue b/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.vue index 208a656fa0f3a..5a40c070a64b6 100644 --- a/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.vue +++ b/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.vue @@ -1,5 +1,6 @@