From e945b184a0f29b47c33bbd05578f3493ca9c8e6c Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Wed, 6 Jun 2018 14:23:40 +0200 Subject: Localize player --- .../videos/+video-watch/video-watch.component.ts | 19 +- client/src/assets/player/peertube-link-button.ts | 2 +- client/src/assets/player/peertube-player.ts | 67 ++-- .../src/assets/player/peertube-videojs-plugin.ts | 10 +- client/src/assets/player/resolution-menu-button.ts | 7 +- client/src/assets/player/settings-menu-button.ts | 2 +- client/src/assets/player/settings-menu-item.ts | 4 +- client/src/assets/player/utils.ts | 2 + client/src/assets/player/webtorrent-info-button.ts | 7 +- client/src/locale/source/player_en_US.xml | 378 ++++++++++++++++++++ client/src/locale/source/videojs_en_US.json | 85 +++++ client/src/locale/target/player_fr.json | 1 + client/src/locale/target/player_fr.xml | 379 +++++++++++++++++++++ client/src/standalone/videos/embed.ts | 12 +- 14 files changed, 917 insertions(+), 58 deletions(-) create mode 100644 client/src/locale/source/player_en_US.xml create mode 100644 client/src/locale/source/videojs_en_US.json create mode 100644 client/src/locale/target/player_fr.json create mode 100644 client/src/locale/target/player_fr.xml (limited to 'client') diff --git a/client/src/app/videos/+video-watch/video-watch.component.ts b/client/src/app/videos/+video-watch/video-watch.component.ts index 23d74494c..d3e16c4cf 100644 --- a/client/src/app/videos/+video-watch/video-watch.component.ts +++ b/client/src/app/videos/+video-watch/video-watch.component.ts @@ -1,5 +1,5 @@ import { catchError } from 'rxjs/operators' -import { Component, ElementRef, NgZone, OnDestroy, OnInit, ViewChild } from '@angular/core' +import { Component, ElementRef, LOCALE_ID, NgZone, OnDestroy, OnInit, ViewChild, Inject } from '@angular/core' import { ActivatedRoute, Router } from '@angular/router' import { RedirectService } from '@app/core/routing/redirect.service' import { peertubeLocalStorage } from '@app/shared/misc/peertube-local-storage' @@ -21,9 +21,10 @@ import { MarkdownService } from '../shared' import { VideoDownloadComponent } from './modal/video-download.component' import { VideoReportComponent } from './modal/video-report.component' import { VideoShareComponent } from './modal/video-share.component' -import { getVideojsOptions } from '../../../assets/player/peertube-player' +import { getVideojsOptions, loadLocale, addContextMenu } from '../../../assets/player/peertube-player' import { ServerService } from '@app/core' import { I18n } from '@ngx-translate/i18n-polyfill' +import { environment } from '../../../environments/environment' @Component({ selector: 'my-video-watch', @@ -54,6 +55,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy { likesBarTooltipText = '' hasAlreadyAcceptedPrivacyConcern = false + private videojsLocaleLoaded = false private otherVideos: Video[] = [] private paramsSub: Subscription @@ -72,7 +74,8 @@ export class VideoWatchComponent implements OnInit, OnDestroy { private markdownService: MarkdownService, private zone: NgZone, private redirectService: RedirectService, - private i18n: I18n + private i18n: I18n, + @Inject(LOCALE_ID) private localeId: string ) {} get user () { @@ -365,7 +368,6 @@ export class VideoWatchComponent implements OnInit, OnDestroy { inactivityTimeout: 2500, videoFiles: this.video.files, playerElement: this.playerElement, - videoEmbedUrl: this.video.embedUrl, videoViewUrl: this.videoService.getVideoViewUrl(this.video.uuid), videoDuration: this.video.duration, enableHotkeys: true, @@ -374,11 +376,18 @@ export class VideoWatchComponent implements OnInit, OnDestroy { startTime }) + if (this.videojsLocaleLoaded === false) { + await loadLocale(environment.apiUrl, videojs, environment.production === true ? this.localeId : 'fr') + this.videojsLocaleLoaded = true + } + const self = this - this.zone.runOutsideAngular(() => { + this.zone.runOutsideAngular(async () => { videojs(this.playerElement, videojsOptions, function () { self.player = this this.on('customError', (event, data) => self.handleError(data.err)) + + addContextMenu(self.player, self.video.embedUrl) }) }) diff --git a/client/src/assets/player/peertube-link-button.ts b/client/src/assets/player/peertube-link-button.ts index a13815d61..26f8b9d73 100644 --- a/client/src/assets/player/peertube-link-button.ts +++ b/client/src/assets/player/peertube-link-button.ts @@ -24,7 +24,7 @@ class PeerTubeLinkButton extends Button { const el = videojsUntyped.dom.createEl('a', { href: buildVideoLink(), innerHTML: 'PeerTube', - title: 'Go to the video page', + title: this.player_.localize('Go to the video page'), className: 'vjs-peertube-link', target: '_blank' }) diff --git a/client/src/assets/player/peertube-player.ts b/client/src/assets/player/peertube-player.ts index d204b9703..b604097fa 100644 --- a/client/src/assets/player/peertube-player.ts +++ b/client/src/assets/player/peertube-player.ts @@ -12,6 +12,7 @@ import './peertube-videojs-plugin' import './peertube-load-progress-bar' import { videojsUntyped } from './peertube-videojs-typings' import { buildVideoEmbed, buildVideoLink, copyToClipboard } from './utils' +import { is18nLocale, isDefaultLocale } from '../../../../shared/models/i18n/i18n' // Change 'Playback Rate' to 'Speed' (smaller for our settings menu) videojsUntyped.getComponent('PlaybackRateMenuButton').prototype.controlText_ = 'Speed' @@ -20,7 +21,6 @@ function getVideojsOptions (options: { autoplay: boolean, playerElement: HTMLVideoElement, videoViewUrl: string, - videoEmbedUrl: string, videoDuration: number, videoFiles: VideoFile[], enableHotkeys: boolean, @@ -43,29 +43,6 @@ function getVideojsOptions (options: { videoViewUrl: options.videoViewUrl, videoDuration: options.videoDuration, startTime: options.startTime - }, - contextmenuUI: { - content: [ - { - label: 'Copy the video URL', - listener: function () { - copyToClipboard(buildVideoLink()) - } - }, - { - label: 'Copy the video URL at the current time', - listener: function () { - const player = this - copyToClipboard(buildVideoLink(player.currentTime())) - } - }, - { - label: 'Copy embed code', - listener: () => { - copyToClipboard(buildVideoEmbed(options.videoEmbedUrl)) - } - } - ] } }, controlBar: { @@ -135,4 +112,44 @@ function getControlBarChildren (options: { return children } -export { getVideojsOptions } +function addContextMenu (player: any, videoEmbedUrl: string) { + console.log(videoEmbedUrl) + + player.contextmenuUI({ + content: [ + { + label: player.localize('Copy the video URL'), + listener: function () { + copyToClipboard(buildVideoLink()) + } + }, + { + label: player.localize('Copy the video URL at the current time'), + listener: function () { + const player = this + copyToClipboard(buildVideoLink(player.currentTime())) + } + }, + { + label: player.localize('Copy embed code'), + listener: () => { + copyToClipboard(buildVideoEmbed(videoEmbedUrl)) + } + } + ] + }) +} + +function loadLocale (serverUrl: string, videojs: any, locale: string) { + if (!is18nLocale(locale) || isDefaultLocale(locale)) return undefined + + return fetch(serverUrl + '/client/locales/' + locale + '/player.json') + .then(res => res.json()) + .then(json => videojs.addLanguage(locale, json)) +} + +export { + loadLocale, + getVideojsOptions, + addContextMenu +} diff --git a/client/src/assets/player/peertube-videojs-plugin.ts b/client/src/assets/player/peertube-videojs-plugin.ts index 79df42a53..68e98f170 100644 --- a/client/src/assets/player/peertube-videojs-plugin.ts +++ b/client/src/assets/player/peertube-videojs-plugin.ts @@ -4,15 +4,7 @@ import { VideoFile } from '../../../../shared/models/videos/video.model' import { renderVideo } from './video-renderer' import './settings-menu-button' import { PeertubePluginOptions, VideoJSComponentInterface, videojsUntyped } from './peertube-videojs-typings' -import { - getAverageBandwidth, - getStoredMute, - getStoredVolume, - isMobile, - saveAverageBandwidth, - saveMuteInStore, - saveVolumeInStore -} from './utils' +import { getAverageBandwidth, getStoredMute, getStoredVolume, saveAverageBandwidth, saveMuteInStore, saveVolumeInStore } from './utils' import minBy from 'lodash-es/minBy' import maxBy from 'lodash-es/maxBy' import * as CacheChunkStore from 'cache-chunk-store' diff --git a/client/src/assets/player/resolution-menu-button.ts b/client/src/assets/player/resolution-menu-button.ts index 2efc8de69..d317a5efc 100644 --- a/client/src/assets/player/resolution-menu-button.ts +++ b/client/src/assets/player/resolution-menu-button.ts @@ -8,10 +8,7 @@ class ResolutionMenuButton extends MenuButton { label: HTMLElement constructor (player: videojs.Player, options) { - options.label = 'Quality' super(player, options) - - this.controlText_ = 'Quality' this.player = player player.peertube().on('videoFileUpdate', () => this.updateLabel()) @@ -51,7 +48,7 @@ class ResolutionMenuButton extends MenuButton { this.player_, { id: -1, - label: 'Auto', + label: this.player_.localize('Auto'), src: null } )) @@ -77,4 +74,6 @@ class ResolutionMenuButton extends MenuButton { return this.player_.peertube().getCurrentResolutionLabel() } } +ResolutionMenuButton.prototype.controlText_ = 'Quality' + MenuButton.registerComponent('ResolutionMenuButton', ResolutionMenuButton) diff --git a/client/src/assets/player/settings-menu-button.ts b/client/src/assets/player/settings-menu-button.ts index bf6ac145a..b51c52506 100644 --- a/client/src/assets/player/settings-menu-button.ts +++ b/client/src/assets/player/settings-menu-button.ts @@ -275,7 +275,7 @@ class SettingsDialog extends Component { } -SettingsButton.prototype.controlText_ = 'Settings Button' +SettingsButton.prototype.controlText_ = 'Settings' Component.registerComponent('SettingsButton', SettingsButton) Component.registerComponent('SettingsDialog', SettingsDialog) diff --git a/client/src/assets/player/settings-menu-item.ts b/client/src/assets/player/settings-menu-item.ts index 048c88533..f595fd459 100644 --- a/client/src/assets/player/settings-menu-item.ts +++ b/client/src/assets/player/settings-menu-item.ts @@ -132,7 +132,7 @@ class SettingsMenuItem extends MenuItem { const button = this.subMenu.menu.addChild('MenuItem', {}, 0) button.name_ = 'BackButton' button.addClass('vjs-back-button') - button.el_.innerHTML = this.subMenu.controlText_ + button.el_.innerHTML = this.player_.localize(this.subMenu.controlText_) } /** @@ -201,7 +201,7 @@ class SettingsMenuItem extends MenuItem { saveUpdateLabel.call(this.subMenu) } - this.settingsSubMenuTitleEl_.innerHTML = this.subMenu.controlText_ + this.settingsSubMenuTitleEl_.innerHTML = this.player_.localize(this.subMenu.controlText_) this.settingsSubMenuEl_.appendChild(this.subMenu.menu.el_) this.panelChildEl.appendChild(this.settingsSubMenuEl_) this.update() diff --git a/client/src/assets/player/utils.ts b/client/src/assets/player/utils.ts index 487b3a1be..ce7aaea2a 100644 --- a/client/src/assets/player/utils.ts +++ b/client/src/assets/player/utils.ts @@ -1,3 +1,5 @@ +import { is18nLocale, isDefaultLocale } from '../../../../shared/models/i18n/i18n' + function toTitleCase (str: string) { return str.charAt(0).toUpperCase() + str.slice(1) } diff --git a/client/src/assets/player/webtorrent-info-button.ts b/client/src/assets/player/webtorrent-info-button.ts index baeb22b64..10945c665 100644 --- a/client/src/assets/player/webtorrent-info-button.ts +++ b/client/src/assets/player/webtorrent-info-button.ts @@ -60,13 +60,8 @@ class WebtorrentInfoButton extends Button { className: 'peers-number', textContent: 'HTTP' }) - const subDivFallbackText = videojsUntyped.dom.createEl('span', { - className: 'peers-text', - textContent: ' fallback' - }) subDivHttp.appendChild(subDivHttpText) - subDivHttp.appendChild(subDivFallbackText) div.appendChild(subDivHttp) this.player_.peertube().on('torrentInfo', (event, data) => { @@ -89,7 +84,7 @@ class WebtorrentInfoButton extends Button { uploadSpeedUnit.textContent = ' ' + uploadSpeed[ 1 ] peersNumber.textContent = numPeers - peersText.textContent = ' peers' + peersText.textContent = ' ' + this.player_.localize('peers') subDivHttp.className = 'vjs-peertube-hidden' subDivWebtorrent.className = 'vjs-peertube-displayed' diff --git a/client/src/locale/source/player_en_US.xml b/client/src/locale/source/player_en_US.xml new file mode 100644 index 000000000..5bb6afdf7 --- /dev/null +++ b/client/src/locale/source/player_en_US.xml @@ -0,0 +1,378 @@ + + + + + Audio Player + undefined + + + Video Player + undefined + + + Play + undefined + + + Pause + undefined + + + Replay + undefined + + + Current Time + undefined + + + Duration + undefined + + + Remaining Time + undefined + + + Stream Type + undefined + + + LIVE + undefined + + + Loaded + undefined + + + Progress + undefined + + + Progress Bar + undefined + + + {1} of {2} + undefined + + + Fullscreen + undefined + + + Non-Fullscreen + undefined + + + Mute + undefined + + + Unmute + undefined + + + Playback Rate + undefined + + + Subtitles + undefined + + + subtitles off + undefined + + + Captions + undefined + + + captions off + undefined + + + Chapters + undefined + + + Descriptions + undefined + + + descriptions off + undefined + + + Audio Track + undefined + + + Volume Level + undefined + + + You aborted the media playback + undefined + + + A network error caused the media download to fail part-way. + undefined + + + The media could not be loaded, either because the server or network failed or because the format is not supported. + undefined + + + The media playback was aborted due to a corruption problem or because the media used features your browser did not support. + undefined + + + No compatible source was found for this media. + undefined + + + The media is encrypted and we do not have the keys to decrypt it. + undefined + + + Play Video + undefined + + + Close + undefined + + + Close Modal Dialog + undefined + + + Modal Window + undefined + + + This is a modal window + undefined + + + This modal can be closed by pressing the Escape key or activating the close button. + undefined + + + , opens captions settings dialog + undefined + + + , opens subtitles settings dialog + undefined + + + , opens descriptions settings dialog + undefined + + + , selected + undefined + + + captions settings + undefined + + + subititles settings + undefined + + + descriptions settings + undefined + + + Text + undefined + + + White + undefined + + + Black + undefined + + + Red + undefined + + + Green + undefined + + + Blue + undefined + + + Yellow + undefined + + + Magenta + undefined + + + Cyan + undefined + + + Background + undefined + + + Window + undefined + + + Transparent + undefined + + + Semi-Transparent + undefined + + + Opaque + undefined + + + Font Size + undefined + + + Text Edge Style + undefined + + + None + undefined + + + Raised + undefined + + + Depressed + undefined + + + Uniform + undefined + + + Dropshadow + undefined + + + Font Family + undefined + + + Proportional Sans-Serif + undefined + + + Monospace Sans-Serif + undefined + + + Proportional Serif + undefined + + + Monospace Serif + undefined + + + Casual + undefined + + + Script + undefined + + + Small Caps + undefined + + + Reset + undefined + + + restore all settings to the default values + undefined + + + Done + undefined + + + Caption Settings Dialog + undefined + + + Beginning of dialog window. Escape will cancel and close the window. + undefined + + + End of dialog window. + undefined + + + {1} is loading. + undefined + + + Quality + undefined + + + Auto + undefined + + + Speed + undefined + + + peers + undefined + + + Go to the video page + undefined + + + Settings + undefined + + + Uses P2P, others may know you are watching this video. + undefined + + + Copy the video URL + undefined + + + Copy the video URL at the current time + undefined + + + Copy embed code + undefined + + + + \ No newline at end of file diff --git a/client/src/locale/source/videojs_en_US.json b/client/src/locale/source/videojs_en_US.json new file mode 100644 index 000000000..92caaa683 --- /dev/null +++ b/client/src/locale/source/videojs_en_US.json @@ -0,0 +1,85 @@ +{ + "Audio Player": "Audio Player", + "Video Player": "Video Player", + "Play": "Play", + "Pause": "Pause", + "Replay": "Replay", + "Current Time": "Current Time", + "Duration": "Duration", + "Remaining Time": "Remaining Time", + "Stream Type": "Stream Type", + "LIVE": "LIVE", + "Loaded": "Loaded", + "Progress": "Progress", + "Progress Bar": "Progress Bar", + "progress bar timing: currentTime={1} duration={2}": "{1} of {2}", + "Fullscreen": "Fullscreen", + "Non-Fullscreen": "Non-Fullscreen", + "Mute": "Mute", + "Unmute": "Unmute", + "Playback Rate": "Playback Rate", + "Subtitles": "Subtitles", + "subtitles off": "subtitles off", + "Captions": "Captions", + "captions off": "captions off", + "Chapters": "Chapters", + "Descriptions": "Descriptions", + "descriptions off": "descriptions off", + "Audio Track": "Audio Track", + "Volume Level": "Volume Level", + "You aborted the media playback": "You aborted the media playback", + "A network error caused the media download to fail part-way.": "A network error caused the media download to fail part-way.", + "The media could not be loaded, either because the server or network failed or because the format is not supported.": "The media could not be loaded, either because the server or network failed or because the format is not supported.", + "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "The media playback was aborted due to a corruption problem or because the media used features your browser did not support.", + "No compatible source was found for this media.": "No compatible source was found for this media.", + "The media is encrypted and we do not have the keys to decrypt it.": "The media is encrypted and we do not have the keys to decrypt it.", + "Play Video": "Play Video", + "Close": "Close", + "Close Modal Dialog": "Close Modal Dialog", + "Modal Window": "Modal Window", + "This is a modal window": "This is a modal window", + "This modal can be closed by pressing the Escape key or activating the close button.": "This modal can be closed by pressing the Escape key or activating the close button.", + ", opens captions settings dialog": ", opens captions settings dialog", + ", opens subtitles settings dialog": ", opens subtitles settings dialog", + ", opens descriptions settings dialog": ", opens descriptions settings dialog", + ", selected": ", selected", + "captions settings": "captions settings", + "subtitles settings": "subititles settings", + "descriptions settings": "descriptions settings", + "Text": "Text", + "White": "White", + "Black": "Black", + "Red": "Red", + "Green": "Green", + "Blue": "Blue", + "Yellow": "Yellow", + "Magenta": "Magenta", + "Cyan": "Cyan", + "Background": "Background", + "Window": "Window", + "Transparent": "Transparent", + "Semi-Transparent": "Semi-Transparent", + "Opaque": "Opaque", + "Font Size": "Font Size", + "Text Edge Style": "Text Edge Style", + "None": "None", + "Raised": "Raised", + "Depressed": "Depressed", + "Uniform": "Uniform", + "Dropshadow": "Dropshadow", + "Font Family": "Font Family", + "Proportional Sans-Serif": "Proportional Sans-Serif", + "Monospace Sans-Serif": "Monospace Sans-Serif", + "Proportional Serif": "Proportional Serif", + "Monospace Serif": "Monospace Serif", + "Casual": "Casual", + "Script": "Script", + "Small Caps": "Small Caps", + "Reset": "Reset", + "restore all settings to the default values": "restore all settings to the default values", + "Done": "Done", + "Caption Settings Dialog": "Caption Settings Dialog", + "Beginning of dialog window. Escape will cancel and close the window.": "Beginning of dialog window. Escape will cancel and close the window.", + "End of dialog window.": "End of dialog window.", + "{1} is loading.": "{1} is loading." +} diff --git a/client/src/locale/target/player_fr.json b/client/src/locale/target/player_fr.json new file mode 100644 index 000000000..6c399fc3f --- /dev/null +++ b/client/src/locale/target/player_fr.json @@ -0,0 +1 @@ +{"Audio Player":"Lecteur audio","Video Player":"Lecteur vidéo","Play":"Lecture","Pause":"Pause","Replay":"Revoir","Current Time":"Temps actuel","Duration":"Durée","Remaining Time":"Temps restant","Stream Type":"Type de flux","LIVE":"EN DIRECT","Loaded":"Chargé","Progress":"Progression","Progress Bar":"Barre de progression","progress bar timing: currentTime={1} duration={2}":"{1} de {2}","Fullscreen":"Plein écran","Non-Fullscreen":"Fenêtré","Mute":"Sourdine","Unmute":"Son activé","Playback Rate":"Vitesse de lecture","Subtitles":"Sous-titres","subtitles off":"Sous-titres désactivés","Captions":"Sous-titres transcrits","captions off":"Sous-titres transcrits désactivés","Chapters":"Chapitres","Descriptions":"Descriptions","descriptions off":"descriptions désactivées","Audio Track":"Piste audio","Volume Level":"Niveau de volume","You aborted the media playback":"Vous avez interrompu la lecture de la vidéo.","A network error caused the media download to fail part-way.":"Une erreur de réseau a interrompu le téléchargement de la vidéo.","The media could not be loaded, either because the server or network failed or because the format is not supported.":"Cette vidéo n'a pas pu être chargée, soit parce que le serveur ou le réseau a échoué ou parce que le format n'est pas reconnu.","The media playback was aborted due to a corruption problem or because the media used features your browser did not support.":"La lecture de la vidéo a été interrompue à cause d'un problème de corruption ou parce que la vidéo utilise des fonctionnalités non prises en charge par votre navigateur.","No compatible source was found for this media.":"Aucune source compatible n'a été trouvée pour cette vidéo.","The media is encrypted and we do not have the keys to decrypt it.":"Le média est chiffré et nous n'avons pas les clés pour le déchiffrer.","Play Video":"Lire la vidéo","Close":"Fermer","Close Modal Dialog":"Fermer la boîte de dialogue modale","Modal Window":"Fenêtre modale","This is a modal window":"Ceci est une fenêtre modale","This modal can be closed by pressing the Escape key or activating the close button.":"Ce modal peut être fermé en appuyant sur la touche Échap ou activer le bouton de fermeture.",", opens captions settings dialog":", ouvrir les paramètres des sous-titres transcrits",", opens subtitles settings dialog":", ouvrir les paramètres des sous-titres",", opens descriptions settings dialog":", ouvrir les paramètres des descriptions",", selected":", sélectionné","captions settings":"Paramètres des sous-titres transcrits","subtitles settings":"Paramètres des sous-titres","descriptions settings":"Paramètres des descriptions","Text":"Texte","White":"Blanc","Black":"Noir","Red":"Rouge","Green":"Vert","Blue":"Bleu","Yellow":"Jaune","Magenta":"Magenta","Cyan":"Cyan","Background":"Arrière-plan","Window":"Fenêtre","Transparent":"Transparent","Semi-Transparent":"Semi-transparent","Opaque":"Opaque","Font Size":"Taille des caractères","Text Edge Style":"Style des contours du texte","None":"Aucun","Raised":"Élevé","Depressed":"Enfoncé","Uniform":"Uniforme","Dropshadow":"Ombre portée","Font Family":"Familles de polices","Proportional Sans-Serif":"Polices à chasse variable sans empattement (Proportional Sans-Serif)","Monospace Sans-Serif":"Polices à chasse fixe sans empattement (Monospace Sans-Serif)","Proportional Serif":"Polices à chasse variable avec empattement (Proportional Serif)","Monospace Serif":"Polices à chasse fixe avec empattement (Monospace Serif)","Casual":"Manuscrite","Script":"Scripte","Small Caps":"Petites capitales","Reset":"Réinitialiser","restore all settings to the default values":"Restaurer tous les paramètres aux valeurs par défaut","Done":"Terminé","Caption Settings Dialog":"Boîte de dialogue des paramètres des sous-titres transcrits","Beginning of dialog window. Escape will cancel and close the window.":"Début de la fenêtre de dialogue. La touche d'échappement annulera et fermera la fenêtre.","End of dialog window.":"Fin de la fenêtre de dialogue.","{1} is loading.":"{1} est en train de charger","Quality":"Qualité","Auto":"Auto","Speed":"Vitesse","peers":"pairs","Go to the video page":"Aller sur la page de la vidéo","Settings":"Paramètres","Uses P2P, others may know you are watching this video.":"Utilise le P2P, d'autres personnes pourraient savoir que vous regardez cette vidéo.","Copy the video URL":"Copier le lien de la vidéo","Copy the video URL at the current time":"Copier le lien de la vidéo à partir de cette séquence","Copy embed code":"Copier le code d'intégration"} \ No newline at end of file diff --git a/client/src/locale/target/player_fr.xml b/client/src/locale/target/player_fr.xml new file mode 100644 index 000000000..eafa4baff --- /dev/null +++ b/client/src/locale/target/player_fr.xml @@ -0,0 +1,379 @@ + + + + + + + Audio Player + Lecteur audio + + + Video Player + Lecteur vidéo + + + Play + Lecture + + + Pause + Pause + + + Replay + Revoir + + + Current Time + Temps actuel + + + Duration + Durée + + + Remaining Time + Temps restant + + + Stream Type + Type de flux + + + LIVE + EN DIRECT + + + Loaded + Chargé + + + Progress + Progression + + + Progress Bar + Barre de progression + + + {1} of {2} + {1} de {2} + + + Fullscreen + Plein écran + + + Non-Fullscreen + Fenêtré + + + Mute + Sourdine + + + Unmute + Son activé + + + Playback Rate + Vitesse de lecture + + + Subtitles + Sous-titres + + + subtitles off + Sous-titres désactivés + + + Captions + Sous-titres transcrits + + + captions off + Sous-titres transcrits désactivés + + + Chapters + Chapitres + + + Descriptions + Descriptions + + + descriptions off + descriptions désactivées + + + Audio Track + Piste audio + + + Volume Level + Niveau de volume + + + You aborted the media playback + Vous avez interrompu la lecture de la vidéo. + + + A network error caused the media download to fail part-way. + Une erreur de réseau a interrompu le téléchargement de la vidéo. + + + The media could not be loaded, either because the server or network failed or because the format is not supported. + Cette vidéo n'a pas pu être chargée, soit parce que le serveur ou le réseau a échoué ou parce que le format n'est pas reconnu. + + + The media playback was aborted due to a corruption problem or because the media used features your browser did not support. + La lecture de la vidéo a été interrompue à cause d'un problème de corruption ou parce que la vidéo utilise des fonctionnalités non prises en charge par votre navigateur. + + + No compatible source was found for this media. + Aucune source compatible n'a été trouvée pour cette vidéo. + + + The media is encrypted and we do not have the keys to decrypt it. + Le média est chiffré et nous n'avons pas les clés pour le déchiffrer. + + + Play Video + Lire la vidéo + + + Close + Fermer + + + Close Modal Dialog + Fermer la boîte de dialogue modale + + + Modal Window + Fenêtre modale + + + This is a modal window + Ceci est une fenêtre modale + + + This modal can be closed by pressing the Escape key or activating the close button. + Ce modal peut être fermé en appuyant sur la touche Échap ou activer le bouton de fermeture. + + + , opens captions settings dialog + , ouvrir les paramètres des sous-titres transcrits + + + , opens subtitles settings dialog + , ouvrir les paramètres des sous-titres + + + , opens descriptions settings dialog + , ouvrir les paramètres des descriptions + + + , selected + , sélectionné + + + captions settings + Paramètres des sous-titres transcrits + + + subititles settings + Paramètres des sous-titres + + + descriptions settings + Paramètres des descriptions + + + Text + Texte + + + White + Blanc + + + Black + Noir + + + Red + Rouge + + + Green + Vert + + + Blue + Bleu + + + Yellow + Jaune + + + Magenta + Magenta + + + Cyan + Cyan + + + Background + Arrière-plan + + + Window + Fenêtre + + + Transparent + Transparent + + + Semi-Transparent + Semi-transparent + + + Opaque + Opaque + + + Font Size + Taille des caractères + + + Text Edge Style + Style des contours du texte + + + None + Aucun + + + Raised + Élevé + + + Depressed + Enfoncé + + + Uniform + Uniforme + + + Dropshadow + Ombre portée + + + Font Family + Familles de polices + + + Proportional Sans-Serif + Polices à chasse variable sans empattement (Proportional Sans-Serif) + + + Monospace Sans-Serif + Polices à chasse fixe sans empattement (Monospace Sans-Serif) + + + Proportional Serif + Polices à chasse variable avec empattement (Proportional Serif) + + + Monospace Serif + Polices à chasse fixe avec empattement (Monospace Serif) + + + Casual + Manuscrite + + + Script + Scripte + + + Small Caps + Petites capitales + + + Reset + Réinitialiser + + + restore all settings to the default values + Restaurer tous les paramètres aux valeurs par défaut + + + Done + Terminé + + + Caption Settings Dialog + Boîte de dialogue des paramètres des sous-titres transcrits + + + Beginning of dialog window. Escape will cancel and close the window. + Début de la fenêtre de dialogue. La touche d'échappement annulera et fermera la fenêtre. + + + End of dialog window. + Fin de la fenêtre de dialogue. + + + {1} is loading. + {1} est en train de charger + + + Quality + Qualité + + + Auto + Auto + + + Speed + Vitesse + + + peers + pairs + + + Go to the video page + Aller sur la page de la vidéo + + + Settings + Paramètres + + + Uses P2P, others may know you are watching this video. + Utilise le P2P, d'autres personnes pourraient savoir que vous regardez cette vidéo. + + + Copy the video URL + Copier le lien de la vidéo + + + Copy the video URL at the current time + Copier le lien de la vidéo à partir de cette séquence + + + Copy embed code + Copier le code d'intégration + + + \ No newline at end of file diff --git a/client/src/standalone/videos/embed.ts b/client/src/standalone/videos/embed.ts index d603690ca..166013226 100644 --- a/client/src/standalone/videos/embed.ts +++ b/client/src/standalone/videos/embed.ts @@ -14,14 +14,14 @@ import 'core-js/es6/regexp' import 'core-js/es6/map' import 'core-js/es6/weak-map' import 'core-js/es6/set' - // For google bot that uses Chrome 41 and does not understand fetch import 'whatwg-fetch' import * as videojs from 'video.js' import { VideoDetails } from '../../../../shared' -import { getVideojsOptions } from '../../assets/player/peertube-player' +import { addContextMenu, getVideojsOptions, loadLocale } from '../../assets/player/peertube-player' +import { environment } from '../../environments/environment' function getVideoUrl (id: string) { return window.location.origin + '/api/v1/videos/' + id @@ -61,7 +61,8 @@ function videoFetchError (videoElement: HTMLVideoElement) { const urlParts = window.location.href.split('/') const videoId = urlParts[urlParts.length - 1] -loadVideoInfo(videoId) +loadLocale(environment.apiUrl, videojs, navigator.language) + .then(() => loadVideoInfo(videoId)) .then(async response => { const videoContainerId = 'video-container' const videoElement = document.getElementById(videoContainerId) as HTMLVideoElement @@ -91,7 +92,6 @@ loadVideoInfo(videoId) const videojsOptions = getVideojsOptions({ autoplay, inactivityTimeout: 1500, - videoEmbedUrl: window.location.origin + videoInfo.embedPath, videoViewUrl: getVideoUrl(videoId) + '/views', playerElement: videoElement, videoFiles: videoInfo.files, @@ -106,8 +106,10 @@ loadVideoInfo(videoId) player.dock({ title: videoInfo.name, - description: 'Uses P2P, others may know you are watching this video.' + description: player.localize('Uses P2P, others may know you are watching this video.') }) + + addContextMenu(player, window.location.origin + videoInfo.embedPath) }) }) .catch(err => console.error(err)) -- cgit v1.2.3