diff --git a/.github/workflows/report.yml b/.github/workflows/report.yml new file mode 100644 index 00000000..e24f0b48 --- /dev/null +++ b/.github/workflows/report.yml @@ -0,0 +1,50 @@ +# This is a basic workflow to help you get started with Actions + +name: Project Board Automation + +on: + issues: + types: [labeled, unlabeled, closed, deleted] + +jobs: + assign-issues-to-projects: + runs-on: ubuntu-latest + steps: + + # For bug reports + - name: New bug issue + uses: alex-page/github-project-automation-plus@v0.5.1 + if: github.event.action == 'labeled' && contains(github.event.issue.labels.*.name, 'bug') + with: + project: Bug Reports + column: To assign + repo-token: ${{ secrets.PUSH_TOKEN }} + action: update + + - name: Bug label removed + uses: alex-page/github-project-automation-plus@v0.5.1 + if: github.event.action == 'unlabeled' || github.event.action == 'closed' || github.event.action == 'deleted' + with: + action: delete + project: Bug Reports + column: To assign + repo-token: ${{ secrets.PUSH_TOKEN }} + + # For feature requests + - name: New feature issue + uses: alex-page/github-project-automation-plus@v0.5.1 + if: github.event.action == 'labeled' && contains(github.event.issue.labels.*.name, 'enhancement') + with: + project: Feature Requests + column: To assign + repo-token: ${{ secrets.PUSH_TOKEN }} + action: update + + - name: Feature request label removed + uses: alex-page/github-project-automation-plus@v0.5.1 + if: github.event.action == 'unlabeled' || github.event.action == 'closed' || github.event.action == 'deleted' + with: + action: delete + project: Feature Requests + column: To assign + repo-token: ${{ secrets.PUSH_TOKEN }} diff --git a/package-lock.json b/package-lock.json index 67ce048c..d2d0d70e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10734,9 +10734,9 @@ } }, "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", + "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", "dev": true }, "yargs": { @@ -11499,9 +11499,9 @@ } }, "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", + "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", "dev": true }, "yargs": { @@ -18293,18 +18293,18 @@ } }, "youtube-suggest": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/youtube-suggest/-/youtube-suggest-1.1.1.tgz", - "integrity": "sha512-nMkXJV24xe0QZ67YAfEtVfdGCtuyhOMcvX4GkO824TivwQbkHMNaWlMGlUkePSXCu2vPReP6nYhknoHzmD0/Aw==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/youtube-suggest/-/youtube-suggest-1.1.2.tgz", + "integrity": "sha512-U1CrSIDf9q4H7lx84YiAPfGyMLIXDmSlOLrwcXBkGJFEUodzrD+ZSYMEpJK5UNVWyzE73yxvwGtqrV0dbNQ6LA==", "requires": { "node-fetch": "^2.6.0", "smol-jsonp": "^1.0.0" } }, "yt-channel-info": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/yt-channel-info/-/yt-channel-info-1.3.0.tgz", - "integrity": "sha512-75ML9snDZhXSkaczR3mgcq6EyI2jjPYzjXcz5TV9C9gSRkhCv2gxVhJVPXfeUQuAa0YGySE3F1V0Yz2HyY3zfg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yt-channel-info/-/yt-channel-info-2.0.0.tgz", + "integrity": "sha512-Qrd9ONv9NbVPGGwCWPDwuQds43iXcNQHMB4iE9VqBtDt9WuMKoZd6BvoZDT10QCKisknByO1XIkM1hxbKyZNnA==", "requires": { "axios": "^0.21.1", "querystring": "^0.2.0" @@ -18326,9 +18326,9 @@ } }, "yt-comment-scraper": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/yt-comment-scraper/-/yt-comment-scraper-3.0.2.tgz", - "integrity": "sha512-vWg/2D0eCJ0DTRayBmxqjZdBXSjArDFp/UAlK/r9tOq+x89hyQwuvP5r5URzLeRXGyv0g0COXsNapZGQR5aaPA==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/yt-comment-scraper/-/yt-comment-scraper-4.0.1.tgz", + "integrity": "sha512-5uReiiLnaBhTBBsTfxIYcoV62EATe8dXAkkUCkCG3pgLU+qty9iCjNQvSgY8tZhnCPNAPO+lJaxzbGJ3hJRm4g==", "requires": { "axios": "^0.21.1", "node-html-parser": "^2.0.2" @@ -18377,9 +18377,9 @@ } }, "yt-trending-scraper": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/yt-trending-scraper/-/yt-trending-scraper-1.1.1.tgz", - "integrity": "sha512-ElD3MIZ1ukjOcexYm5VIdLtY22hskrtHA9+8t/5Ox8CG7+vGlTJy2N5MUVAhh0ucoOl8cfkVrsuEUQbzXeABig==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/yt-trending-scraper/-/yt-trending-scraper-1.1.2.tgz", + "integrity": "sha512-kRR/bBhNBq/GAvHDSdKE9MxJcwg+CxWb/JZtr2J3xZZ5UF3txdUc3zCLxqf+RRVcdJuObxEv0MgReCwspoFoAg==", "requires": { "axios": "^0.21.1" }, diff --git a/package.json b/package.json index 807f023c..785dc88c 100644 --- a/package.json +++ b/package.json @@ -46,9 +46,9 @@ "vuex": "^3.6.2", "xml2json": "^0.12.0", "youtube-chat": "git+https://github.com/IcedCoffeee/youtube-chat.git", - "youtube-suggest": "^1.1.1", - "yt-channel-info": "^1.3.0", - "yt-comment-scraper": "^3.0.2", + "youtube-suggest": "^1.1.2", + "yt-channel-info": "^2.0.0", + "yt-comment-scraper": "^4.0.1", "yt-dash-manifest-generator": "1.1.0", "yt-trending-scraper": "^1.1.1", "yt-xml2vtt": "^1.2.0", diff --git a/src/main/index.js b/src/main/index.js index 1ff88842..7e116cb2 100644 --- a/src/main/index.js +++ b/src/main/index.js @@ -1,75 +1,150 @@ import { app, BrowserWindow, Menu, ipcMain, screen } from 'electron' -import { productName } from '../../package.json' import Datastore from 'nedb' -require('@electron/remote/main').initialize() - -require('electron-context-menu')({ - showSearchWithGoogle: false, - showSaveImageAs: true, - showCopyImageAddress: true, - prepend: (params, browserWindow) => [] -}) - -const localDataStorage = app.getPath('userData') // Grabs the userdata directory based on the user's OS - -const settingsDb = new Datastore({ - filename: localDataStorage + '/settings.db', - autoload: true -}) - -// set app name -app.setName(productName) - -// disable electron warning -process.env.ELECTRON_DISABLE_SECURITY_WARNINGS = 'true' -const path = require('path') -const isDev = process.env.NODE_ENV === 'development' -const isDebug = process.argv.includes('--debug') -let mainWindow -let startupUrl - -// CORS somehow gets re-enabled in Electron v9.0.4 -// This line disables it. -// This line can possible be removed if the issue is fixed upstream -app.commandLine.appendSwitch('disable-features', 'OutOfBlinkCors') - -app.commandLine.appendSwitch('enable-accelerated-video-decode') -app.commandLine.appendSwitch('ignore-gpu-blacklist') - -// See: https://stackoverflow.com/questions/45570589/electron-protocol-handler-not-working-on-windows -// remove so we can register each time as we run the app. -app.removeAsDefaultProtocolClient('freetube') - -// If we are running a non-packaged version of the app && on windows -if (isDev && process.platform === 'win32') { - // Set the path of electron.exe and your app. - // These two additional parameters are only available on windows. - app.setAsDefaultProtocolClient('freetube', process.execPath, [path.resolve(process.argv[1])]) +if (process.argv.includes('--version')) { + console.log(`v${app.getVersion()}`) + app.exit(0) } else { - app.setAsDefaultProtocolClient('freetube') + runApp() } -// TODO: Uncomment if needed -// only allow single instance of application -if (!isDev) { - const gotTheLock = app.requestSingleInstanceLock() +function runApp() { + require('@electron/remote/main').initialize() - if (gotTheLock) { - app.on('second-instance', (event, commandLine, workingDirectory) => { - // Someone tried to run a second instance, we should focus our window. - if (mainWindow && typeof (commandLine) !== 'undefined') { - if (mainWindow.isMinimized()) mainWindow.restore() - mainWindow.focus() + require('electron-context-menu')({ + showSearchWithGoogle: false, + showSaveImageAs: true, + showCopyImageAddress: true, + prepend: (params, browserWindow) => [] + }) - const url = getLinkUrl(commandLine) - if (url) { - mainWindow.webContents.send('openUrl', url) + const localDataStorage = app.getPath('userData') // Grabs the userdata directory based on the user's OS + + const settingsDb = new Datastore({ + filename: localDataStorage + '/settings.db', + autoload: true + }) + + // disable electron warning + process.env.ELECTRON_DISABLE_SECURITY_WARNINGS = 'true' + const path = require('path') + const isDev = process.env.NODE_ENV === 'development' + const isDebug = process.argv.includes('--debug') + let mainWindow + let startupUrl + + // CORS somehow gets re-enabled in Electron v9.0.4 + // This line disables it. + // This line can possible be removed if the issue is fixed upstream + app.commandLine.appendSwitch('disable-features', 'OutOfBlinkCors') + + app.commandLine.appendSwitch('enable-accelerated-video-decode') + app.commandLine.appendSwitch('enable-file-cookies') + app.commandLine.appendSwitch('ignore-gpu-blacklist') + + // See: https://stackoverflow.com/questions/45570589/electron-protocol-handler-not-working-on-windows + // remove so we can register each time as we run the app. + app.removeAsDefaultProtocolClient('freetube') + + // If we are running a non-packaged version of the app && on windows + if (isDev && process.platform === 'win32') { + // Set the path of electron.exe and your app. + // These two additional parameters are only available on windows. + app.setAsDefaultProtocolClient('freetube', process.execPath, [path.resolve(process.argv[1])]) + } else { + app.setAsDefaultProtocolClient('freetube') + } + + // TODO: Uncomment if needed + // only allow single instance of application + if (!isDev) { + const gotTheLock = app.requestSingleInstanceLock() + + if (gotTheLock) { + app.on('second-instance', (event, commandLine, workingDirectory) => { + // Someone tried to run a second instance, we should focus our window. + if (mainWindow && typeof (commandLine) !== 'undefined') { + if (mainWindow.isMinimized()) mainWindow.restore() + mainWindow.focus() + + const url = getLinkUrl(commandLine) + if (url) { + mainWindow.webContents.send('openUrl', url) + } } - } + }) + + app.on('ready', (event, commandLine, workingDirectory) => { + settingsDb.find({ + $or: [ + { _id: 'disableSmoothScrolling' }, + { _id: 'useProxy' }, + { _id: 'proxyProtocol' }, + { _id: 'proxyHostname' }, + { _id: 'proxyPort' } + ] + }, function (err, doc) { + if (err) { + app.exit(0) + return + } + + let disableSmoothScrolling = false + let useProxy = false + let proxyProtocol = 'socks5' + let proxyHostname = '127.0.0.1' + let proxyPort = '9050' + + if (typeof doc === 'object' && doc.length > 0) { + doc.forEach((dbItem) => { + switch (dbItem._id) { + case 'disableSmoothScrolling': + disableSmoothScrolling = dbItem.value + break + case 'useProxy': + useProxy = dbItem.value + break + case 'proxyProtocol': + proxyProtocol = dbItem.value + break + case 'proxyHostname': + proxyHostname = dbItem.value + break + case 'proxyPort': + proxyPort = dbItem.value + break + } + }) + } + + if (disableSmoothScrolling) { + app.commandLine.appendSwitch('disable-smooth-scrolling') + } else { + app.commandLine.appendSwitch('enable-smooth-scrolling') + } + + const proxyUrl = `${proxyProtocol}://${proxyHostname}:${proxyPort}` + + createWindow(useProxy, proxyUrl) + + if (isDev) { + installDevTools() + } + + if (isDebug) { + mainWindow.webContents.openDevTools() + } + }) + }) + } else { + app.quit() + } + } else { + require('electron-debug')({ + showDevTools: !(process.env.RENDERER_REMOTE_DEBUGGING === 'true') }) - app.on('ready', (event, commandLine, workingDirectory) => { + app.on('ready', () => { settingsDb.find({ $or: [ { _id: 'disableSmoothScrolling' }, @@ -131,426 +206,371 @@ if (!isDev) { } }) }) - } else { - app.quit() - } -} else { - require('electron-debug')({ - showDevTools: !(process.env.RENDERER_REMOTE_DEBUGGING === 'true') - }) - - app.on('ready', () => { - settingsDb.find({ - $or: [ - { _id: 'disableSmoothScrolling' }, - { _id: 'useProxy' }, - { _id: 'proxyProtocol' }, - { _id: 'proxyHostname' }, - { _id: 'proxyPort' } - ] - }, function (err, doc) { - if (err) { - app.exit(0) - return - } - - let disableSmoothScrolling = false - let useProxy = false - let proxyProtocol = 'socks5' - let proxyHostname = '127.0.0.1' - let proxyPort = '9050' - - if (typeof doc === 'object' && doc.length > 0) { - doc.forEach((dbItem) => { - switch (dbItem._id) { - case 'disableSmoothScrolling': - disableSmoothScrolling = dbItem.value - break - case 'useProxy': - useProxy = dbItem.value - break - case 'proxyProtocol': - proxyProtocol = dbItem.value - break - case 'proxyHostname': - proxyHostname = dbItem.value - break - case 'proxyPort': - proxyPort = dbItem.value - break - } - }) - } - - if (disableSmoothScrolling) { - app.commandLine.appendSwitch('disable-smooth-scrolling') - } else { - app.commandLine.appendSwitch('enable-smooth-scrolling') - } - - const proxyUrl = `${proxyProtocol}://${proxyHostname}:${proxyPort}` - - createWindow(useProxy, proxyUrl) - - if (isDev) { - installDevTools() - } - - if (isDebug) { - mainWindow.webContents.openDevTools() - } - }) - }) -} - -async function installDevTools () { - try { - /* eslint-disable */ - require('devtron').install() - require('vue-devtools').install() - /* eslint-enable */ - } catch (err) { - console.log(err) - } -} - -function createWindow (useProxy = false, proxyUrl = '') { - /** - * Initial window options - */ - mainWindow = new BrowserWindow({ - backgroundColor: '#fff', - icon: isDev - ? path.join(__dirname, '../../_icons/iconColor.png') - /* eslint-disable-next-line */ - : `${__dirname}/_icons/iconColor.png`, - autoHideMenuBar: true, - // useContentSize: true, - webPreferences: { - nodeIntegration: true, - nodeIntegrationInWorker: false, - webSecurity: false, - backgroundThrottling: false, - enableRemoteModule: true, - contextIsolation: false - }, - show: false - }) - - mainWindow.setBounds({ - width: 1200, - height: 800 - }) - - if (useProxy) { - mainWindow.webContents.session.setProxy({ - proxyRules: proxyUrl - }) } - settingsDb.findOne({ - _id: 'bounds' - }, function (err, doc) { - if (doc === null || err) { - return + async function installDevTools () { + try { + /* eslint-disable */ + require('devtron').install() + require('vue-devtools').install() + /* eslint-enable */ + } catch (err) { + console.log(err) } + } - if (typeof doc !== 'object' || typeof doc.value !== 'object') { - return - } + function createWindow (useProxy = false, proxyUrl = '') { + /** + * Initial window options + */ + mainWindow = new BrowserWindow({ + backgroundColor: '#fff', + icon: isDev + ? path.join(__dirname, '../../_icons/iconColor.png') + /* eslint-disable-next-line */ + : `${__dirname}/_icons/iconColor.png`, + autoHideMenuBar: true, + // useContentSize: true, + webPreferences: { + nodeIntegration: true, + nodeIntegrationInWorker: false, + webSecurity: false, + backgroundThrottling: false, + enableRemoteModule: true, + contextIsolation: false + }, + show: false + }) - const { maximized, ...bounds } = doc.value - const allDisplaysSummaryWidth = screen - .getAllDisplays() - .reduce((accumulator, { size: { width } }) => accumulator + width, 0) + mainWindow.setBounds({ + width: 1200, + height: 800 + }) - if (allDisplaysSummaryWidth >= bounds.x) { - mainWindow.setBounds({ - x: bounds.x, - y: bounds.y, - width: bounds.width, - height: bounds.height + if (useProxy) { + mainWindow.webContents.session.setProxy({ + proxyRules: proxyUrl }) } - if (maximized) { - mainWindow.maximize() - } - }) - // eslint-disable-next-line - setMenu() - - // load root file/url - if (isDev) { - mainWindow.loadURL('http://localhost:9080') - } else { - /* eslint-disable-next-line */ - mainWindow.loadFile(`${__dirname}/index.html`) - - global.__static = path - .join(__dirname, '/static') - .replace(/\\/g, '\\\\') - } - - // Show when loaded - mainWindow.on('ready-to-show', () => { - mainWindow.show() - mainWindow.focus() - }) - - mainWindow.on('closed', () => { - console.log('closed') - }) - - ipcMain.on('setBounds', (_e, data) => { - const value = { - ...mainWindow.getNormalBounds(), - maximized: mainWindow.isMaximized() - } + // Set CONSENT cookie on reasonable domains + [ + 'http://www.youtube.com', + 'https://www.youtube.com', + 'http://youtube.com', + 'https://youtube.com' + ].forEach(url => { + mainWindow.webContents.session.cookies.set({ + url: url, + name: 'CONSENT', + value: 'YES+' + }) + }) settingsDb.findOne({ _id: 'bounds' }, function (err, doc) { - if (err) { + if (doc === null || err) { return } - if (doc !== null) { - settingsDb.update({ - _id: 'bounds' - }, { - $set: { - value - } - }, {}) - } else { - settingsDb.insert({ - _id: 'bounds', - value + + if (typeof doc !== 'object' || typeof doc.value !== 'object') { + return + } + + const { maximized, ...bounds } = doc.value + const allDisplaysSummaryWidth = screen + .getAllDisplays() + .reduce((accumulator, { size: { width } }) => accumulator + width, 0) + + if (allDisplaysSummaryWidth >= bounds.x) { + mainWindow.setBounds({ + x: bounds.x, + y: bounds.y, + width: bounds.width, + height: bounds.height }) } + if (maximized) { + mainWindow.maximize() + } }) - }) - ipcMain.on('appReady', () => { - if (startupUrl) { - mainWindow.webContents.send('openUrl', startupUrl) + // eslint-disable-next-line + setMenu() + + // load root file/url + if (isDev) { + mainWindow.loadURL('http://localhost:9080') + } else { + /* eslint-disable-next-line */ + mainWindow.loadFile(`${__dirname}/index.html`) + + global.__static = path + .join(__dirname, '/static') + .replace(/\\/g, '\\\\') } - }) - ipcMain.on('disableSmoothScrolling', () => { - app.commandLine.appendSwitch('disable-smooth-scrolling') - mainWindow.close() - createWindow() - }) - - ipcMain.on('enableSmoothScrolling', () => { - app.commandLine.appendSwitch('enable-smooth-scrolling') - mainWindow.close() - createWindow() - }) - - ipcMain.on('enableProxy', (event, url) => { - console.log(url) - mainWindow.webContents.session.setProxy({ - proxyRules: url + // Show when loaded + mainWindow.on('ready-to-show', () => { + mainWindow.show() + mainWindow.focus() }) - }) - ipcMain.on('disableProxy', () => { - mainWindow.webContents.session.setProxy({}) - }) -} + mainWindow.on('closed', () => { + console.log('closed') + }) -app.on('window-all-closed', () => { - if (process.platform !== 'darwin') { - app.quit() + ipcMain.on('setBounds', (_e, data) => { + const value = { + ...mainWindow.getNormalBounds(), + maximized: mainWindow.isMaximized() + } + + settingsDb.findOne({ + _id: 'bounds' + }, function (err, doc) { + if (err) { + return + } + if (doc !== null) { + settingsDb.update({ + _id: 'bounds' + }, { + $set: { + value + } + }, {}) + } else { + settingsDb.insert({ + _id: 'bounds', + value + }) + } + }) + }) + + ipcMain.on('appReady', () => { + if (startupUrl) { + mainWindow.webContents.send('openUrl', startupUrl) + } + }) + + ipcMain.on('disableSmoothScrolling', () => { + app.commandLine.appendSwitch('disable-smooth-scrolling') + mainWindow.close() + createWindow() + }) + + ipcMain.on('enableSmoothScrolling', () => { + app.commandLine.appendSwitch('enable-smooth-scrolling') + mainWindow.close() + createWindow() + }) + + ipcMain.on('enableProxy', (event, url) => { + console.log(url) + mainWindow.webContents.session.setProxy({ + proxyRules: url + }) + }) + + ipcMain.on('disableProxy', () => { + mainWindow.webContents.session.setProxy({}) + }) } - mainWindow.webContents.session.clearCache() - mainWindow.webContents.session.clearStorageData({ - storages: [ - 'appcache', - 'cookies', - 'filesystem', - 'indexdb', - 'shadercache', - 'websql', - 'serviceworkers', - 'cachestorage' - ] - }) -}) - -app.on('activate', () => { - if (mainWindow === null) { - createWindow() - } -}) - -/* - * Callback when processing a freetube:// link (macOS) - */ -app.on('open-url', (event, url) => { - event.preventDefault() - - if (mainWindow && mainWindow.webContents) { - mainWindow.webContents.send('openUrl', baseUrl(url)) - } else { - startupUrl = baseUrl(url) - } -}) - -/* - * Check if an argument was passed and send it over to the GUI (Linux / Windows). - * Remove freetube:// protocol if present - */ -const url = getLinkUrl(process.argv) -if (url) { - startupUrl = url -} - -function baseUrl(arg) { - return arg.replace('freetube://', '') -} - -function getLinkUrl(argv) { - if (argv.length > 1) { - return baseUrl(argv[argv.length - 1]) - } else { - return null - } -} - -/** - * Auto Updater - * - * Uncomment the following code below and install `electron-updater` to - * support auto updating. Code Signing with a valid certificate is required. - * https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-electron-builder.html#auto-updating - */ - -/* -import { autoUpdater } from 'electron-updater' -autoUpdater.on('update-downloaded', () => { - autoUpdater.quitAndInstall() -}) - -app.on('ready', () => { - if (process.env.NODE_ENV === 'production') autoUpdater.checkForUpdates() -}) - */ - -/* eslint-disable-next-line */ -const sendMenuEvent = async data => { - mainWindow.webContents.send('change-view', data) -} - -const template = [{ - label: 'File', - submenu: [ - { - role: 'quit' + app.on('window-all-closed', () => { + if (process.platform !== 'darwin') { + app.quit() } - ] -}, -{ - label: 'Edit', - submenu: [{ - role: 'cut' - }, - { - role: 'copy', - accelerator: 'CmdOrCtrl+C', - selector: 'copy:' - }, - { - role: 'paste', - accelerator: 'CmdOrCtrl+V', - selector: 'paste:' - }, - { - role: 'pasteandmatchstyle' - }, - { - role: 'delete' - }, - { - role: 'selectall' - } - ] -}, -{ - label: 'View', - submenu: [{ - role: 'reload' - }, - { - role: 'forcereload', - accelerator: 'CmdOrCtrl+Shift+R' - }, - { - role: 'toggledevtools' - }, - { - type: 'separator' - }, - { - role: 'resetzoom' - }, - { - role: 'zoomin' - }, - { - role: 'zoomout' - }, - { - type: 'separator' - }, - { - role: 'togglefullscreen' - } - ] -}, -{ - role: 'window', - submenu: [{ - role: 'minimize' - }, - { - role: 'close' - } - ] -} -] -function setMenu () { - if (process.platform === 'darwin') { - template.unshift({ - label: app.getName(), - submenu: [ - { role: 'about' }, - { type: 'separator' }, - { role: 'services' }, - { type: 'separator' }, - { role: 'hide' }, - { role: 'hideothers' }, - { role: 'unhide' }, - { type: 'separator' }, - { role: 'quit' } + mainWindow.webContents.session.clearCache() + mainWindow.webContents.session.clearStorageData({ + storages: [ + 'appcache', + 'cookies', + 'filesystem', + 'indexdb', + 'shadercache', + 'websql', + 'serviceworkers', + 'cachestorage' ] }) + }) - template.push({ - role: 'window' - }) + app.on('activate', () => { + if (mainWindow === null) { + createWindow() + } + }) - template.push({ - role: 'help' - }) + /* + * Callback when processing a freetube:// link (macOS) + */ + app.on('open-url', (event, url) => { + event.preventDefault() - template.push({ role: 'services' }) + if (mainWindow && mainWindow.webContents) { + mainWindow.webContents.send('openUrl', baseUrl(url)) + } else { + startupUrl = baseUrl(url) + } + }) + + /* + * Check if an argument was passed and send it over to the GUI (Linux / Windows). + * Remove freetube:// protocol if present + */ + const url = getLinkUrl(process.argv) + if (url) { + startupUrl = url } - const menu = Menu.buildFromTemplate(template) - Menu.setApplicationMenu(menu) + function baseUrl(arg) { + return arg.replace('freetube://', '') + } + + function getLinkUrl(argv) { + if (argv.length > 1) { + return baseUrl(argv[argv.length - 1]) + } else { + return null + } + } + + /** + * Auto Updater + * + * Uncomment the following code below and install `electron-updater` to + * support auto updating. Code Signing with a valid certificate is required. + * https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-electron-builder.html#auto-updating + */ + + /* + import { autoUpdater } from 'electron-updater' + autoUpdater.on('update-downloaded', () => { + autoUpdater.quitAndInstall() + }) + + app.on('ready', () => { + if (process.env.NODE_ENV === 'production') autoUpdater.checkForUpdates() + }) + */ + + /* eslint-disable-next-line */ + const sendMenuEvent = async data => { + mainWindow.webContents.send('change-view', data) + } + + const template = [{ + label: 'File', + submenu: [ + { + role: 'quit' + } + ] + }, + { + label: 'Edit', + submenu: [{ + role: 'cut' + }, + { + role: 'copy', + accelerator: 'CmdOrCtrl+C', + selector: 'copy:' + }, + { + role: 'paste', + accelerator: 'CmdOrCtrl+V', + selector: 'paste:' + }, + { + role: 'pasteandmatchstyle' + }, + { + role: 'delete' + }, + { + role: 'selectall' + } + ] + }, + { + label: 'View', + submenu: [{ + role: 'reload' + }, + { + role: 'forcereload', + accelerator: 'CmdOrCtrl+Shift+R' + }, + { + role: 'toggledevtools' + }, + { + type: 'separator' + }, + { + role: 'resetzoom' + }, + { + role: 'zoomin' + }, + { + role: 'zoomout' + }, + { + type: 'separator' + }, + { + role: 'togglefullscreen' + } + ] + }, + { + role: 'window', + submenu: [{ + role: 'minimize' + }, + { + role: 'close' + } + ] + } + ] + + function setMenu () { + if (process.platform === 'darwin') { + template.unshift({ + label: app.getName(), + submenu: [ + { role: 'about' }, + { type: 'separator' }, + { role: 'services' }, + { type: 'separator' }, + { role: 'hide' }, + { role: 'hideothers' }, + { role: 'unhide' }, + { type: 'separator' }, + { role: 'quit' } + ] + }) + + template.push({ + role: 'window' + }) + + template.push({ + role: 'help' + }) + + template.push({ role: 'services' }) + } + + const menu = Menu.buildFromTemplate(template) + Menu.setApplicationMenu(menu) + } } diff --git a/src/renderer/components/privacy-settings/privacy-settings.js b/src/renderer/components/privacy-settings/privacy-settings.js index 53b4421f..3e9f42b6 100644 --- a/src/renderer/components/privacy-settings/privacy-settings.js +++ b/src/renderer/components/privacy-settings/privacy-settings.js @@ -33,6 +33,10 @@ export default Vue.extend({ saveWatchedProgress: function () { return this.$store.getters.getSaveWatchedProgress }, + removeVideoMetaFiles: function () { + return this.$store.getters.getRemoveVideoMetaFiles + }, + profileList: function () { return this.$store.getters.getProfileList }, @@ -66,6 +70,13 @@ export default Vue.extend({ this.updateRememberHistory(value) }, + handleVideoMetaFiles: function (value) { + if (!value) { + this.updateRemoveVideoMetaFiles(false) + } + this.updateRemoveVideoMetaFiles(value) + }, + handleRemoveHistory: function (option) { this.showRemoveHistoryPrompt = false @@ -102,6 +113,7 @@ export default Vue.extend({ ...mapActions([ 'updateRememberHistory', + 'updateRemoveVideoMetaFiles', 'removeAllHistory', 'updateSaveWatchedProgress', 'clearSessionSearchHistory', diff --git a/src/renderer/components/privacy-settings/privacy-settings.vue b/src/renderer/components/privacy-settings/privacy-settings.vue index e0191eda..d39b7214 100644 --- a/src/renderer/components/privacy-settings/privacy-settings.vue +++ b/src/renderer/components/privacy-settings/privacy-settings.vue @@ -23,6 +23,15 @@ @change="updateSaveWatchedProgress" /> +
+ +

diff --git a/src/renderer/components/watch-video-comments/watch-video-comments.vue b/src/renderer/components/watch-video-comments/watch-video-comments.vue index 20b96740..a993a373 100644 --- a/src/renderer/components/watch-video-comments/watch-video-comments.vue +++ b/src/renderer/components/watch-video-comments/watch-video-comments.vue @@ -47,8 +47,9 @@ class="commentThumbnail" @click="goToChannel(comment.authorLink)" > -

{{ comment.author }} diff --git a/src/renderer/main.js b/src/renderer/main.js index 9513d603..4404b54c 100644 --- a/src/renderer/main.js +++ b/src/renderer/main.js @@ -27,7 +27,7 @@ Vue.component('FontAwesomeIcon', FontAwesomeIcon) Vue.use(VueI18n) // List of locales approved for use -const activeLocales = ['en-US', 'en_GB', 'ar', 'bg', 'cs', 'da', 'de-DE', 'el', 'es', 'es-MX', 'fi', 'fr-FR', 'gl', 'he', 'hu', 'hr', 'id', 'it', 'ja', 'nb_NO', 'nl', 'pl', 'pt', 'pt-BR', 'pt-PT', 'ru', 'sk', 'sl', 'sv', 'tr', 'uk', 'vi', 'zh-CN', 'zh-TW'] +const activeLocales = ['en-US', 'en_GB', 'ar', 'bg', 'cs', 'da', 'de-DE', 'el', 'es', 'es-MX', 'fi', 'fr-FR', 'gl', 'he', 'hu', 'hr', 'id', 'is', 'it', 'ja', 'nb_NO', 'nl', 'nn', 'pl', 'pt', 'pt-BR', 'pt-PT', 'ru', 'sk', 'sl', 'sv', 'tr', 'uk', 'vi', 'zh-CN', 'zh-TW'] const messages = {} /* eslint-disable-next-line */ const fileLocation = isDev ? 'static/locales/' : `${__dirname}/static/locales/` diff --git a/src/renderer/store/modules/settings.js b/src/renderer/store/modules/settings.js index 1c427b05..bd12ed7c 100644 --- a/src/renderer/store/modules/settings.js +++ b/src/renderer/store/modules/settings.js @@ -47,6 +47,7 @@ const state = { enableSearchSuggestions: true, rememberHistory: true, saveWatchedProgress: true, + removeVideoMetaFiles: true, autoplayVideos: true, autoplayPlaylists: true, playNextVideo: false, @@ -141,6 +142,10 @@ const getters = { return state.saveWatchedProgress }, + getRemoveVideoMetaFiles: () => { + return state.removeVideoMetaFiles + }, + getAutoplayVideos: () => { return state.autoplayVideos }, @@ -330,6 +335,9 @@ const actions = { case 'saveWatchedProgress': commit('setSaveWatchedProgress', result.value) break + case 'removeVideoMetaFiles': + commit('setRemoveVideoMetaFiles', result.value) + break case 'autoplayVideos': commit('setAutoplayVideos', result.value) break @@ -555,6 +563,14 @@ const actions = { }) }, + updateRemoveVideoMetaFiles ({ commit }, removeVideoMetaFiles) { + settingsDb.update({ _id: 'removeVideoMetaFiles' }, { _id: 'removeVideoMetaFiles', value: removeVideoMetaFiles }, { upsert: true }, (err, numReplaced) => { + if (!err) { + commit('setRemoveVideoMetaFiles', removeVideoMetaFiles) + } + }) + }, + updateAutoplayVideos ({ commit }, autoplayVideos) { settingsDb.update({ _id: 'autoplayVideos' }, { _id: 'autoplayVideos', value: autoplayVideos }, { upsert: true }, (err, numReplaced) => { if (!err) { @@ -822,6 +838,11 @@ const mutations = { setSaveWatchedProgress (state, saveWatchedProgress) { state.saveWatchedProgress = saveWatchedProgress }, + + setRemoveVideoMetaFiles (state, removeVideoMetaFiles) { + state.removeVideoMetaFiles = removeVideoMetaFiles + }, + setAutoplayVideos (state, autoplayVideos) { state.autoplayVideos = autoplayVideos }, diff --git a/src/renderer/views/Watch/Watch.js b/src/renderer/views/Watch/Watch.js index 00745b4d..1e5c4990 100644 --- a/src/renderer/views/Watch/Watch.js +++ b/src/renderer/views/Watch/Watch.js @@ -91,6 +91,9 @@ export default Vue.extend({ rememberHistory: function () { return this.$store.getters.getRememberHistory }, + removeVideoMetaFiles: function () { + return this.$store.getters.getRemoveVideoMetaFiles + }, saveWatchedProgress: function () { return this.$store.getters.getSaveWatchedProgress }, @@ -899,8 +902,6 @@ export default Vue.extend({ videoId: this.videoId, watchProgress: currentTime } - - console.log('update watch progress') this.updateWatchProgress(payload) } } @@ -928,6 +929,31 @@ export default Vue.extend({ }, 200) } } + + if (this.removeVideoMetaFiles) { + const userData = remote.app.getPath('userData') + if (this.isDev) { + const dashFileLocation = `dashFiles/${this.videoId}.xml` + const vttFileLocation = `storyboards/${this.videoId}.vtt` + // only delete the file it actually exists + if (fs.existsSync('dashFiles/') && fs.existsSync(dashFileLocation)) { + fs.rmSync(dashFileLocation) + } + if (fs.existsSync('storyboards/') && fs.existsSync(vttFileLocation)) { + fs.rmSync(vttFileLocation) + } + } else { + const dashFileLocation = `${userData}/dashFiles/${this.videoId}.xml` + const vttFileLocation = `${userData}/storyboards/${this.videoId}.vtt` + + if (fs.existsSync(`${userData}/dashFiles/`) && fs.existsSync(dashFileLocation)) { + fs.rmSync(dashFileLocation) + } + if (fs.existsSync(`${userData}/storyboards/`) && fs.existsSync(vttFileLocation)) { + fs.rmSync(vttFileLocation) + } + } + } }, handleVideoError: function (error) { diff --git a/static/locales/ar.yaml b/static/locales/ar.yaml index ae869862..fc27a3b4 100644 --- a/static/locales/ar.yaml +++ b/static/locales/ar.yaml @@ -18,7 +18,7 @@ Delete: 'حذف' Select all: 'تحديد الكل' Reload: 'إعادة تحميل' Force Reload: 'فرض إعادة التحميل' -Toggle Developer Tools: 'تفعيل أدوات المطوّر' +Toggle Developer Tools: 'فتح أدوات المطوّر' Actual size: 'الحجم الأصلي' Zoom in: 'تكبير' Zoom out: 'تصغير' @@ -64,6 +64,7 @@ Search Filters: Fetching results. Please wait: 'جاري إحضار النتائج. الرجاء الانتظار' Fetch more results: 'إحضار المزيد من النتائج' # Sidebar + There are no more results for this search: لم يتبقى المزيد من النتائج لهذا البحث Subscriptions: # On Subscriptions Page Subscriptions: 'الاشتراكات' @@ -80,6 +81,11 @@ Most Popular: 'الأكثر شعبية' Playlists: 'قوائم التشغيل' User Playlists: Your Playlists: 'قوائم التشغيل الخاصة بك' + Your saved videos are empty. Click on the save button on the corner of a video to have it listed here: ليس + لديك أي فيديو محتفظ عليه. إضغط على زر "إحفظ" في زاوية الفيديو لكي يحفظ هنا. + Playlist Message: هذه الصفحة لا تظهر قائمات التشغيل بشكل كامل, وإنما تظهر فيديوات + إحتفضت عليها أو فضّلتها. عندما يكمل العمل بالكامل على هذه الصفحة, سترى كل فيديواتك + هنا تنتقل إلى قائمة تشغيل تسمى "المفضلة". History: # On History Page History: 'السجلّ' @@ -115,6 +121,7 @@ Settings: #! List countries Check for Latest Blog Posts: تحقق من أحدث منشورات المدونة Check for Updates: تحقّق من وجود تحديثات + View all Invidious instance information: عرض جميع نماذج Invidious Theme Settings: Theme Settings: 'إعدادات السِمة' Match Top Bar with Main Color: 'طابق الشريط العلوي مع اللون الأساسي' @@ -175,6 +182,7 @@ Settings: 1440p: '1440p' 4k: '4k' 8k: '‍8k' + Playlist Next Video Interval: الفاصل الزمني لتشغيل الفيديو التالي في قائمة التشغيل Privacy Settings: Privacy Settings: 'إعدادات الخصوصية' Remember History: 'تذّكر سجلّ المشاهدة' @@ -191,6 +199,7 @@ Settings: أنت متأكد أنك تريد إزالة جميع الاشتراكات والملفات الشخصية؟ لا يمكن التراجع عن هذا. Remove All Subscriptions / Profiles: إزالة جميع الاشتراكات \ الملفات الشخصية + Automatically Remove Video Meta Files: إزالة ملفات تعريف الفيديو تلقائيًا Subscription Settings: Subscription Settings: 'إعدادات الاشتراك' Hide Videos on Watch: 'أخفِ الفيديوهات عند مشاهدتها' @@ -265,7 +274,7 @@ Settings: Data Settings: إعدادات البيانات One or more subscriptions were unable to be imported: تعذر استيراد واحد أو أكثر من الاشتراكات - Check for Legacy Subscriptions: تحقق من وجود اشتراك قديم + Check for Legacy Subscriptions: تحقق من وجود اشتراكات بالصيغة القديمة Manage Subscriptions: إدارة الإشتراكات Distraction Free Settings: Hide Live Chat: اخفي الدردشة المباشرة @@ -273,10 +282,12 @@ Settings: Hide Trending Videos: اخفي الفيديوهات الرائجة Hide Recommended Videos: اخفي الفيديوهات الموصّى بها Hide Comment Likes: اخفي اعجابات التعليقات - Hide Channel Subscribers: اخفي اشتراكات القنوات - Hide Video Views: اخفي عدد مشاهدات الفيديوهات + Hide Channel Subscribers: اخف عدد اشتراكات القناة + Hide Video Views: اخف عدد مشاهدات الفيديو Hide Video Likes And Dislikes: إخفاء الإعجاب وعدم الإعجاب للفيديو Distraction Free Settings: إعدادات عدم الإزعاج + Hide Active Subscriptions: اخفي الإشتراكات الناشطة + Hide Playlists: إخفاء قوائم التشغيل The app needs to restart for changes to take effect. Restart and apply change?: البرنامج يحتاج لإعادة التشغيل كي يسري مفعول التغييرات. هل تريد إعادة التشغيل و تطبيق التغييرات؟ Proxy Settings: @@ -291,6 +302,10 @@ Settings: Proxy Protocol: بروتوكول البروكسي Enable Tor / Proxy: تفعيل تور / البروكسي Proxy Settings: خيارات البروكسي + Error getting network information. Is your proxy configured properly?: هنالك خطأ + في جلب معلومات الشبكة. هل ضبطت إعدادات وكيلك بصورة صحيحة؟ + Clicking on Test Proxy will send a request to: النقر على اختبار البروكسي سيؤدي + إلى إرسال طلب إلى About: #On About page About: 'حول' @@ -335,6 +350,17 @@ About: View License: اعرض الرخصة Source code: الشفرة المصدرية Beta: تجريبي + these people and projects: هؤلاء الناس والمشاريع + FreeTube is made possible by: Freetube أصبح ممكنا بواسطة + Credits: الاعتمادات + room rules: قواعد الغرفة + Please read the: يرجى قراءة + Please check for duplicates before posting: يرجى التحقق من التكرارات قبل النشر + GitHub issues: مشاكل GitHub + FreeTube Wiki: ويكي Freetube + GitHub releases: إصدارات GitHub + Downloads / Changelog: التحميلات\التغييرات + Licensed under the AGPLv3: مرخّص تحت رخصة أفيرو جيبيإل النسخة الثالثة Profile: All Channels: 'جميع القنوات' Profile Manager: 'مدير الملف الشخصي' @@ -376,6 +402,7 @@ Profile: $ selected: $ تم اختياره Other Channels: قنوات أُخرى Subscription List: قائمة الاشتراكات + Profile Filter: مرشح الملف الشخصي Channel: Subscriber: 'مُشترِك' Subscribers: 'مُشترِكين' @@ -465,7 +492,7 @@ Video: Year: 'سنة' Years: 'سنوات' Ago: 'منذ' - Upcoming: 'العرض الأول في' + Upcoming: 'يبدأ العرض' Published on: 'نُشر في' # $ is replaced with the number and % with the unit (days, hours, minutes...) Publicationtemplate: 'قبل $ %' @@ -480,12 +507,12 @@ Video: الصفحة للتحقق مرة أخرى Audio: Best: الأفضل - High: عالٍ + High: عال Medium: متوسط Low: منخفض - audio only: صوت فقط - video only: فيديو فقط - Download Video: نزّل الفيديو + audio only: الصوت فقط + video only: الفيديو فقط + Download Video: تحميل الفيديو Started streaming on: بدأ البث على Streamed on: تبث على Copy Invidious Channel Link: انسخ رابط قناة انفيديوس @@ -494,6 +521,7 @@ Video: Open Channel in YouTube: افتح القناة على يوتيوب Video has been saved: تم حفظ الفيديو Save Video: احفظ الفيديو + Video has been removed from your saved list: تمت إزالة الفيديو من قائمتك المحفوظة Videos: #& Sort By Sort By: @@ -591,9 +619,9 @@ Tooltips: General Settings: Thumbnail Preference: كلّ الصّور المصغّرة في FreeTube سيتمّ استبدالها بإطار من الفيديو بدل من الصّورة المصغّرة الافتراضيّة - Preferred API Backend: اختر الواجهة الخلفية التي يستخدمها FreeTube لجلب البيانات - . الAPI المحلي هو مستخرج محلي . الAPI التابع لInvidious يتطلب التواصل مع خادم - شبكة Invidious . + Preferred API Backend: اختر الواجهة الخلفية التي يستخدمها FreeTube لجلب البيانات. + الواجهة البرمجية المحلية للتطبيق هي مستخرج محلي. الواجهة البرمجية للتطبيق التابعة + لInvidious (بديل لموقع يوتيوب) يتطلب التواصل مع خادم شبكة Invidious Invidious Instance: واجهة Invidious البرمجية المستخدمة من قبل FreeTube. امسح الواجهة البرمجية الحالية للاختيار من قائمة الواجهات Fallback to Non-Preferred Backend on Failure: عند تواجد مشكلة مع الواجهة البرمجية @@ -608,3 +636,18 @@ Tooltips: باستخدام التنسيقات القديمة التي تم إرجاعها من قبلها بدلاً من أن تستخدم الصيغ التي تم إرجاعها من قبل Invidious . يساعد هذا الخيار عندما لا تعمل الفيديوهات التي تم إرجاعها من قبل Invidious بسبب قيود البلد + Default Video Format: حدّد التنسيقات المستخدمة عند تشغيل الفيديو. تنسيق داش (التدفق + الميكانيكي المتكيّف عبر بروتوكول نقل النص التشعبي) يمكنها أن تُشغِّل جودات أعلى. + التنسيقات القديمة محدودة بجودة 720p كحدّ أقصى لكنها تستخدم عرضًا أقل للنطاق. + التنسيقات الصوتية هي للتدفق الصوتي فقط + Privacy Settings: + Remove Video Meta Files: عندما يمكن، يحذف Freetube تلقائيًا ملفات التعريف التي + تم إنشاؤها أثناء تشغيل الفيديو ، عندما تكون صفحة المشاهدة مغلقة. + Subscription Settings: + Fetch Feeds from RSS: عند تفعيلها، سوف يستخدم فريتيوب طريقة RSS بدلًا من طريقته + المعتادة لجلب صفحة اشتراكاتك. طريقة RSS أسرع وتتخطى حجب الآي بي IP، لكنها لا + تقدّم معلومات معينة مثل مدّة الفيديو أو حالة البث المباشر. +This video is unavailable because of missing formats. This can happen due to country unavailability.: هذا + الفيديو غير متوفر لفقدان بعض التنسيقات. من الممكن لهذا أن يحدث بسبب الحظر في دولة + معيّنة. +More: المزيد diff --git a/static/locales/bg.yaml b/static/locales/bg.yaml index 92213a04..c67c6682 100644 --- a/static/locales/bg.yaml +++ b/static/locales/bg.yaml @@ -210,6 +210,7 @@ Settings: Are you sure you want to remove all subscriptions and profiles? This cannot be undone.: 'Сигурни ли сте, че искате да премахнете всички абонаменти и профили? Това не може да бъде възстановено.' + Automatically Remove Video Meta Files: Автоматично премахване на видео метафайловете Subscription Settings: Subscription Settings: 'Настройки на абонаменти' Hide Videos on Watch: 'Скриване на видеата при гледане' @@ -628,10 +629,10 @@ Yes: 'Да' No: 'Не' Tooltips: Subscription Settings: - Fetch Feeds from RSS: Когато е активирано, FreeTube ще използва RSS вместо метода - по подразбиране за получаване на абонаментите. RSS е по-бърз метод и преодолява - блокиранията на IP адреса, но не получава някои съпътстващи данни, като продължителност - на видеото или дали е на живо + Fetch Feeds from RSS: FreeTube ще използва RSS вместо метода по подразбиране за + получаване на абонаментите. RSS е по-бърз метод и преодолява блокиранията на + IP адреса, но не получава някои съпътстващи данни, като продължителност на видеото + или дали е на живо Player Settings: Default Video Format: Настройка на използваните формати. Dash форматите могат да показват видеа с по-високо качество. Старите формати са ограничени до макс. @@ -657,6 +658,10 @@ Tooltips: Preferred API Backend: Избиране на начина, по който FreeTube получава данните. Локалният интерфейс има вградено извличане. Invidious интерфейсът изисква Invidious сървър, към който да се свърже. + Privacy Settings: + Remove Video Meta Files: Когато страницата за гледане бъде затворена, FreeTube + автоматично ще изтрива метафайловете, създадени по време на възпроизвеждане + на видеото. More: Още Playing Next Video Interval: Пускане на следващото видео веднага. Щракнете за отказ. | Пускане на следващото видео след {nextVideoInterval} секунда. Щракнете за отказ. diff --git a/static/locales/cs.yaml b/static/locales/cs.yaml index 1d7cc26c..b166ade6 100644 --- a/static/locales/cs.yaml +++ b/static/locales/cs.yaml @@ -208,6 +208,7 @@ Settings: Remove All Subscriptions / Profiles: 'Odstranit všechna odebírání / profily' Are you sure you want to remove all subscriptions and profiles? This cannot be undone.: 'Chcete opravdu odstranit všechna odebírání a profily? Toto nelze vrátit zpět.' + Automatically Remove Video Meta Files: Automaticky odstranit meta soubory videa Subscription Settings: Subscription Settings: 'Nastavení odebírání' Hide Videos on Watch: 'Skrýt videa při přehrávání' @@ -630,6 +631,9 @@ Tooltips: IP, ale neposkytuje určité informace, jako je délka videa a podobně' # Toast Messages + Privacy Settings: + Remove Video Meta Files: Pokud je povoleno, FreeTube automaticky odstraní meta + soubory vytvořené během přehrávání videa, když se stránka sledování zavře. Local API Error (Click to copy): 'Chyba lokálního API (kliknutím zkopírujete)' Invidious API Error (Click to copy): 'Chyba Invidious API (kliknutím zkopírujete)' Falling back to Invidious API: 'Přepínám na Invidious API' diff --git a/static/locales/de-DE.yaml b/static/locales/de-DE.yaml index eeed1408..46766b15 100644 --- a/static/locales/de-DE.yaml +++ b/static/locales/de-DE.yaml @@ -1,7 +1,7 @@ FreeTube: FreeTube # Currently on Subscriptions, Playlists, and History 'This part of the app is not ready yet. Come back later when progress has been made.': >- - Dieser Teil des Programms ist noch nicht fertig. Bitte komme zu einem späteren Zeitpunkt + Dieser Teil des Programms ist noch nicht fertig. Bitte komm zu einem späteren Zeitpunkt wieder. # Webkit Menu Bar @@ -70,13 +70,13 @@ Subscriptions: Subscriptions: Abonnements Latest Subscriptions: Neueste Abonnements 'Your Subscription list is currently empty. Start adding subscriptions to see them here.': Deine - Abonnementliste ist aktuell leer. Beginne Abonnements hinzuzufügen um sie hier + Abonnementliste ist aktuell leer. Beginne Abonnements hinzuzufügen, um sie hier zu sehen. 'Getting Subscriptions. Please wait.': Rufe Abonnements ab. Bitte warten. Refresh Subscriptions: Abonnements aktualisieren Getting Subscriptions. Please wait.: Lade Abonnements. Bitte warten. This profile has a large number of subscriptions. Forcing RSS to avoid rate limiting: Dieses - Profil hat eine große Anzahl von Abonnenten. RSS zur Vermeidung von Tarifbeschränkungen + Profil hat eine große Anzahl von Abonnements. RSS zur Vermeidung von Geschwindigkeitsbeschränkungen erzwingen Load More Videos: Lade mehr Videos Trending: Trends @@ -85,12 +85,12 @@ Playlists: Wiedergabelisten User Playlists: Your Playlists: Deine Wiedergabelisten Your saved videos are empty. Click on the save button on the corner of a video to have it listed here: Deine - gespeicherten Videos sind leer. Klicken Sie auf die Schaltfläche „Speichern“ in - der Ecke eines Videos, damit es hier aufgelistet wird + gespeicherten Videos sind leer. Klicke auf die Schaltfläche „Speichern“ in der + Ecke eines Videos, damit es hier aufgelistet wird Playlist Message: Diese Seite spiegelt nicht die vollständig funktionierenden Wiedergabelisten - wider. Sie listet nur Videos auf, die Sie gespeichert oder favorisiert haben. - Wenn die Arbeiten abgeschlossen sind, werden alle Videos, die sich derzeit hier - befinden, in eine Wiedergabeliste „Favoriten“ migriert. + wider. Sie listet nur Videos auf, die Du gespeichert oder favorisiert hast. Wenn + die Arbeiten abgeschlossen sind, werden alle Videos, die sich derzeit hier befinden, + in eine Wiedergabeliste „Favoriten“ migriert. History: # On History Page History: Verlauf @@ -110,7 +110,7 @@ Settings: Preferred API Backend: Preferred API Backend: Bevorzugtes API-System Local API: Lokale API - Invidious API: Invidious API + Invidious API: Invidious-API Video View Type: Video View Type: Videoansichtstyp Grid: Gitter @@ -130,7 +130,7 @@ Settings: View all Invidious instance information: Alle Informationen zur Invidious-Instanz anzeigen Theme Settings: - Theme Settings: Thema Einstellungen + Theme Settings: Thema-Einstellungen Match Top Bar with Main Color: Obere Leiste an Hauptfarbe anpassen Base Theme: Base Theme: Grundlegendes Thema @@ -246,6 +246,7 @@ Settings: du sicher, dass du alle Abonnements und Profile löschen möchtest? Diese Aktion kann nicht rückgängig gemacht werden. Remove All Subscriptions / Profiles: Alle Abonnements / Profile löschen + Automatically Remove Video Meta Files: Meta-Dateien von Videos automatisch löschen Data Settings: How do I import my subscriptions?: Wie importiere ich meine Abonnements? Unknown data key: Unbekannter Datenschlüssel @@ -669,8 +670,8 @@ Tooltips: API nicht verfügbar sein sollte, automatisch die nicht bevorzugte Alternative zu nutzen. Preferred API Backend: Wähle das Backend, welches FreeTube zum Laden der Daten - nutzen soll. Die lokale API ist ein integrierter Extrahierer. Die Invidious - API dagegen verwendet einen externen Server. + nutzen soll. Die lokale API ist ein integrierter Extrahierer. Die Invidious-API + dagegen verwendet einen externen Server. Region for Trending: Die Trendregion erlaubt es dir auszuwählen, aus welchem Land die Trends angezeigt werden sollen. Nicht alle Optionen werden auch von YouTube unterstützt @@ -685,11 +686,14 @@ Tooltips: dafür aber auch weniger Bandbreite. Audioformate umfassen reine Audiostreams. Proxy Videos Through Invidious: Zu Invidious verbinden, um Videos abzurufen, anstatt eine direkten Verbindung zu YouTube aufzubauen. Überschreibt die API-Präferenz. - Force Local Backend for Legacy Formats: Dies funktioniert nur wenn du die Invidious - API als Standard ausgewählt hast. Die lokale API wird bei der Verwendung von - Legacy Formaten diese verwenden, anstatt auf Invidious zurückzugreifen. Dies - hilft dann, wenn Videos von Invidious nicht abspielbar sind. Zum Beispiel aufgrund - von Landesbeschränkungen. + Force Local Backend for Legacy Formats: Dies funktioniert nur, wenn du die Invidious-API + als Standard ausgewählt hast. Die lokale API wird bei der Verwendung von Legacy + -Formaten diese verwenden, anstatt auf Invidious zurückzugreifen. Dies hilft + dann, wenn Videos von Invidious nicht abspielbar sind aufgrund von Landesbeschränkungen. + Privacy Settings: + Remove Video Meta Files: Bei Aktivierung löscht FreeTube alle Meta-Dateien die + während der Videowiedergabe erzeugt werden, sobald die Videoseite verlassen + wird. Playing Next Video Interval: Nächstes Video wird sofort abgespielt. Zum Abbrechen klicken. | Nächstes Video wird in {nextVideoInterval} Sekunden abgespielt. Zum Abbrechen klicken. | Nächstes Video wird in {nextVideoInterval} Sekunden abgespielt. Zum Abbrechen diff --git a/static/locales/en-US.yaml b/static/locales/en-US.yaml index 967f457d..8d893e03 100644 --- a/static/locales/en-US.yaml +++ b/static/locales/en-US.yaml @@ -195,6 +195,7 @@ Settings: Privacy Settings: Privacy Settings Remember History: Remember History Save Watched Progress: Save Watched Progress + Automatically Remove Video Meta Files: Automatically Remove Video Meta Files Clear Search Cache: Clear Search Cache Are you sure you want to clear out your search cache?: Are you sure you want to clear out your search cache? @@ -570,7 +571,10 @@ Tooltips: Subscription Settings: Fetch Feeds from RSS: When enabled, FreeTube will use RSS instead of its default method for grabbing your subscription feed. RSS is faster and prevents IP blocking, - but doesn't provide certain information like video duration or live status. + but doesn't provide certain information like video duration or live status + Privacy Settings: + Remove Video Meta Files: When enabled, FreeTube automatically deletes meta files created during video playback, + when the watch page is closed. # Toast Messages Local API Error (Click to copy): Local API Error (Click to copy) diff --git a/static/locales/hr.yaml b/static/locales/hr.yaml index 622710eb..a8de7c80 100644 --- a/static/locales/hr.yaml +++ b/static/locales/hr.yaml @@ -201,6 +201,8 @@ Settings: Are you sure you want to remove all subscriptions and profiles? This cannot be undone.: Stvarno želiš ukloniti sve pretplate i profile? Ovo je nepovratna radnja. Remove All Subscriptions / Profiles: Ukloni sve pretplate/profile + Automatically Remove Video Meta Files: Automatski ukloni datoteke metapodataka + videa Subscription Settings: Subscription Settings: 'Postavke pretplata' Hide Videos on Watch: 'Sakrij video nakon gledanja' @@ -663,6 +665,10 @@ Tooltips: standardne metode za dohvaćanje podataka tvoje pretplate. RSS je brži i sprečava blokiranje IP adresa, ali ne pruža određene podatke kao što su trajanje videa ili stanja „uživo” + Privacy Settings: + Remove Video Meta Files: Kad je aktivirano, FreeTube automatski uklanja datoteke + metapodataka koji su stvoreni tijekom reprodukcije videa, kad se zatvori stranica + gledanja. Playing Next Video Interval: Trenutna reprodukcija sljedećeg videa. Pritisni za prekid. | Reprodukcija sljedećeg videa za {nextVideoInterval} sekunde. Pritisni za prekid. | Reprodukcija sljedećeg videa za {nextVideoInterval} sekundi. Pritisni za prekid. diff --git a/static/locales/hu.yaml b/static/locales/hu.yaml index 798ac30e..5152ba75 100644 --- a/static/locales/hu.yaml +++ b/static/locales/hu.yaml @@ -211,6 +211,7 @@ Settings: Remove All Subscriptions / Profiles: 'Összes feliratkozás és profil eltávolítása' Are you sure you want to remove all subscriptions and profiles? This cannot be undone.: 'Biztosan törli az összes feliratkozást és profilt? A művelet nem vonható vissza.' + Automatically Remove Video Meta Files: Videométafájlok önműködő eltávolítása Subscription Settings: Subscription Settings: 'Feliratkozás beállításai' Hide Videos on Watch: 'Videók elrejtése megtekintés után' @@ -664,6 +665,9 @@ Tooltips: visszaadott örökölt formátumokat fogja használni az Invidious által visszaadottak helyett. Segít, ha az Invidious által visszaküldött videókat nem lehet lejátszani az ország korlátozása miatt + Privacy Settings: + Remove Video Meta Files: Ha engedélyezve van, a FreeTube önműködőén törli a videolejátszás + során létrehozott métafájlokat, amikor a nézési oldal bezárul. Playing Next Video Interval: A következő videó lejátszása folyamatban van. Kattintson a törléshez. | A következő videó lejátszása {nextVideoInterval} másodperc múlva történik. Kattintson a törléshez. | A következő videó lejátszása {nextVideoInterval} diff --git a/static/locales/id.yaml b/static/locales/id.yaml index 04342b9a..f3bac887 100644 --- a/static/locales/id.yaml +++ b/static/locales/id.yaml @@ -207,6 +207,7 @@ Settings: Are you sure you want to remove all subscriptions and profiles? This cannot be undone.: 'Apakah Anda yakin ingin menghapus semua langganan dan profil? Tindakan ini tidak bisa diurungkan.' + Automatically Remove Video Meta Files: Secara Otomatis Hapus File Meta Video Subscription Settings: Subscription Settings: 'Pengaturan Langganan' Hide Videos on Watch: 'Sembunyikan Video saat Menonton' @@ -654,6 +655,9 @@ Tooltips: Preferred API Backend: Pilih layanan yang digunakan oleh FreeTube untuk mengambil data. API lokal adalah ekstraktor bawaan. API Invidious membutuhkan sambungan ke server Invidious. + Privacy Settings: + Remove Video Meta Files: Saat diaktifkan, FreeTube secara otomatis menghapus file + meta yang dibuat selama pemutaran video, saat halaman tonton ditutup. Playing Next Video Interval: Langsung putar video berikutnya. Klik untuk batal. | Putar video berikutnya dalam {nextVideoInterval} detik. Klik untuk batal. | Putar video berikutnya dalam {nextVideoInterval} detik. Klik untuk batal. diff --git a/static/locales/is.yaml b/static/locales/is.yaml index dc8b8371..5ce703e8 100644 --- a/static/locales/is.yaml +++ b/static/locales/is.yaml @@ -214,6 +214,7 @@ Settings: Are you sure you want to remove all subscriptions and profiles? This cannot be undone.: 'Ertu viss um að þú viljir fjarlægja allar áskriftir og notkunarsnið? Ekki er hægt að afturkalla þetta.' + Automatically Remove Video Meta Files: Sjálfvirkt fjarlægja lýsigögn úr myndskeiðaskrám Subscription Settings: Subscription Settings: 'Stillingar áskrifta' Hide Videos on Watch: 'Fela myndskeið eftir áhorf' @@ -588,6 +589,9 @@ Tooltips: á borð við tímalengd myndskeiða eða stöðu í beinni útsendingu' # Toast Messages + Privacy Settings: + Remove Video Meta Files: Þegar þetta er virkt, eyðir FreeTube sjálfkrafa lýsigagnaskrám + sem útbúnar eru við afspilun, þegar skoðunarsíðunni er lokað. Local API Error (Click to copy): 'Villa í staðværu API-kerfisviðmóti (smella til að afrita)' Invidious API Error (Click to copy): 'Villa í Invidious API-kerfisviðmóti (smella diff --git a/static/locales/nl.yaml b/static/locales/nl.yaml index 69703964..358aee42 100644 --- a/static/locales/nl.yaml +++ b/static/locales/nl.yaml @@ -44,7 +44,7 @@ Search Filters: Time: Time: 'Tijd' Any Time: 'Ooit' - Last Hour: 'Laatste uur' + Last Hour: 'Afgelopen uur' Today: 'Vandaag' This Week: 'Deze week' This Month: 'Deze maand' @@ -62,7 +62,7 @@ Search Filters: Long (> 20 minutes): 'Lang (> 20 minuten)' # On Search Page Search Results: 'Zoekresultaten' - Fetching results. Please wait: 'Resultaten verzamelen. Een momentje' + Fetching results. Please wait: 'Resultaten verzamelen. Even geduld aub' Fetch more results: 'Meer resultaten laden' # Sidebar There are no more results for this search: Er zijn geen verdere resultaten voor @@ -70,24 +70,24 @@ Search Filters: Subscriptions: # On Subscriptions Page Subscriptions: 'Abonnementen' - Latest Subscriptions: 'Nieuwste Van Abonnementen' + Latest Subscriptions: 'Nieuwste Abonnementen' 'Your Subscription list is currently empty. Start adding subscriptions to see them here.': 'U heeft nog geen Abonnementen. Voeg abonnementen toe om ze hier te zien' 'Getting Subscriptions. Please wait.': '' Refresh Subscriptions: Vernieuw abonnementen - Getting Subscriptions. Please wait.: Abonnementen verzamelen. Een momentje. + Getting Subscriptions. Please wait.: Abonnementen verzamelen. Even geduld aub. This profile has a large number of subscriptions. Forcing RSS to avoid rate limiting: Dit - profiel heeft een groot aantal abonnementen. RSS wordt geforceerd om tariefbeperkingen - te voorkomen - Load More Videos: Laad Meer Video's + profiel heeft een groot aantal abonnementen. Forceer RSS om snelheidsbeperking + te vermijden + Load More Videos: Meer Video's Laden Trending: 'Trending' Most Popular: 'Populair' Playlists: 'Afspeellijsten' User Playlists: Your Playlists: 'Uw afspeellijsten' Your saved videos are empty. Click on the save button on the corner of a video to have it listed here: Je - opgeslagen video's is leeg. Klik op de video opslaan knop in de hoek van een video - om het hier in de lijst te plaatsen + opgeslagen video's is leeg. Klik op de opslaan knop in de hoek van een video om + het hier in de lijst te plaatsen Playlist Message: Deze pagina is niet reflectief van volledig functionele afspeellijst. Er worden alleen video's weergegeven die jij hebt opgeslagen of gefavoriet. Wanneer we klaar zijn met de ontwikkeling van deze feature zullen al deze video's worden @@ -112,7 +112,7 @@ Settings: Local API: 'Lokale API' Invidious API: 'Invidious API' Video View Type: - Video View Type: 'Video Toontype' + Video View Type: 'Type Videoweergave' Grid: 'Raster' List: 'Lijst' Thumbnail Preference: @@ -130,14 +130,14 @@ Settings: View all Invidious instance information: Bekijk alle Invidious-instantiegegevens Theme Settings: Theme Settings: 'Thema Instellingen' - Match Top Bar with Main Color: 'Paar Bovenste Balk met Primaire Kleur' + Match Top Bar with Main Color: 'Laat de bovenste balk overeenkomen met de hoofdkleur' Base Theme: Base Theme: 'Basisthema' Black: 'Zwart' Dark: 'Donker' Light: 'Licht' Main Color Theme: - Main Color Theme: 'Primaire Themakleur' + Main Color Theme: 'Hoofdkleur Thema' Red: 'Rood' Pink: 'Roze' Purple: 'Paars' @@ -161,7 +161,7 @@ Settings: Disable Smooth Scrolling: Vloeiend Scrollen Uitschakelen Player Settings: Player Settings: 'Speler Instellingen' - Force Local Backend for Legacy Formats: 'Forceer Lokale Backend Voor Legacy Indelingen' + Force Local Backend for Legacy Formats: 'Lokale Backend Forceren voor Oudere Formaten' Play Next Video: 'Volgende Video Automatisch Afspelen' Turn on Subtitles by Default: 'Schakel Ondertiteling Standaard in' Autoplay Videos: 'Video''s Automatisch Afspelen' @@ -171,10 +171,10 @@ Settings: Default Volume: 'Standaard Volume' Default Playback Rate: 'Standaard Afspeelsnelheid' Default Video Format: - Default Video Format: 'Standaard Video-Indeling' - Dash Formats: 'Dash Indelingen' - Legacy Formats: 'Legacy Indelingen' - Audio Formats: 'Audio Indelingen' + Default Video Format: 'Standaard Videoformaat' + Dash Formats: 'Dash Formaten' + Legacy Formats: 'Verouderde formaten' + Audio Formats: 'Audio Formaten' Default Quality: Default Quality: 'Standaard Videokwaliteit' Auto: 'Automatisch' @@ -190,20 +190,21 @@ Settings: Playlist Next Video Interval: Afspeellijst Volgende Video Tussentijd Privacy Settings: Privacy Settings: 'Privacy Instellingen' - Remember History: 'Herinner Geschiedenis' - Save Watched Progress: 'Herinner Video Voortgang' - Clear Search Cache: 'Verwijder Zoek-cache' + Remember History: 'Onthoud Geschiedenis' + Save Watched Progress: 'Bewaar Bekeken Voortgang' + Clear Search Cache: 'Verwijder Zoek-Cache' Are you sure you want to clear out your search cache?: 'Weet u zeker dat u de zoek-cache wil verwijderen?' - Search cache has been cleared: 'De zoek-cache is verwijdert' + Search cache has been cleared: 'De zoek-cache is verwijderd' Remove Watch History: 'Verwijder Kijkgeschiedenis' Are you sure you want to remove your entire watch history?: 'Weet u zeker dat u uw volledige kijkgeschiedenis wil verwijderen?' - Watch history has been cleared: 'Kijkgeschiedenis is verwijdert' + Watch history has been cleared: 'Kijkgeschiedenis is verwijderd' Are you sure you want to remove all subscriptions and profiles? This cannot be undone.: Weet u zeker dat u alle abonnementen en profielen wil verwijderen? Dit kan niet worden ontdaan. Remove All Subscriptions / Profiles: Verwijder alle Abonnementen / Profielen + Automatically Remove Video Meta Files: Video-Metabestanden Automatisch Verwijderen Subscription Settings: Subscription Settings: 'Abonnement instellingen' Hide Videos on Watch: 'Verberg Video''s Zodra Bekeken' @@ -249,7 +250,7 @@ Settings: niet genoeg data, item word overgeslagen Subscriptions have been successfully exported: Abonnementen zijn met succes geïmporteerd Invalid history file: Ongeldig geschiedenisbestand - This might take a while, please wait: Dit kan eventjes duren, een momentje + This might take a while, please wait: Dit kan eventjes duren, even geduld aub Invalid subscriptions file: Ongeldig abonnementenbestand One or more subscriptions were unable to be imported: Een of meer abonnementen konden niet worden geïmporteerd @@ -296,7 +297,7 @@ Settings: Hide Playlists: Verberg Afspeellijst The app needs to restart for changes to take effect. Restart and apply change?: De applicatie moet opnieuw opstarten om de veranderingen aan te brengen. Wilt u opnieuw - opstarten? + opstarten en verandering toepassen? Proxy Settings: Error getting network information. Is your proxy configured properly?: Fout bij het opvragen van netwerk informatie. Is uw proxy correct geconfigureerd? @@ -307,7 +308,7 @@ Settings: Your Info: Uw Informatie Test Proxy: Test Proxy Clicking on Test Proxy will send a request to: Door op Test Proxy te klikken zal - er een request worden verstuurd naar + er een verzoek worden verstuurd naar Proxy Port Number: Proxy Poortnummer Proxy Host: Proxy Host Proxy Protocol: Proxy Protocol @@ -346,7 +347,7 @@ About: #On Channel Page Donate: Doneer - these people and projects: deze mensen en project + these people and projects: deze mensen en projecten FreeTube is made possible by: FreeTube is mogelijk gemaakt door Credits: Met dank aan Translate: Vertalen @@ -377,18 +378,19 @@ Channel: Unsubscribe: 'Afmelden' Search Channel: 'Zoek op Kanaal' Your search results have returned 0 results: 'Uw zoekactie heeft 0 resultaten opgeleverd' - Sort By: 'Sorteer Bij' + Sort By: 'Sorteer Op' Videos: Videos: 'Video''s' - This channel does not currently have any videos: 'Dit kanaal heeft nog geen video''s' + This channel does not currently have any videos: 'Dit kanaal heeft op dit moment + nog geen video''s' Sort Types: Newest: 'Nieuwste' Oldest: 'Oudste' Most Popular: 'Meest Populair' Playlists: Playlists: 'Afspeellijsten' - This channel does not currently have any playlists: 'Dit kanaal heeft nog geen - afspeellijsten' + This channel does not currently have any playlists: 'Dit kanaal heeft momenteel + nog geen afspeellijsten' Sort Types: Last Video Added: 'Laatst Toegevoegd' Newest: 'Nieuwste' @@ -466,12 +468,12 @@ Video: #& Videos Autoplay: Automatisch Afspelen Play Previous Video: Speel Vorige Video af - Play Next Video: Volgende Video Automatisch Afspelen - Reverse Playlist: Playlist Omkeren - Shuffle Playlist: Schuifelen Playlist + Play Next Video: Volgende Video Afspelen + Reverse Playlist: Afspeellijst Omkeren + Shuffle Playlist: Afspeellijst in willekeurige volgorde afspelen Loop Playlist: Herhaal Playlist - Starting soon, please refresh the page to check again: Begint spoedig, a.u.b. herlaad - de pagina om nog maal te checken + Starting soon, please refresh the page to check again: Start binnenkort, vernieuw + de pagina om opnieuw te controleren Audio: Best: Beste High: Hoog @@ -516,13 +518,13 @@ Playlist: #& Views Toggle Theatre Mode: 'Schakel Theatermodus In' Change Format: - Change Video Formats: 'Verander Video indeling' - Use Dash Formats: 'Gebruik Dash Indelingen' - Use Legacy Formats: 'Gebruik Legacy Indelingen' - Use Audio Formats: 'Gebruik Audio Indelingen' - Audio formats are not available for this video: Audio indelingen zijn niet beschikbaar + Change Video Formats: 'Verander Video Formaten' + Use Dash Formats: 'Gebruik Dash Formaten' + Use Legacy Formats: 'Gebruik Legacy Formaten' + Use Audio Formats: 'Gebruik Audio Formaten' + Audio formats are not available for this video: Audio formaten zijn niet beschikbaar voor deze video - Dash formats are not available for this video: Dash indelingen zijn niet beschikbaar + Dash formats are not available for this video: Dash formaten zijn niet beschikbaar voor deze video Share: Share Video: 'Deel Video' @@ -537,7 +539,7 @@ Share: YouTube URL copied to clipboard: 'YouTube URL is gekopieerd naar het klembord' YouTube Embed URL copied to clipboard: 'YouTube Insluitlink is gekopieerd naar het klemboard' - Include Timestamp: Begrijp Tijdstempel In + Include Timestamp: Inclusief Tijdstempel YouTube Channel URL copied to clipboard: YouTube URL is gekopieerd naar het klembord Invidious Channel URL copied to clipboard: Invidious Kanaal URL is gekopieerd naar het klembord @@ -545,7 +547,7 @@ Mini Player: 'Minispeler' Comments: Comments: 'Reacties' Click to View Comments: 'Klik om Reacties Te Tonen' - Getting comment replies, please wait: 'Reacties worden verzameld, een momentje' + Getting comment replies, please wait: 'Reacties worden verzameld, even geduld aub' Show Comments: 'Toon Reacties' Hide Comments: 'Verberg Reacties' # Context: View 10 Replies, View 1 Reply @@ -553,14 +555,15 @@ Comments: Hide: 'Verberg' Replies: 'Reacties' Reply: 'Reactie' - There are no comments available for this video: 'Er zijn geen reacties op deze video' - Load More Comments: 'Laad Meer Reacties' + There are no comments available for this video: 'Er zijn geen reacties beschikbaar + voor deze video' + Load More Comments: 'Meer Reacties Laden' There are no more comments for this video: Er zijn geen verdere reacties op deze video - No more comments available: Er zijn niet meer reacties beschikbaar + No more comments available: Er zijn geen reacties meer beschikbaar Newest first: Nieuwste Eerst - Top comments: Bovenste reacties - Sort by: Sorteer Bij + Top comments: Top Reacties + Sort by: Sorteer Op Up Next: 'Volgende' # Toast Messages @@ -571,8 +574,8 @@ Falling back to the local API: 'Terugvallen op lokale API' Subscriptions have not yet been implemented: 'Abonnementen zijn nog niet geïmplementeerd' Loop is now disabled: 'Herhalen is nu uitgeschakeld' Loop is now enabled: 'Herhalen is nu ingeschakeld' -Shuffle is now disabled: 'Schuifelen is nu uitgeschakeld' -Shuffle is now enabled: 'Schuifelen is nu ingeschakeld' +Shuffle is now disabled: 'Willekeurig afspelen is nu uitgeschakeld' +Shuffle is now enabled: 'Willekeurig afspelen is nu ingeschakeld' Playing Next Video: 'Volgende Video Word Afgespeeld' Playing Previous Video: 'Vorige Video Word Afgespeeld' Playing next video in 5 seconds. Click to cancel: 'Volgende Video Begint in 5 Seconden. @@ -588,14 +591,14 @@ Profile: $ is now the active profile: $ is nu het actieve profiel Your default profile has been changed to your primary profile: Uw standaardprofiel is veranderd naar uw hoofdprofiel - Removed $ from your profiles: $ is verwijdert uit uw profielen + Removed $ from your profiles: $ is verwijderd uit uw profielen Your default profile has been set to $: Uw standaard profiel is ingesteld op $ Profile has been updated: Profiel is geüpdate Profile has been created: Profiel is aangemaakt - Your profile name cannot be empty: U profiel naam kan niet leeg zijn + Your profile name cannot be empty: Uw profielnaam mag niet leeg zijn Profile could not be found: Profiel kon niet worden gevonden - All subscriptions will also be deleted.: Alle abonnementen zullen worden verwijderd. - Are you sure you want to delete this profile?: Weet u zeker dat u dit profiel wil + All subscriptions will also be deleted.: Alle abonnementen zullen ook worden verwijderd. + Are you sure you want to delete this profile?: Weet u zeker dat u dit profiel wilt verwijderen? Delete Profile: Verwijder Profiel Make Default Profile: Creëer Standaard Profiel @@ -605,7 +608,7 @@ Profile: Custom Color: Eigen Kleur Color Picker: Kleur Kiezer Edit Profile: Pas Profiel aan - Create New Profile: Creëer een Nieuw Profile + Create New Profile: Creëer een Nieuw Profiel Profile Manager: Beheer Profiel All Channels: Alle Kanalen Profile Select: Selecteer een Profiel @@ -631,8 +634,8 @@ Download From Site: Download van de Website Version $ is now available! Click for more details: Versie $ is nu beschikbaar! Klik voor meer informatie This video is unavailable because of missing formats. This can happen due to country unavailability.: Deze - video is niet beschikbaar vanwege ontbrekende video indelingen. Dit kan gebeuren - als de video niet in uw land beschikbaar is. + video is niet beschikbaar vanwege ontbrekende videoformaten. Dit kan gebeuren als + de video niet in uw land beschikbaar is. Tooltips: Player Settings: Default Video Format: Selecteer de video indeling dat wordt gebruikt wanneer u @@ -667,6 +670,10 @@ Tooltips: Region for Trending: Met trend regio kan je instellen uit welk land je trending video's je wil zien. Niet alle weergegeven landen worden ook daadwerkelijk ondersteund door YouTube + Privacy Settings: + Remove Video Meta Files: Wanneer ingeschakeld zal FreeTube automatisch meta bestanden + die worden gecreëerd tijdens het afspelen van video's verwijderen zodra de pagina + wordt gesloten. Playing Next Video Interval: Volgende video wordt afgespeeld. Klik om te onderbreken. | Volgende video wordt afgespeeld in {nextVideoInterval} seconde. Klik om te onderbreken. | Volgende video wordt afgespeeld in {nextVideoInterval} seconden. Klik om te onderbreken. diff --git a/static/locales/pl.yaml b/static/locales/pl.yaml index d2103d2b..083bc548 100644 --- a/static/locales/pl.yaml +++ b/static/locales/pl.yaml @@ -244,6 +244,7 @@ Settings: jesteś pewny/a, że chcesz usunąć wszystkie subskrypcje i profile? Nie będzie można tego cofnąć. Remove All Subscriptions / Profiles: Usuń wszystkie subskrypcje / profile + Automatically Remove Video Meta Files: Samoczynnie usuwaj pliki metadanych filmu Data Settings: How do I import my subscriptions?: Jak mogę zaimportować swoje subskrypcje? Unknown data key: Nieznany klucz danych @@ -675,6 +676,9 @@ Tooltips: 720p, ale zużywają mniej przepustowości. Formaty audio odtwarzają tylko dźwięk Proxy Videos Through Invidious: Będzie dostarczał filmy, łącząc się z Invidious, a nie bezpośrednio z YouTube. Nadpisuje ustawienia API + Privacy Settings: + Remove Video Meta Files: Po włączeniu FreeTube samoczynnie usunie pliki metadanych + utworzone podczas odtwarzania filmu, gdy tylko strona odtwarzania zostanie zamknięta. Playing Next Video Interval: Odtwarzanie kolejnego filmu już za chwilę. Wciśnij aby przerwać. | Odtwarzanie kolejnego filmu za {nextVideoInterval} sekundę. Wciśnij aby przerwać. | Odtwarzanie kolejnego filmu za {nextVideoInterval} sekund. Wciśnij diff --git a/static/locales/pt-BR.yaml b/static/locales/pt-BR.yaml index 37778548..06d0f0f5 100644 --- a/static/locales/pt-BR.yaml +++ b/static/locales/pt-BR.yaml @@ -185,6 +185,7 @@ Settings: 1440p: '1440p' 4k: '4k' 8k: '8k' + Playlist Next Video Interval: Intervalo do próximo vídeo da lista de reprodução Subscription Settings: Subscription Settings: 'Configurações de inscrições' Hide Videos on Watch: 'Esconder vídeos após assisti-los' @@ -241,6 +242,8 @@ Settings: certeza de que quer apagar todas as inscrições e perfis? Esta ação não pode ser desfeita. Remove All Subscriptions / Profiles: Remover Todas as Inscrições / Perfis + Automatically Remove Video Meta Files: Remover automaticamente os metarquivos + de vídeo Data Settings: Subscriptions have been successfully exported: Inscrições foram exportadas com sucesso @@ -291,6 +294,7 @@ Settings: Hide Video Likes And Dislikes: Ocultar curtidas e desgostos do vídeo Hide Video Views: Ocultar Visualizações de Vídeo Hide Active Subscriptions: Ocultar Inscrições Ativas + Hide Playlists: Ocultar listas de reprodução The app needs to restart for changes to take effect. Restart and apply change?: O aplicativo necessita reiniciar para as mudanças fazerem efeito. Reiniciar e aplicar mudança? @@ -621,6 +625,7 @@ Profile: Profile has been updated: Perfil atualizado Profile has been created: Perfil criado Your profile name cannot be empty: Seu nome de perfil não pode ficar em branco + Profile Filter: Filtro de Perfil Version $ is now available! Click for more details: Versão $ está disponível agora! Clique para mais detalhes A new blog is now available, $. Click to view more: Um novo blog está disponível, @@ -633,7 +638,7 @@ This video is unavailable because of missing formats. This can happen due to cou Tooltips: Subscription Settings: Fetch Feeds from RSS: Quando ativado, o FreeTube usará RSS em vez de seu método - padrão para obter o feed de sua assinatura. O RSS é mais rápido e evita o bloqueio + padrão para obter o feed de sua assinatura. O RSS é mais rápido e evita bloqueio de IP, mas não fornece certas informações como duração do vídeo ou status ao vivo Player Settings: @@ -663,4 +668,12 @@ Tooltips: Preferred API Backend: Escolha o backend que o FreeTube usa para obter os dados. A API local é um extrator integrado. A API Invidious requer um servidor Invidious para se conectar. + Privacy Settings: + Remove Video Meta Files: Quando ativado, o FreeTube exclui automaticamente os + metarquivos criados durante a reprodução do vídeo quando a página de exibição + é fechada. More: Mais +Playing Next Video Interval: Reproduzindo o próximo vídeo imediatamente. Clique para + cancelar. | Reproduzindo o próximo vídeo em {nextVideoInterval} segundo(s). Clique + para cancelar. | Reproduzindo o próximo vídeo em {nextVideoInterval} segundos. Clique + para cancelar. diff --git a/static/locales/ro.yaml b/static/locales/ro.yaml index 54b78abb..1c49a012 100644 --- a/static/locales/ro.yaml +++ b/static/locales/ro.yaml @@ -189,9 +189,10 @@ Settings: Remember History: '' Save Watched Progress: '' Clear Search Cache: '' - Are you sure you want to clear out your search cache?: '' - Search cache has been cleared: '' - Remove Watch History: '' + Are you sure you want to clear out your search cache?: 'Sunteti siguri ca doriti + sa stergeti chache-ul cautarilor ?' + Search cache has been cleared: 'Cache-ul cautarilor a fost sters' + Remove Watch History: 'Sterge Istoricul Vizualizarilor' Are you sure you want to remove your entire watch history?: '' Watch history has been cleared: '' Remove All Subscriptions / Profiles: '' diff --git a/static/locales/ru.yaml b/static/locales/ru.yaml index 5938ce74..8bae27dc 100644 --- a/static/locales/ru.yaml +++ b/static/locales/ru.yaml @@ -1,7 +1,7 @@ FreeTube: 'FreeTube' # Currently on Subscriptions, Playlists, and History 'This part of the app is not ready yet. Come back later when progress has been made.': >- - Эта часть приложения еще не готова. Вернитесь позже, когда будет достигнут прогресс. + Эта часть приложения ещё не готова. Вернитесь позже, когда будет достигнут прогресс. # Webkit Menu Bar File: 'Файл' @@ -127,21 +127,21 @@ Settings: View all Invidious instance information: Показать все доступные экземпляры Invidious Theme Settings: Theme Settings: 'Настройки темы' - Match Top Bar with Main Color: 'Совместить верхнюю панель с основным цветом' + Match Top Bar with Main Color: 'Верхняя панель основного цвета' Base Theme: Base Theme: 'Базовая тема' Black: 'Чёрная' Dark: 'Тёмная' Light: 'Светлая' Main Color Theme: - Main Color Theme: 'Основная цветовая тема' + Main Color Theme: 'Тема основного цвета' Red: 'Красная' Pink: 'Розовая' Purple: 'Фиолетовая' Deep Purple: 'Тёмно-фиолетовая' Indigo: 'Индиго' - Blue: 'Синия' - Light Blue: 'Светло-синия' + Blue: 'Синяя' + Light Blue: 'Светло-синяя' Cyan: 'Голубая' Teal: 'Бирюзовая' Green: 'Зелёная' @@ -242,6 +242,7 @@ Settings: Are you sure you want to remove all subscriptions and profiles? This cannot be undone.: Вы уверены, что хотите удалить все подписки и профили? Это нельзя отменить. Remove All Subscriptions / Profiles: Удалить все подписки/профили + Automatically Remove Video Meta Files: Автоматическое удаление мета-файлов видео Data Settings: How do I import my subscriptions?: Как мне импортировать свои подписки? Unknown data key: Неизвестный ключ данных @@ -466,9 +467,9 @@ Video: Autoplay: Автовоспроизведение Play Previous Video: Воспроизвести предыдущее видео Play Next Video: Воспроизводить следующее видео - Reverse Playlist: Обратный плейлист - Shuffle Playlist: Перемешанный плейлист - Loop Playlist: Циклический плейлист + Reverse Playlist: Обратный порядок плейлиста + Shuffle Playlist: Перемешать плейлист + Loop Playlist: Зациклить плейлист Starting soon, please refresh the page to check again: Скоро начнётся, обновите страницу, чтобы проверить ещё раз Audio: @@ -485,9 +486,9 @@ Video: Open Channel in YouTube: Открыть канал в YouTube Streamed on: Транслировано Started streaming on: Трансляция начата на - Video has been removed from your saved list: Видео было удалено из списка сохраненных - Video has been saved: Видео было добавлено в сохраненные - Save Video: Добавить видео в сохраненные + Video has been removed from your saved list: Видео было удалено из списка сохранённых + Video has been saved: Видео было добавлено в сохранённые + Save Video: Добавить видео в сохранённые Videos: #& Sort By Sort By: @@ -568,8 +569,8 @@ Invidious API Error (Click to copy): 'Ошибка invidious API (Нажмите Falling back to Invidious API: 'Возврат к Invidious API' Falling back to the local API: 'Возврат к локальному API' Subscriptions have not yet been implemented: 'Подписки ещё не реализованы' -Loop is now disabled: 'Цикл теперь отключён' -Loop is now enabled: 'Цикл теперь включён' +Loop is now disabled: 'Зацикливание теперь отключено' +Loop is now enabled: 'Зацикливание теперь включено' Shuffle is now disabled: 'Перемешивание теперь отключено' Shuffle is now enabled: 'Перемешивание теперь включено' Playing Next Video: 'Воспроизведение следующего видео' @@ -578,7 +579,7 @@ Playing next video in 5 seconds. Click to cancel: 'Воспроизведени через 5 секунд. Нажмите, чтобы отменить.' Canceled next video autoplay: 'Отменено автовоспроизведение следующего видео' 'The playlist has ended. Enable loop to continue playing': 'Плейлист закончился. - Включите цикл, чтобы продолжить воспроизведение' + Включите зацикливание, чтобы продолжить воспроизведение' Yes: 'Да' No: 'Нет' @@ -619,7 +620,7 @@ Profile: No channel(s) have been selected: Канал(ы) не были выбраны Add Selected To Profile: Добавить выбранное в профиль Delete Selected: Удалить выбранное - Select None: Выбрать ничего + Select None: Не выбрано Select All: Выбрать все $ selected: $ выбрано Other Channels: Другие каналы @@ -632,7 +633,7 @@ Download From Site: Скачать с сайта Version $ is now available! Click for more details: Версия $ уже доступна! Нажмите, чтобы узнать больше This video is unavailable because of missing formats. This can happen due to country unavailability.: Это - видео недоступно из-за отсутствия форматов. Это может произойти из-за недоступности + видео недоступно из-за отсутствия форматов. Это может произойти из-за ограничений страны. Tooltips: General Settings: @@ -647,9 +648,8 @@ Tooltips: Preferred API Backend: Выберите серверную часть, которую FreeTube использует для получения данных. Локальный API - это встроенный экстрактор. Invidious API требует подключения к Invidious серверу. - Region for Trending: Область тенденций позволяет вам выбрать популярные видео - из страны, которые вы хотите отображать. Не все отображаемые страны на самом - деле поддерживаются YouTube + Region for Trending: Регион трендов позволяет вам выбрать популярные видео из + выбранной страны. Не все отображаемые страны поддерживаются YouTube Subscription Settings: Fetch Feeds from RSS: Если этот параметр включен, FreeTube будет получать вашу ленту подписок с помощью RSS, а не как обычно. RSS работает быстрее и предотвращает @@ -667,6 +667,10 @@ Tooltips: устаревшие форматы, возвращаемые им, вместо форматов, возвращаемых Invidious. Помогает, когда видео, возвращенные Invidious, не воспроизводятся из-за ограничений страны + Privacy Settings: + Remove Video Meta Files: Если этот параметр включен, FreeTube автоматически удаляет + метафайлы, созданные во время воспроизведения видео, когда страница просмотра + закрывается. More: Больше Playing Next Video Interval: Воспроизведение следующего видео без задержки. Нажмите для отмены. | Воспроизведение следующего видео через {nextVideoInterval} сек. Нажмите diff --git a/static/locales/sv.yaml b/static/locales/sv.yaml index 1a401a95..8879fa7d 100644 --- a/static/locales/sv.yaml +++ b/static/locales/sv.yaml @@ -70,6 +70,8 @@ Search Filters: Fetching results. Please wait: 'Hämtar resultat. Snälla vänta' Fetch more results: 'Hämta fler resultat' # Sidebar + There are no more results for this search: Det finns inte fler resultat för den + här sökningen Subscriptions: # On Subscriptions Page Subscriptions: 'Prenumerationer' diff --git a/static/locales/tr.yaml b/static/locales/tr.yaml index ff7a23c0..3090f6ba 100644 --- a/static/locales/tr.yaml +++ b/static/locales/tr.yaml @@ -206,6 +206,8 @@ Settings: Remove All Subscriptions / Profiles: 'Tüm Abonelikler/Profilleri Temizle' Are you sure you want to remove all subscriptions and profiles? This cannot be undone.: 'Tüm abonelikler/profilleri temizlemek istediğinizden emin misiniz? Geri alınamaz.' + Automatically Remove Video Meta Files: Video Meta Dosyalarını Otomatik Olarak + Kaldır Subscription Settings: Subscription Settings: 'Abonelik Ayarları' Hide Videos on Watch: 'İzlenmiş Videoları Gizle' @@ -661,6 +663,9 @@ Tooltips: Region for Trending: Trendlerin bölgesi, hangi ülkenin trend videolarını görüntülemek istediğinizi seçmenize olanak tanır. Görüntülenen ülkelerden bazıları YouTube tarafından desteklenmemektedir + Privacy Settings: + Remove Video Meta Files: Etkinleştirildiğinde, izleme sayfası kapatıldığında video + oynatma sırasında oluşturulan meta dosyaları otomatik olarak silinir. Playing Next Video Interval: Sonraki video hemen oynatılıyor. İptal etmek için tıklayın. | Sonraki video {nextVideoInterval} saniye içinde oynatılıyor. İptal etmek için tıklayın. | Sonraki video {nextVideoInterval} saniye içinde oynatılıyor. İptal etmek diff --git a/static/locales/uk.yaml b/static/locales/uk.yaml index 84f44844..511b36c1 100644 --- a/static/locales/uk.yaml +++ b/static/locales/uk.yaml @@ -211,6 +211,7 @@ Settings: Remove All Subscriptions / Profiles: 'Видалити всі підписки / профілі' Are you sure you want to remove all subscriptions and profiles? This cannot be undone.: 'Справді хочете вилучити всі підписки та профілі? Цю дію не можна скасувати.' + Automatically Remove Video Meta Files: Автоматично вилучати метафайли відео Subscription Settings: Subscription Settings: 'Налаштування підписки' Hide Videos on Watch: 'Ховати відео при перегляді' @@ -617,6 +618,9 @@ Tooltips: ІР, але не надає дані, як-от тривалість відео або стан трансляції' # Toast Messages + Privacy Settings: + Remove Video Meta Files: Якщо увімкнено, FreeTube автоматично видаляє метафайли, + створені під час відтворення відео, коли сторінку перегляду закрито. Local API Error (Click to copy): 'Помилка локального API (натисніть, щоб скопіювати)' Invidious API Error (Click to copy): 'Помилка Invidious API (натисніть, щоб скопіювати)' Falling back to Invidious API: 'Повернення до API Invidious' diff --git a/static/locales/zh-CN.yaml b/static/locales/zh-CN.yaml index d25d8b8d..62529036 100644 --- a/static/locales/zh-CN.yaml +++ b/static/locales/zh-CN.yaml @@ -175,6 +175,7 @@ Settings: 1440p: '1440p' 4k: '4k' 8k: '8k' + Playlist Next Video Interval: 播放列表 下一个影片时间间隔 Subscription Settings: Subscription Settings: '订阅设置' Hide Videos on Watch: '观看时隐藏视频' @@ -222,6 +223,7 @@ Settings: Clear Search Cache: 清除搜索缓存 Are you sure you want to remove all subscriptions and profiles? This cannot be undone.: 您确定您想移除所有订阅和配置文件吗?这无法撤销。 Remove All Subscriptions / Profiles: 移除所有订阅 / 配置文件 + Automatically Remove Video Meta Files: 自动删除硬盘元数据文件 Data Settings: Subscriptions have been successfully exported: 订阅已成功导出 This might take a while, please wait: 这可能需要一段时间,请稍候 @@ -264,6 +266,7 @@ Settings: Hide Video Views: 隐藏视频观看数量 Distraction Free Settings: 零打扰设置 Hide Active Subscriptions: 隐藏活跃的订阅 + Hide Playlists: 隐藏播放列表 The app needs to restart for changes to take effect. Restart and apply change?: 应用需要重启让修改生效。重启以应用修改? Proxy Settings: Proxy Protocol: 代理协议 @@ -278,6 +281,7 @@ Settings: Test Proxy: 测试代理 Clicking on Test Proxy will send a request to: 点击测试代理将会发送一个请求给 Proxy Port Number: 代理端口号 + Proxy Host: 代理主机 About: #On About page About: '关于' @@ -308,6 +312,18 @@ About: Website: 网站 Blog: 博客 Email: 电子邮件 + Donate: 捐款 + Credits: 贡献者 + Translate: 翻译 + Please read the: 请阅读 + Chat on Matrix: 在 Matrix 上聊天 + Mastodon: Mastodon + FAQ: 常见问题 + FreeTube Wiki: FreeTube维基 + Help: 说明 + GitHub releases: GitHub 版本 + View License: 查看授权 + Licensed under the AGPLv3: 以 AGPLv3 协议授权 Channel: Subscriber: '订阅者' Subscribers: '订阅者' @@ -417,6 +433,9 @@ Video: Open Channel in YouTube: 在YouTube打开频道 Started streaming on: 开始在线直播于 Streamed on: 在线直播于 + Video has been removed from your saved list: 视频已从你的播放列表移除 + Video has been saved: 视频已保存 + Save Video: 保存视频到播放列表 Videos: #& Sort By Sort By: diff --git a/static/locales/zh-TW.yaml b/static/locales/zh-TW.yaml index cf43977b..17dfc93c 100644 --- a/static/locales/zh-TW.yaml +++ b/static/locales/zh-TW.yaml @@ -121,9 +121,9 @@ Settings: Match Top Bar with Main Color: '頂部功能表欄對應主色彩' Base Theme: Base Theme: '基本主題' - Black: '黑' - Dark: '深' - Light: '淺' + Black: '黑色' + Dark: '深色' + Light: '淺色' Main Color Theme: Main Color Theme: '主題色' Red: '紅' @@ -161,7 +161,7 @@ Settings: Default Playback Rate: '預設播放速度' Default Video Format: Default Video Format: '預設影片格式' - Dash Formats: 'Dash格式' + Dash Formats: '儀錶盤格式' Legacy Formats: '傳統格式' Audio Formats: '音訊格式' Default Quality: @@ -224,6 +224,7 @@ Settings: Privacy Settings: 隱私設定 Are you sure you want to remove all subscriptions and profiles? This cannot be undone.: 您確定要移除所有訂閱與設定檔嗎嗎? 注意:這無法復原。 Remove All Subscriptions / Profiles: 移除所有訂閱/設定檔 + Automatically Remove Video Meta Files: 自動刪除影片元檔案 Data Settings: How do I import my subscriptions?: 我要如何匯入我的訂閱? Unknown data key: 未知的資料金鑰 @@ -479,11 +480,11 @@ Playlist: Toggle Theatre Mode: '切換為劇院模式' Change Format: Change Video Formats: '變更影片格式' - Use Dash Formats: '使用Dash格式' + Use Dash Formats: '使用儀錶盤格式' Use Legacy Formats: '使用傳統格式' Use Audio Formats: '使用音訊格式' Audio formats are not available for this video: 這個影片沒有音訊格式 - Dash formats are not available for this video: 這個影片沒有Dash格式 + Dash formats are not available for this video: 這個影片沒有儀錶盤格式 Share: Share Video: '分享影片' Copy Link: '複製連結' @@ -584,7 +585,7 @@ Tooltips: Subscription Settings: Fetch Feeds from RSS: 啟用後,FreeTube將使用RSS代替它的預設方法來抓取您的訂閱來源。RSS的速度較快,而且可以防止IP封鎖,但它可能不會提供某些資訊,例如影片長度或是直播狀態。 Player Settings: - Default Video Format: 設定要用於影片播放的格式。Dash格式有更高的品質。傳統格式會限制在 720p但頻寬需求更低。音訊格式為僅有音訊的串流 + Default Video Format: 設定要用於影片播放的格式。儀錶盤格式有更高的畫質。傳統格式會限制在 720p 但頻寬需求更低。音訊格式為僅有音訊的串流 Proxy Videos Through Invidious: 將連線到 Invidious而非直接連線到 YouTube 來提供影片。覆寫 API 偏好 Force Local Backend for Legacy Formats: 僅當 Invidious API是您預設 API 時才有效。啟用後,區域 API 將會執行並使用由其回傳的的傳統格式,而非 Invidious 回傳的格式。對因為國家地區限制而無法播放 Invidious回傳的影片時有幫助 @@ -596,6 +597,8 @@ Tooltips: Preferred API Backend: 選擇 FreeTube 要用於取得YouTube資料的伺服器。本地 API 是內建擷取器。Invidious API 需要 Invidious 伺服器才能連線。 Region for Trending: 發燒影片區域可以讓您選擇想要顯示哪個國家的發燒影片。 注意:並非所有國家都被YouTube支援 + Privacy Settings: + Remove Video Meta Files: 如果啟用,FreeTube會在關閉觀看頁面時,自動刪除影片播放過程中建立的暫存檔案。 Playing Next Video Interval: 馬上播放下一個影片。點擊取消。| 播放下一個影片的時間為{nextVideoInterval}秒。點擊取消。| 播放下一個影片的時間為{nextVideoInterval}秒。點擊取消。 More: 更多