mirror of
https://github.com/FreeTubeApp/FreeTube
synced 2024-11-25 11:19:59 +01:00
Compare commits
18 Commits
3309a29421
...
d66e54f3f8
Author | SHA1 | Date | |
---|---|---|---|
|
d66e54f3f8 | ||
|
a70a5c6ab2 | ||
|
997fbdbbba | ||
|
fa35784522 | ||
|
687ef1e889 | ||
|
b548532ea7 | ||
|
f71e9cefd6 | ||
|
bb3be09122 | ||
|
5a54142c70 | ||
|
d57111aea6 | ||
|
5ca47a6349 | ||
|
937935f06a | ||
|
0347336647 | ||
|
db27c7b923 | ||
|
2f1986ca53 | ||
|
b64d9896d4 | ||
|
e95426d193 | ||
|
b8c6a40a36 |
@ -15,6 +15,9 @@ const IpcChannels = {
|
|||||||
APP_READY: 'app-ready',
|
APP_READY: 'app-ready',
|
||||||
RELAUNCH_REQUEST: 'relaunch-request',
|
RELAUNCH_REQUEST: 'relaunch-request',
|
||||||
|
|
||||||
|
REQUEST_FULLSCREEN: 'request-fullscreen',
|
||||||
|
REQUEST_PIP: 'request-pip',
|
||||||
|
|
||||||
SEARCH_INPUT_HANDLING_READY: 'search-input-handling-ready',
|
SEARCH_INPUT_HANDLING_READY: 'search-input-handling-ready',
|
||||||
UPDATE_SEARCH_INPUT_TEXT: 'update-search-input-text',
|
UPDATE_SEARCH_INPUT_TEXT: 'update-search-input-text',
|
||||||
|
|
||||||
|
@ -928,6 +928,14 @@ function runApp() {
|
|||||||
return app.getPath('pictures')
|
return app.getPath('pictures')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
ipcMain.on(IpcChannels.REQUEST_FULLSCREEN, ({ sender }) => {
|
||||||
|
sender.executeJavaScript('document.getElementById("videoContainer").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) => {
|
ipcMain.handle(IpcChannels.SHOW_OPEN_DIALOG, async ({ sender }, options) => {
|
||||||
const senderWindow = findSenderWindow(sender)
|
const senderWindow = findSenderWindow(sender)
|
||||||
if (senderWindow) {
|
if (senderWindow) {
|
||||||
|
@ -203,7 +203,6 @@ export default defineComponent({
|
|||||||
'updateHideLiveChat',
|
'updateHideLiveChat',
|
||||||
'updateHideActiveSubscriptions',
|
'updateHideActiveSubscriptions',
|
||||||
'updatePlayNextVideo',
|
'updatePlayNextVideo',
|
||||||
'updateDefaultTheatreMode',
|
|
||||||
'updateHideVideoDescription',
|
'updateHideVideoDescription',
|
||||||
'updateHideComments',
|
'updateHideComments',
|
||||||
'updateHideCommentPhotos',
|
'updateHideCommentPhotos',
|
||||||
|
@ -377,6 +377,10 @@ export default defineComponent({
|
|||||||
return this.$store.getters.getExternalPlayer
|
return this.$store.getters.getExternalPlayer
|
||||||
},
|
},
|
||||||
|
|
||||||
|
externalPlayerIsDefaultViewingMode: function () {
|
||||||
|
return this.externalPlayer !== '' && this.$store.getters.getDefaultViewingMode === 'external_player'
|
||||||
|
},
|
||||||
|
|
||||||
defaultPlayback: function () {
|
defaultPlayback: function () {
|
||||||
return this.$store.getters.getDefaultPlayback
|
return this.$store.getters.getDefaultPlayback
|
||||||
},
|
},
|
||||||
@ -479,13 +483,18 @@ export default defineComponent({
|
|||||||
return this.isInQuickBookmarkPlaylist ? 'base favorite' : 'base'
|
return this.isInQuickBookmarkPlaylist ? 'base favorite' : 'base'
|
||||||
},
|
},
|
||||||
|
|
||||||
watchPageLinkTo() {
|
watchVideoRoute() {
|
||||||
// For `router-link` attribute `to`
|
|
||||||
return {
|
return {
|
||||||
path: `/watch/${this.id}`,
|
path: `/watch/${this.id}`,
|
||||||
query: this.watchPageLinkQuery,
|
query: this.watchPageLinkQuery,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// For `router-link` attribute `to`
|
||||||
|
watchVideoRouterLink() {
|
||||||
|
return !this.externalPlayerIsDefaultViewingMode ? this.watchVideoRoute : {}
|
||||||
|
},
|
||||||
|
|
||||||
watchPageLinkQuery() {
|
watchPageLinkQuery() {
|
||||||
const query = {}
|
const query = {}
|
||||||
if (this.playlistIdFinal) { query.playlistId = this.playlistIdFinal }
|
if (this.playlistIdFinal) { query.playlistId = this.playlistIdFinal }
|
||||||
@ -531,6 +540,11 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
handleWatchPageLinkClick: function() {
|
||||||
|
if (this.externalPlayerIsDefaultViewingMode) {
|
||||||
|
this.handleExternalPlayer()
|
||||||
|
}
|
||||||
|
},
|
||||||
fetchDeArrowThumbnail: async function() {
|
fetchDeArrowThumbnail: async function() {
|
||||||
if (this.thumbnailPreference === 'hidden') { return }
|
if (this.thumbnailPreference === 'hidden') { return }
|
||||||
const videoId = this.id
|
const videoId = this.id
|
||||||
|
@ -14,7 +14,8 @@
|
|||||||
<router-link
|
<router-link
|
||||||
class="thumbnailLink"
|
class="thumbnailLink"
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
:to="watchPageLinkTo"
|
:to="watchVideoRouterLink"
|
||||||
|
@click.native="handleWatchPageLinkClick"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
:src="thumbnail"
|
:src="thumbnail"
|
||||||
@ -34,7 +35,7 @@
|
|||||||
{{ isLive ? $t("Video.Live") : (isUpcoming ? $t("Video.Upcoming") : displayDuration) }}
|
{{ isLive ? $t("Video.Live") : (isUpcoming ? $t("Video.Upcoming") : displayDuration) }}
|
||||||
</div>
|
</div>
|
||||||
<ft-icon-button
|
<ft-icon-button
|
||||||
v-if="externalPlayer !== ''"
|
v-if="externalPlayer !== '' && !externalPlayerIsDefaultViewingMode"
|
||||||
:title="$t('Video.External Player.OpenInTemplate', { externalPlayer })"
|
:title="$t('Video.External Player.OpenInTemplate', { externalPlayer })"
|
||||||
:icon="['fas', 'external-link-alt']"
|
:icon="['fas', 'external-link-alt']"
|
||||||
class="externalPlayerIcon"
|
class="externalPlayerIcon"
|
||||||
@ -112,7 +113,8 @@
|
|||||||
<div class="info">
|
<div class="info">
|
||||||
<router-link
|
<router-link
|
||||||
class="title"
|
class="title"
|
||||||
:to="watchPageLinkTo"
|
:to="watchVideoRouterLink"
|
||||||
|
@click.native="handleWatchPageLinkClick"
|
||||||
>
|
>
|
||||||
<h3 class="h3Title">
|
<h3 class="h3Title">
|
||||||
{{ displayTitle }}
|
{{ displayTitle }}
|
||||||
|
@ -104,12 +104,25 @@ export default defineComponent({
|
|||||||
vrProjection: {
|
vrProjection: {
|
||||||
type: String,
|
type: String,
|
||||||
default: null
|
default: null
|
||||||
|
},
|
||||||
|
startInFullscreen: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
startInFullwindow: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
startInPip: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
emits: [
|
emits: [
|
||||||
'error',
|
'error',
|
||||||
'loaded',
|
'loaded',
|
||||||
'ended',
|
'ended',
|
||||||
|
'player-destroyed',
|
||||||
'timeupdate',
|
'timeupdate',
|
||||||
'toggle-theatre-mode'
|
'toggle-theatre-mode'
|
||||||
],
|
],
|
||||||
@ -139,11 +152,15 @@ export default defineComponent({
|
|||||||
const isLive = ref(false)
|
const isLive = ref(false)
|
||||||
|
|
||||||
const useOverFlowMenu = ref(false)
|
const useOverFlowMenu = ref(false)
|
||||||
const fullWindowEnabled = ref(false)
|
|
||||||
const forceAspectRatio = ref(false)
|
const forceAspectRatio = ref(false)
|
||||||
|
|
||||||
const activeLegacyFormat = shallowRef(null)
|
const activeLegacyFormat = shallowRef(null)
|
||||||
|
|
||||||
|
const fullWindowEnabled = ref(false)
|
||||||
|
const startInFullwindow = props.startInFullwindow
|
||||||
|
let startInFullscreen = props.startInFullscreen
|
||||||
|
let startInPip = props.startInPip
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {{
|
* @type {{
|
||||||
* url: string,
|
* url: string,
|
||||||
@ -1046,6 +1063,15 @@ export default defineComponent({
|
|||||||
emit('ended')
|
emit('ended')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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() {
|
function updateVolume() {
|
||||||
const video_ = video.value
|
const video_ = video.value
|
||||||
// https://docs.videojs.com/html5#volume
|
// https://docs.videojs.com/html5#volume
|
||||||
@ -1645,7 +1671,7 @@ export default defineComponent({
|
|||||||
*/
|
*/
|
||||||
class FullWindowButtonFactory {
|
class FullWindowButtonFactory {
|
||||||
create(rootElement, controls) {
|
create(rootElement, controls) {
|
||||||
return new FullWindowButton(fullWindowEnabled.value, events, rootElement, controls)
|
return new FullWindowButton(fullWindowEnabled.value, startInFullwindow, events, rootElement, controls)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1730,7 +1756,7 @@ export default defineComponent({
|
|||||||
/**
|
/**
|
||||||
* As shaka-player doesn't let you unregister custom control factories,
|
* As shaka-player doesn't let you unregister custom control factories,
|
||||||
* overwrite them with `null` instead so the referenced objects
|
* 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() {
|
function cleanUpCustomPlayerControls() {
|
||||||
shakaControls.registerElement('ft_audio_tracks', null)
|
shakaControls.registerElement('ft_audio_tracks', null)
|
||||||
@ -2525,6 +2551,12 @@ export default defineComponent({
|
|||||||
if (props.chapters.length > 0) {
|
if (props.chapters.length > 0) {
|
||||||
createChapterMarkers()
|
createChapterMarkers()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (startInFullscreen && process.env.IS_ELECTRON) {
|
||||||
|
startInFullscreen = false
|
||||||
|
const { ipcRenderer } = require('electron')
|
||||||
|
ipcRenderer.send(IpcChannels.REQUEST_FULLSCREEN)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
@ -2741,6 +2773,12 @@ export default defineComponent({
|
|||||||
ignoreErrors = true
|
ignoreErrors = true
|
||||||
|
|
||||||
if (ui) {
|
if (ui) {
|
||||||
|
if (ui.getControls()) {
|
||||||
|
// save the state of player settings to reinitialize them upon next creation
|
||||||
|
const controls = ui.getControls()
|
||||||
|
emit('player-destroyed', controls.isFullScreenEnabled(), fullWindowEnabled.value, controls.isPiPEnabled())
|
||||||
|
}
|
||||||
|
|
||||||
// destroying the ui also destroys the player
|
// destroying the ui also destroys the player
|
||||||
await ui.destroy()
|
await ui.destroy()
|
||||||
ui = null
|
ui = null
|
||||||
@ -2793,6 +2831,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
handlePlay,
|
handlePlay,
|
||||||
handlePause,
|
handlePause,
|
||||||
|
handleCanPlay,
|
||||||
handleEnded,
|
handleEnded,
|
||||||
updateVolume,
|
updateVolume,
|
||||||
handleTimeupdate,
|
handleTimeupdate,
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
|
id="videoContainer"
|
||||||
ref="container"
|
ref="container"
|
||||||
class="ftVideoPlayer shaka-video-container"
|
class="ftVideoPlayer shaka-video-container"
|
||||||
:class="{
|
:class="{
|
||||||
@ -9,6 +10,7 @@
|
|||||||
>
|
>
|
||||||
<!-- eslint-disable-next-line vuejs-accessibility/media-has-caption -->
|
<!-- eslint-disable-next-line vuejs-accessibility/media-has-caption -->
|
||||||
<video
|
<video
|
||||||
|
id="video"
|
||||||
ref="video"
|
ref="video"
|
||||||
class="player"
|
class="player"
|
||||||
preload="auto"
|
preload="auto"
|
||||||
@ -19,6 +21,7 @@
|
|||||||
@play="handlePlay"
|
@play="handlePlay"
|
||||||
@pause="handlePause"
|
@pause="handlePause"
|
||||||
@ended="handleEnded"
|
@ended="handleEnded"
|
||||||
|
@canplay="handleCanPlay"
|
||||||
@volumechange="updateVolume"
|
@volumechange="updateVolume"
|
||||||
@timeupdate="handleTimeupdate"
|
@timeupdate="handleTimeupdate"
|
||||||
/>
|
/>
|
||||||
|
@ -5,11 +5,12 @@ import i18n from '../../../i18n/index'
|
|||||||
export class FullWindowButton extends shaka.ui.Element {
|
export class FullWindowButton extends shaka.ui.Element {
|
||||||
/**
|
/**
|
||||||
* @param {boolean} fullWindowEnabled
|
* @param {boolean} fullWindowEnabled
|
||||||
|
* @param {boolean} startInFullWindow
|
||||||
* @param {EventTarget} events
|
* @param {EventTarget} events
|
||||||
* @param {HTMLElement} parent
|
* @param {HTMLElement} parent
|
||||||
* @param {shaka.ui.Controls} controls
|
* @param {shaka.ui.Controls} controls
|
||||||
*/
|
*/
|
||||||
constructor(fullWindowEnabled, events, parent, controls) {
|
constructor(fullWindowEnabled, startInFullWindow, events, parent, controls) {
|
||||||
super(parent, controls)
|
super(parent, controls)
|
||||||
|
|
||||||
/** @private */
|
/** @private */
|
||||||
@ -62,6 +63,12 @@ export class FullWindowButton extends shaka.ui.Element {
|
|||||||
this.updateLocalisedStrings_()
|
this.updateLocalisedStrings_()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if (startInFullWindow) {
|
||||||
|
events.dispatchEvent(new CustomEvent('setFullWindow', {
|
||||||
|
detail: true
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
this.updateLocalisedStrings_()
|
this.updateLocalisedStrings_()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,6 +60,13 @@ export default defineComponent({
|
|||||||
screenshotFolderPlaceholder: '',
|
screenshotFolderPlaceholder: '',
|
||||||
screenshotFilenameExample: '',
|
screenshotFilenameExample: '',
|
||||||
screenshotDefaultPattern: '%Y%M%D-%H%N%S',
|
screenshotDefaultPattern: '%Y%M%D-%H%N%S',
|
||||||
|
viewingModeValues: [
|
||||||
|
'default',
|
||||||
|
...(process.env.IS_ELECTRON ? ['fullscreen'] : []),
|
||||||
|
'fullwindow',
|
||||||
|
...(process.env.IS_ELECTRON ? ['pip'] : []),
|
||||||
|
'external_player'
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@ -119,10 +126,24 @@ export default defineComponent({
|
|||||||
return this.$store.getters.getDefaultQuality
|
return this.$store.getters.getDefaultQuality
|
||||||
},
|
},
|
||||||
|
|
||||||
|
defaultViewingMode: function () {
|
||||||
|
const defaultViewingMode = this.$store.getters.getDefaultViewingMode
|
||||||
|
if ((defaultViewingMode === 'external_player' && this.externalPlayer === '') ||
|
||||||
|
(!process.env.IS_ELECTRON && (defaultViewingMode === 'fullscreen' || defaultViewingMode === 'pip'))) {
|
||||||
|
return 'default'
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultViewingMode
|
||||||
|
},
|
||||||
|
|
||||||
defaultTheatreMode: function () {
|
defaultTheatreMode: function () {
|
||||||
return this.$store.getters.getDefaultTheatreMode
|
return this.$store.getters.getDefaultTheatreMode
|
||||||
},
|
},
|
||||||
|
|
||||||
|
externalPlayer: function () {
|
||||||
|
return this.$store.getters.getExternalPlayer
|
||||||
|
},
|
||||||
|
|
||||||
hideRecommendedVideos: function () {
|
hideRecommendedVideos: function () {
|
||||||
return this.$store.getters.getHideRecommendedVideos
|
return this.$store.getters.getHideRecommendedVideos
|
||||||
},
|
},
|
||||||
@ -177,6 +198,23 @@ export default defineComponent({
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
|
viewingModeNames: function () {
|
||||||
|
const viewingModeNames = [
|
||||||
|
this.$t('Settings.General Settings.Thumbnail Preference.Default'),
|
||||||
|
...(process.env.IS_ELECTRON ? [this.$t('Settings.Player Settings.Default Viewing Mode.Full Screen')] : []),
|
||||||
|
this.$t('Video.Player.Full Window'),
|
||||||
|
...(process.env.IS_ELECTRON ? [this.$t('Settings.Player Settings.Default Viewing Mode.Picture in Picture')] : [])
|
||||||
|
]
|
||||||
|
|
||||||
|
if (this.externalPlayer !== '') {
|
||||||
|
viewingModeNames.push(
|
||||||
|
this.$t('Settings.Player Settings.Default Viewing Mode.External Player', { externalPlayerName: this.externalPlayer })
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return viewingModeNames
|
||||||
|
},
|
||||||
|
|
||||||
enableScreenshot: function() {
|
enableScreenshot: function() {
|
||||||
return this.$store.getters.getEnableScreenshot
|
return this.$store.getters.getEnableScreenshot
|
||||||
},
|
},
|
||||||
@ -289,11 +327,12 @@ export default defineComponent({
|
|||||||
'updatePlayNextVideo',
|
'updatePlayNextVideo',
|
||||||
'updateEnableSubtitlesByDefault',
|
'updateEnableSubtitlesByDefault',
|
||||||
'updateProxyVideos',
|
'updateProxyVideos',
|
||||||
'updateDefaultTheatreMode',
|
'updateDefaultViewingMode',
|
||||||
'updateDefaultSkipInterval',
|
'updateDefaultSkipInterval',
|
||||||
'updateDefaultInterval',
|
'updateDefaultInterval',
|
||||||
'updateDefaultVolume',
|
'updateDefaultVolume',
|
||||||
'updateDefaultPlayback',
|
'updateDefaultPlayback',
|
||||||
|
'updateDefaultTheatreMode',
|
||||||
'updateDefaultVideoFormat',
|
'updateDefaultVideoFormat',
|
||||||
'updateDefaultQuality',
|
'updateDefaultQuality',
|
||||||
'updateVideoVolumeMouseScroll',
|
'updateVideoVolumeMouseScroll',
|
||||||
|
@ -81,6 +81,41 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<ft-flex-box>
|
||||||
|
<ft-select
|
||||||
|
:placeholder="$t('Settings.Player Settings.Default Viewing Mode.Default Viewing Mode')"
|
||||||
|
:value="defaultViewingMode"
|
||||||
|
:select-names="viewingModeNames"
|
||||||
|
:select-values="viewingModeValues"
|
||||||
|
:icon="['fas', 'expand']"
|
||||||
|
@change="updateDefaultViewingMode"
|
||||||
|
/>
|
||||||
|
<ft-select
|
||||||
|
:placeholder="$t('Settings.Player Settings.Default Video Format.Default Video Format')"
|
||||||
|
:value="defaultVideoFormat"
|
||||||
|
:select-names="formatNames"
|
||||||
|
:select-values="formatValues"
|
||||||
|
:tooltip="$t('Tooltips.Player Settings.Default Video Format')"
|
||||||
|
:icon="['fas', 'file-video']"
|
||||||
|
@change="updateDefaultVideoFormat"
|
||||||
|
/>
|
||||||
|
<ft-select
|
||||||
|
:placeholder="$t('Settings.Player Settings.Default Quality.Default Quality')"
|
||||||
|
:value="defaultQuality"
|
||||||
|
:select-names="qualityNames"
|
||||||
|
:select-values="qualityValues"
|
||||||
|
:icon="['fas', 'photo-film']"
|
||||||
|
@change="updateDefaultQuality"
|
||||||
|
/>
|
||||||
|
<ft-select
|
||||||
|
:placeholder="$t('Settings.Player Settings.Video Playback Rate Interval')"
|
||||||
|
:value="videoPlaybackRateInterval"
|
||||||
|
:select-names="playbackRateIntervalValues"
|
||||||
|
:select-values="playbackRateIntervalValues"
|
||||||
|
:icon="['fas', 'gauge']"
|
||||||
|
@change="updateVideoPlaybackRateInterval"
|
||||||
|
/>
|
||||||
|
</ft-flex-box>
|
||||||
<ft-flex-box>
|
<ft-flex-box>
|
||||||
<ft-slider
|
<ft-slider
|
||||||
:label="$t('Settings.Player Settings.Fast-Forward / Rewind Interval')"
|
:label="$t('Settings.Player Settings.Fast-Forward / Rewind Interval')"
|
||||||
@ -127,33 +162,6 @@
|
|||||||
value-extension="x"
|
value-extension="x"
|
||||||
@change="updateMaxVideoPlaybackRate"
|
@change="updateMaxVideoPlaybackRate"
|
||||||
/>
|
/>
|
||||||
<ft-select
|
|
||||||
:placeholder="$t('Settings.Player Settings.Video Playback Rate Interval')"
|
|
||||||
:value="videoPlaybackRateInterval"
|
|
||||||
:select-names="playbackRateIntervalValues"
|
|
||||||
:select-values="playbackRateIntervalValues"
|
|
||||||
:icon="['fas', 'gauge']"
|
|
||||||
@change="updateVideoPlaybackRateInterval"
|
|
||||||
/>
|
|
||||||
</ft-flex-box>
|
|
||||||
<ft-flex-box>
|
|
||||||
<ft-select
|
|
||||||
:placeholder="$t('Settings.Player Settings.Default Video Format.Default Video Format')"
|
|
||||||
:value="defaultVideoFormat"
|
|
||||||
:select-names="formatNames"
|
|
||||||
:select-values="formatValues"
|
|
||||||
:tooltip="$t('Tooltips.Player Settings.Default Video Format')"
|
|
||||||
:icon="['fas', 'file-video']"
|
|
||||||
@change="updateDefaultVideoFormat"
|
|
||||||
/>
|
|
||||||
<ft-select
|
|
||||||
:placeholder="$t('Settings.Player Settings.Default Quality.Default Quality')"
|
|
||||||
:value="defaultQuality"
|
|
||||||
:select-names="qualityNames"
|
|
||||||
:select-values="qualityValues"
|
|
||||||
:icon="['fas', 'photo-film']"
|
|
||||||
@change="updateDefaultQuality"
|
|
||||||
/>
|
|
||||||
</ft-flex-box>
|
</ft-flex-box>
|
||||||
<br>
|
<br>
|
||||||
<ft-flex-box
|
<ft-flex-box
|
||||||
|
@ -45,6 +45,7 @@ import {
|
|||||||
faEnvelope,
|
faEnvelope,
|
||||||
faExchangeAlt,
|
faExchangeAlt,
|
||||||
faExclamationCircle,
|
faExclamationCircle,
|
||||||
|
faExpand,
|
||||||
faExternalLinkAlt,
|
faExternalLinkAlt,
|
||||||
faEye,
|
faEye,
|
||||||
faEyeSlash,
|
faEyeSlash,
|
||||||
@ -158,6 +159,7 @@ library.add(
|
|||||||
faEnvelope,
|
faEnvelope,
|
||||||
faExchangeAlt,
|
faExchangeAlt,
|
||||||
faExclamationCircle,
|
faExclamationCircle,
|
||||||
|
faExpand,
|
||||||
faExternalLinkAlt,
|
faExternalLinkAlt,
|
||||||
faEye,
|
faEye,
|
||||||
faEyeSlash,
|
faEyeSlash,
|
||||||
|
@ -179,6 +179,7 @@ const state = {
|
|||||||
defaultQuality: '720',
|
defaultQuality: '720',
|
||||||
defaultSkipInterval: 5,
|
defaultSkipInterval: 5,
|
||||||
defaultTheatreMode: false,
|
defaultTheatreMode: false,
|
||||||
|
defaultViewingMode: 'default',
|
||||||
defaultVideoFormat: 'dash',
|
defaultVideoFormat: 'dash',
|
||||||
disableSmoothScrolling: false,
|
disableSmoothScrolling: false,
|
||||||
displayVideoPlayButton: false,
|
displayVideoPlayButton: false,
|
||||||
|
@ -66,6 +66,9 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
data: function () {
|
data: function () {
|
||||||
return {
|
return {
|
||||||
|
startNextVideoInFullscreen: false,
|
||||||
|
startNextVideoInFullwindow: false,
|
||||||
|
startNextVideoInPip: false,
|
||||||
isLoading: true,
|
isLoading: true,
|
||||||
firstLoad: true,
|
firstLoad: true,
|
||||||
useTheatreMode: false,
|
useTheatreMode: false,
|
||||||
@ -166,6 +169,12 @@ export default defineComponent({
|
|||||||
defaultTheatreMode: function () {
|
defaultTheatreMode: function () {
|
||||||
return this.$store.getters.getDefaultTheatreMode
|
return this.$store.getters.getDefaultTheatreMode
|
||||||
},
|
},
|
||||||
|
defaultViewingMode: function () {
|
||||||
|
return this.$store.getters.getDefaultViewingMode
|
||||||
|
},
|
||||||
|
externalPlayer: function () {
|
||||||
|
return this.$store.getters.getExternalPlayer
|
||||||
|
},
|
||||||
defaultVideoFormat: function () {
|
defaultVideoFormat: function () {
|
||||||
return this.$store.getters.getDefaultVideoFormat
|
return this.$store.getters.getDefaultVideoFormat
|
||||||
},
|
},
|
||||||
@ -313,7 +322,7 @@ export default defineComponent({
|
|||||||
this.checkIfPlaylist()
|
this.checkIfPlaylist()
|
||||||
|
|
||||||
// this has to be below checkIfPlaylist() as theatrePossible needs to know if there is a playlist or not
|
// this has to be below checkIfPlaylist() as theatrePossible needs to know if there is a playlist or not
|
||||||
this.useTheatreMode = this.defaultTheatreMode && this.theatrePossible
|
this.setViewingModeOnFirstLoad()
|
||||||
|
|
||||||
if (!process.env.SUPPORTS_LOCAL_API || this.backendPreference === 'invidious') {
|
if (!process.env.SUPPORTS_LOCAL_API || this.backendPreference === 'invidious') {
|
||||||
this.getVideoInformationInvidious()
|
this.getVideoInformationInvidious()
|
||||||
@ -324,6 +333,21 @@ export default defineComponent({
|
|||||||
window.addEventListener('beforeunload', this.handleWatchProgress)
|
window.addEventListener('beforeunload', this.handleWatchProgress)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setViewingModeOnFirstLoad: function () {
|
||||||
|
this.useTheatreMode = this.defaultTheatreMode && this.theatrePossible
|
||||||
|
|
||||||
|
switch (this.defaultViewingMode) {
|
||||||
|
case 'fullscreen':
|
||||||
|
this.startNextVideoInFullscreen = true
|
||||||
|
return
|
||||||
|
case 'fullwindow':
|
||||||
|
this.startNextVideoInFullwindow = true
|
||||||
|
return
|
||||||
|
case 'pip':
|
||||||
|
this.startNextVideoInPip = true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
changeTimestamp: function (timestamp) {
|
changeTimestamp: function (timestamp) {
|
||||||
const player = this.$refs.player
|
const player = this.$refs.player
|
||||||
|
|
||||||
@ -1228,6 +1252,12 @@ export default defineComponent({
|
|||||||
this.activeFormat = 'audio'
|
this.activeFormat = 'audio'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
handlePlayerDestroyed: function(startNextVideoInFullscreen = false, startNextVideoInFullwindow = false, startNextVideoInPip = false) {
|
||||||
|
this.startNextVideoInFullscreen = startNextVideoInFullscreen
|
||||||
|
this.startNextVideoInFullwindow = startNextVideoInFullwindow
|
||||||
|
this.startNextVideoInPip = startNextVideoInPip
|
||||||
|
},
|
||||||
|
|
||||||
handleVideoEnded: function () {
|
handleVideoEnded: function () {
|
||||||
if ((!this.watchingPlaylist || !this.autoplayPlaylists) && !this.playNextVideo) {
|
if ((!this.watchingPlaylist || !this.autoplayPlaylists) && !this.playNextVideo) {
|
||||||
return
|
return
|
||||||
|
@ -34,10 +34,14 @@
|
|||||||
:theatre-possible="theatrePossible"
|
:theatre-possible="theatrePossible"
|
||||||
:use-theatre-mode="useTheatreMode"
|
:use-theatre-mode="useTheatreMode"
|
||||||
:vr-projection="vrProjection"
|
:vr-projection="vrProjection"
|
||||||
|
:start-in-fullscreen="startNextVideoInFullscreen"
|
||||||
|
:start-in-fullwindow="startNextVideoInFullwindow"
|
||||||
|
:start-in-pip="startNextVideoInPip"
|
||||||
class="videoPlayer"
|
class="videoPlayer"
|
||||||
@error="handlePlayerError"
|
@error="handlePlayerError"
|
||||||
@loaded="handleVideoLoaded"
|
@loaded="handleVideoLoaded"
|
||||||
@timeupdate="updateCurrentChapter"
|
@timeupdate="updateCurrentChapter"
|
||||||
|
@player-destroyed="handlePlayerDestroyed"
|
||||||
@ended="handleVideoEnded"
|
@ended="handleVideoEnded"
|
||||||
@toggle-theatre-mode="useTheatreMode = !useTheatreMode"
|
@toggle-theatre-mode="useTheatreMode = !useTheatreMode"
|
||||||
/>
|
/>
|
||||||
|
@ -686,20 +686,23 @@ Channel:
|
|||||||
Shorts:
|
Shorts:
|
||||||
This channel does not currently have any shorts: ''
|
This channel does not currently have any shorts: ''
|
||||||
Live:
|
Live:
|
||||||
Live: ''
|
Live: 'Regstreeks'
|
||||||
This channel does not currently have any live streams: ''
|
This channel does not currently have any live streams: 'Hierdie kanaal het tans
|
||||||
|
geen rekstreekse stromings nie'
|
||||||
Playlists:
|
Playlists:
|
||||||
Playlists: ''
|
Playlists: 'Afspeellyste'
|
||||||
This channel does not currently have any playlists: ''
|
This channel does not currently have any playlists: 'Hierdie kanaal het tans geen
|
||||||
|
afspeellyste nie'
|
||||||
Sort Types:
|
Sort Types:
|
||||||
Last Video Added: ''
|
Last Video Added: 'Laaste toegevoegde video'
|
||||||
Newest: ''
|
Newest: 'Nuutste'
|
||||||
Oldest: ''
|
Oldest: 'Oudste'
|
||||||
Podcasts:
|
Podcasts:
|
||||||
Podcasts: ''
|
Podcasts: 'Podsendings'
|
||||||
This channel does not currently have any podcasts: ''
|
This channel does not currently have any podcasts: 'Hierdie kanaal het tans geen
|
||||||
|
podsendings nie'
|
||||||
Releases:
|
Releases:
|
||||||
Releases: ''
|
Releases: 'Vrystellings'
|
||||||
This channel does not currently have any releases: 'Hierdie kanaal het nie tans
|
This channel does not currently have any releases: 'Hierdie kanaal het nie tans
|
||||||
enige vrystellings nie'
|
enige vrystellings nie'
|
||||||
About:
|
About:
|
||||||
|
@ -392,11 +392,16 @@ Settings:
|
|||||||
Player Settings:
|
Player Settings:
|
||||||
Player Settings: Player
|
Player Settings: Player
|
||||||
Play Next Video: Play Next Video
|
Play Next Video: Play Next Video
|
||||||
Turn on Subtitles by Default: Turn on Subtitles by Default
|
Turn on Subtitles by Default: Enable Subtitles by Default
|
||||||
Autoplay Videos: Autoplay Videos
|
Autoplay Videos: Autoplay Videos
|
||||||
Proxy Videos Through Invidious: Proxy Videos Through Invidious
|
Proxy Videos Through Invidious: Proxy Videos Through Invidious
|
||||||
Autoplay Playlists: Autoplay Playlists
|
Autoplay Playlists: Autoplay Playlists
|
||||||
Enable Theatre Mode by Default: Enable Theatre Mode by Default
|
Enable Theatre Mode by Default: Enable Theater Mode by Default
|
||||||
|
Default Viewing Mode:
|
||||||
|
Default Viewing Mode: Default Viewing Mode
|
||||||
|
Full Screen: Full Screen
|
||||||
|
Picture in Picture: Picture in Picture
|
||||||
|
External Player: External Player ({externalPlayerName})
|
||||||
Scroll Volume Over Video Player: Scroll Volume Over Video Player
|
Scroll Volume Over Video Player: Scroll Volume Over Video Player
|
||||||
Scroll Playback Rate Over Video Player: Scroll Playback Rate 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
|
Skip by Scrolling Over Video Player: Skip by Scrolling Over Video Player
|
||||||
|
Loading…
Reference in New Issue
Block a user