Localize player
This commit is contained in:
parent
550a562cec
commit
e945b184a0
23 changed files with 1049 additions and 61 deletions
|
@ -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)
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
@ -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'
|
||||
})
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { is18nLocale, isDefaultLocale } from '../../../../shared/models/i18n/i18n'
|
||||
|
||||
function toTitleCase (str: string) {
|
||||
return str.charAt(0).toUpperCase() + str.slice(1)
|
||||
}
|
||||
|
|
|
@ -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'
|
||||
|
|
378
client/src/locale/source/player_en_US.xml
Normal file
378
client/src/locale/source/player_en_US.xml
Normal file
|
@ -0,0 +1,378 @@
|
|||
<xliff xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 http://docs.oasis-open.org/xliff/v1.2/os/xliff-core-1.2-strict.xsd" xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
|
||||
<file original="namespace1" datatype="plaintext" source-language="undefined" target-language="undefined">
|
||||
<body>
|
||||
<trans-unit id="Audio Player">
|
||||
<source>Audio Player</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Video Player">
|
||||
<source>Video Player</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Play">
|
||||
<source>Play</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Pause">
|
||||
<source>Pause</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Replay">
|
||||
<source>Replay</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Current Time">
|
||||
<source>Current Time</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Duration">
|
||||
<source>Duration</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Remaining Time">
|
||||
<source>Remaining Time</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Stream Type">
|
||||
<source>Stream Type</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="LIVE">
|
||||
<source>LIVE</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Loaded">
|
||||
<source>Loaded</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Progress">
|
||||
<source>Progress</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Progress Bar">
|
||||
<source>Progress Bar</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="progress bar timing: currentTime={1} duration={2}">
|
||||
<source>{1} of {2}</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Fullscreen">
|
||||
<source>Fullscreen</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Non-Fullscreen">
|
||||
<source>Non-Fullscreen</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Mute">
|
||||
<source>Mute</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Unmute">
|
||||
<source>Unmute</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Playback Rate">
|
||||
<source>Playback Rate</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Subtitles">
|
||||
<source>Subtitles</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="subtitles off">
|
||||
<source>subtitles off</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Captions">
|
||||
<source>Captions</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="captions off">
|
||||
<source>captions off</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chapters">
|
||||
<source>Chapters</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Descriptions">
|
||||
<source>Descriptions</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="descriptions off">
|
||||
<source>descriptions off</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Audio Track">
|
||||
<source>Audio Track</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Volume Level">
|
||||
<source>Volume Level</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="You aborted the media playback">
|
||||
<source>You aborted the media playback</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="A network error caused the media download to fail part-way.">
|
||||
<source>A network error caused the media download to fail part-way.</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="The media could not be loaded, either because the server or network failed or because the format is not supported.">
|
||||
<source>The media could not be loaded, either because the server or network failed or because the format is not supported.</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="The media playback was aborted due to a corruption problem or because the media used features your browser did not support.">
|
||||
<source>The media playback was aborted due to a corruption problem or because the media used features your browser did not support.</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="No compatible source was found for this media.">
|
||||
<source>No compatible source was found for this media.</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="The media is encrypted and we do not have the keys to decrypt it.">
|
||||
<source>The media is encrypted and we do not have the keys to decrypt it.</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Play Video">
|
||||
<source>Play Video</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Close">
|
||||
<source>Close</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Close Modal Dialog">
|
||||
<source>Close Modal Dialog</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Modal Window">
|
||||
<source>Modal Window</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="This is a modal window">
|
||||
<source>This is a modal window</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="This modal can be closed by pressing the Escape key or activating the close button.">
|
||||
<source>This modal can be closed by pressing the Escape key or activating the close button.</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id=", opens captions settings dialog">
|
||||
<source>, opens captions settings dialog</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id=", opens subtitles settings dialog">
|
||||
<source>, opens subtitles settings dialog</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id=", opens descriptions settings dialog">
|
||||
<source>, opens descriptions settings dialog</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id=", selected">
|
||||
<source>, selected</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="captions settings">
|
||||
<source>captions settings</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="subtitles settings">
|
||||
<source>subititles settings</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="descriptions settings">
|
||||
<source>descriptions settings</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Text">
|
||||
<source>Text</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="White">
|
||||
<source>White</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Black">
|
||||
<source>Black</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Red">
|
||||
<source>Red</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Green">
|
||||
<source>Green</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Blue">
|
||||
<source>Blue</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Yellow">
|
||||
<source>Yellow</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Magenta">
|
||||
<source>Magenta</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Cyan">
|
||||
<source>Cyan</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Background">
|
||||
<source>Background</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Window">
|
||||
<source>Window</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Transparent">
|
||||
<source>Transparent</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Semi-Transparent">
|
||||
<source>Semi-Transparent</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Opaque">
|
||||
<source>Opaque</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Font Size">
|
||||
<source>Font Size</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Text Edge Style">
|
||||
<source>Text Edge Style</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="None">
|
||||
<source>None</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Raised">
|
||||
<source>Raised</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Depressed">
|
||||
<source>Depressed</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Uniform">
|
||||
<source>Uniform</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Dropshadow">
|
||||
<source>Dropshadow</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Font Family">
|
||||
<source>Font Family</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Proportional Sans-Serif">
|
||||
<source>Proportional Sans-Serif</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Monospace Sans-Serif">
|
||||
<source>Monospace Sans-Serif</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Proportional Serif">
|
||||
<source>Proportional Serif</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Monospace Serif">
|
||||
<source>Monospace Serif</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Casual">
|
||||
<source>Casual</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Script">
|
||||
<source>Script</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Small Caps">
|
||||
<source>Small Caps</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reset">
|
||||
<source>Reset</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="restore all settings to the default values">
|
||||
<source>restore all settings to the default values</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Done">
|
||||
<source>Done</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Caption Settings Dialog">
|
||||
<source>Caption Settings Dialog</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Beginning of dialog window. Escape will cancel and close the window.">
|
||||
<source>Beginning of dialog window. Escape will cancel and close the window.</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="End of dialog window.">
|
||||
<source>End of dialog window.</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="{1} is loading.">
|
||||
<source>{1} is loading.</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Quality">
|
||||
<source>Quality</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Auto">
|
||||
<source>Auto</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Speed">
|
||||
<source>Speed</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="peers">
|
||||
<source>peers</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Go to the video page">
|
||||
<source>Go to the video page</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Settings">
|
||||
<source>Settings</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Uses P2P, others may know you are watching this video.">
|
||||
<source>Uses P2P, others may know you are watching this video.</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Copy the video URL">
|
||||
<source>Copy the video URL</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Copy the video URL at the current time">
|
||||
<source>Copy the video URL at the current time</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Copy embed code">
|
||||
<source>Copy embed code</source>
|
||||
<target>undefined</target>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
85
client/src/locale/source/videojs_en_US.json
Normal file
85
client/src/locale/source/videojs_en_US.json
Normal file
|
@ -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."
|
||||
}
|
1
client/src/locale/target/player_fr.json
Normal file
1
client/src/locale/target/player_fr.json
Normal file
|
@ -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"}
|
379
client/src/locale/target/player_fr.xml
Normal file
379
client/src/locale/target/player_fr.xml
Normal file
|
@ -0,0 +1,379 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--XLIFF document generated by Zanata. Visit http://zanata.org for more infomation.-->
|
||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.1" xmlns:xyz="urn:appInfo:Items" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.1 http://www.oasis-open.org/committees/xliff/documents/xliff-core-1.1.xsd" version="1.1">
|
||||
<file source-language="en-US" datatype="plaintext" original="" target-language="fr">
|
||||
<body>
|
||||
<trans-unit id="Audio Player">
|
||||
<source>Audio Player</source>
|
||||
<target>Lecteur audio</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Video Player">
|
||||
<source>Video Player</source>
|
||||
<target>Lecteur vidéo</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Play">
|
||||
<source>Play</source>
|
||||
<target>Lecture</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Pause">
|
||||
<source>Pause</source>
|
||||
<target>Pause</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Replay">
|
||||
<source>Replay</source>
|
||||
<target>Revoir</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Current Time">
|
||||
<source>Current Time</source>
|
||||
<target>Temps actuel</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Duration">
|
||||
<source>Duration</source>
|
||||
<target>Durée</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Remaining Time">
|
||||
<source>Remaining Time</source>
|
||||
<target>Temps restant</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Stream Type">
|
||||
<source>Stream Type</source>
|
||||
<target>Type de flux</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="LIVE">
|
||||
<source>LIVE</source>
|
||||
<target>EN DIRECT</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Loaded">
|
||||
<source>Loaded</source>
|
||||
<target>Chargé</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Progress">
|
||||
<source>Progress</source>
|
||||
<target>Progression</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Progress Bar">
|
||||
<source>Progress Bar</source>
|
||||
<target>Barre de progression</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="progress bar timing: currentTime={1} duration={2}">
|
||||
<source>{1} of {2}</source>
|
||||
<target>{1} de {2}</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Fullscreen">
|
||||
<source>Fullscreen</source>
|
||||
<target>Plein écran</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Non-Fullscreen">
|
||||
<source>Non-Fullscreen</source>
|
||||
<target>Fenêtré</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Mute">
|
||||
<source>Mute</source>
|
||||
<target>Sourdine</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Unmute">
|
||||
<source>Unmute</source>
|
||||
<target>Son activé</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Playback Rate">
|
||||
<source>Playback Rate</source>
|
||||
<target>Vitesse de lecture</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Subtitles">
|
||||
<source>Subtitles</source>
|
||||
<target>Sous-titres</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="subtitles off">
|
||||
<source>subtitles off</source>
|
||||
<target>Sous-titres désactivés</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Captions">
|
||||
<source>Captions</source>
|
||||
<target>Sous-titres transcrits</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="captions off">
|
||||
<source>captions off</source>
|
||||
<target>Sous-titres transcrits désactivés</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Chapters">
|
||||
<source>Chapters</source>
|
||||
<target>Chapitres</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Descriptions">
|
||||
<source>Descriptions</source>
|
||||
<target>Descriptions</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="descriptions off">
|
||||
<source>descriptions off</source>
|
||||
<target>descriptions désactivées</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Audio Track">
|
||||
<source>Audio Track</source>
|
||||
<target>Piste audio</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Volume Level">
|
||||
<source>Volume Level</source>
|
||||
<target>Niveau de volume</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="You aborted the media playback">
|
||||
<source>You aborted the media playback</source>
|
||||
<target>Vous avez interrompu la lecture de la vidéo.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="A network error caused the media download to fail part-way.">
|
||||
<source>A network error caused the media download to fail part-way.</source>
|
||||
<target>Une erreur de réseau a interrompu le téléchargement de la vidéo.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="The media could not be loaded, either because the server or network failed or because the format is not supported.">
|
||||
<source>The media could not be loaded, either because the server or network failed or because the format is not supported.</source>
|
||||
<target>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.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="The media playback was aborted due to a corruption problem or because the media used features your browser did not support.">
|
||||
<source>The media playback was aborted due to a corruption problem or because the media used features your browser did not support.</source>
|
||||
<target>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.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="No compatible source was found for this media.">
|
||||
<source>No compatible source was found for this media.</source>
|
||||
<target>Aucune source compatible n'a été trouvée pour cette vidéo.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="The media is encrypted and we do not have the keys to decrypt it.">
|
||||
<source>The media is encrypted and we do not have the keys to decrypt it.</source>
|
||||
<target>Le média est chiffré et nous n'avons pas les clés pour le déchiffrer.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Play Video">
|
||||
<source>Play Video</source>
|
||||
<target>Lire la vidéo</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Close">
|
||||
<source>Close</source>
|
||||
<target>Fermer</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Close Modal Dialog">
|
||||
<source>Close Modal Dialog</source>
|
||||
<target>Fermer la boîte de dialogue modale</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Modal Window">
|
||||
<source>Modal Window</source>
|
||||
<target>Fenêtre modale</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="This is a modal window">
|
||||
<source>This is a modal window</source>
|
||||
<target>Ceci est une fenêtre modale</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="This modal can be closed by pressing the Escape key or activating the close button.">
|
||||
<source>This modal can be closed by pressing the Escape key or activating the close button.</source>
|
||||
<target>Ce modal peut être fermé en appuyant sur la touche Échap ou activer le bouton de fermeture.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id=", opens captions settings dialog">
|
||||
<source>, opens captions settings dialog</source>
|
||||
<target>, ouvrir les paramètres des sous-titres transcrits</target>
|
||||
</trans-unit>
|
||||
<trans-unit id=", opens subtitles settings dialog">
|
||||
<source>, opens subtitles settings dialog</source>
|
||||
<target>, ouvrir les paramètres des sous-titres</target>
|
||||
</trans-unit>
|
||||
<trans-unit id=", opens descriptions settings dialog">
|
||||
<source>, opens descriptions settings dialog</source>
|
||||
<target>, ouvrir les paramètres des descriptions</target>
|
||||
</trans-unit>
|
||||
<trans-unit id=", selected">
|
||||
<source>, selected</source>
|
||||
<target>, sélectionné</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="captions settings">
|
||||
<source>captions settings</source>
|
||||
<target>Paramètres des sous-titres transcrits</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="subtitles settings">
|
||||
<source>subititles settings</source>
|
||||
<target>Paramètres des sous-titres</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="descriptions settings">
|
||||
<source>descriptions settings</source>
|
||||
<target>Paramètres des descriptions</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Text">
|
||||
<source>Text</source>
|
||||
<target>Texte</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="White">
|
||||
<source>White</source>
|
||||
<target>Blanc</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Black">
|
||||
<source>Black</source>
|
||||
<target>Noir</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Red">
|
||||
<source>Red</source>
|
||||
<target>Rouge</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Green">
|
||||
<source>Green</source>
|
||||
<target>Vert</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Blue">
|
||||
<source>Blue</source>
|
||||
<target>Bleu</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Yellow">
|
||||
<source>Yellow</source>
|
||||
<target>Jaune</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Magenta">
|
||||
<source>Magenta</source>
|
||||
<target>Magenta</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Cyan">
|
||||
<source>Cyan</source>
|
||||
<target>Cyan</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Background">
|
||||
<source>Background</source>
|
||||
<target>Arrière-plan</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Window">
|
||||
<source>Window</source>
|
||||
<target>Fenêtre</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Transparent">
|
||||
<source>Transparent</source>
|
||||
<target>Transparent</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Semi-Transparent">
|
||||
<source>Semi-Transparent</source>
|
||||
<target>Semi-transparent</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Opaque">
|
||||
<source>Opaque</source>
|
||||
<target>Opaque</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Font Size">
|
||||
<source>Font Size</source>
|
||||
<target>Taille des caractères</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Text Edge Style">
|
||||
<source>Text Edge Style</source>
|
||||
<target>Style des contours du texte</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="None">
|
||||
<source>None</source>
|
||||
<target>Aucun</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Raised">
|
||||
<source>Raised</source>
|
||||
<target>Élevé</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Depressed">
|
||||
<source>Depressed</source>
|
||||
<target>Enfoncé</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Uniform">
|
||||
<source>Uniform</source>
|
||||
<target>Uniforme</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Dropshadow">
|
||||
<source>Dropshadow</source>
|
||||
<target>Ombre portée</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Font Family">
|
||||
<source>Font Family</source>
|
||||
<target>Familles de polices</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Proportional Sans-Serif">
|
||||
<source>Proportional Sans-Serif</source>
|
||||
<target>Polices à chasse variable sans empattement (Proportional Sans-Serif)</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Monospace Sans-Serif">
|
||||
<source>Monospace Sans-Serif</source>
|
||||
<target>Polices à chasse fixe sans empattement (Monospace Sans-Serif)</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Proportional Serif">
|
||||
<source>Proportional Serif</source>
|
||||
<target>Polices à chasse variable avec empattement (Proportional Serif)</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Monospace Serif">
|
||||
<source>Monospace Serif</source>
|
||||
<target>Polices à chasse fixe avec empattement (Monospace Serif)</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Casual">
|
||||
<source>Casual</source>
|
||||
<target>Manuscrite</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Script">
|
||||
<source>Script</source>
|
||||
<target>Scripte</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Small Caps">
|
||||
<source>Small Caps</source>
|
||||
<target>Petites capitales</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Reset">
|
||||
<source>Reset</source>
|
||||
<target>Réinitialiser</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="restore all settings to the default values">
|
||||
<source>restore all settings to the default values</source>
|
||||
<target>Restaurer tous les paramètres aux valeurs par défaut</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Done">
|
||||
<source>Done</source>
|
||||
<target>Terminé</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Caption Settings Dialog">
|
||||
<source>Caption Settings Dialog</source>
|
||||
<target>Boîte de dialogue des paramètres des sous-titres transcrits</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Beginning of dialog window. Escape will cancel and close the window.">
|
||||
<source>Beginning of dialog window. Escape will cancel and close the window.</source>
|
||||
<target>Début de la fenêtre de dialogue. La touche d'échappement annulera et fermera la fenêtre.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="End of dialog window.">
|
||||
<source>End of dialog window.</source>
|
||||
<target>Fin de la fenêtre de dialogue.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="{1} is loading.">
|
||||
<source>{1} is loading.</source>
|
||||
<target>{1} est en train de charger</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Quality">
|
||||
<source>Quality</source>
|
||||
<target>Qualité</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Auto">
|
||||
<source>Auto</source>
|
||||
<target>Auto</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Speed">
|
||||
<source>Speed</source>
|
||||
<target>Vitesse</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="peers">
|
||||
<source>peers</source>
|
||||
<target>pairs</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Go to the video page">
|
||||
<source>Go to the video page</source>
|
||||
<target>Aller sur la page de la vidéo</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Settings">
|
||||
<source>Settings</source>
|
||||
<target>Paramètres</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Uses P2P, others may know you are watching this video.">
|
||||
<source>Uses P2P, others may know you are watching this video.</source>
|
||||
<target>Utilise le P2P, d'autres personnes pourraient savoir que vous regardez cette vidéo.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Copy the video URL">
|
||||
<source>Copy the video URL</source>
|
||||
<target>Copier le lien de la vidéo</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Copy the video URL at the current time">
|
||||
<source>Copy the video URL at the current time</source>
|
||||
<target>Copier le lien de la vidéo à partir de cette séquence</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="Copy embed code">
|
||||
<source>Copy embed code</source>
|
||||
<target>Copier le code d'intégration</target>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file></xliff>
|
|
@ -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))
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
"danger:clean:prod": "scripty",
|
||||
"danger:clean:modules": "scripty",
|
||||
"i18n:generate": "scripty",
|
||||
"i18n:xliff2json": "node ./dist/scripts/i18n/xliff2json.js",
|
||||
"i18n:create-custom-files": "node ./dist/scripts/i18n/create-custom-files.js",
|
||||
"reset-password": "node ./dist/scripts/reset-password.js",
|
||||
"play": "scripty",
|
||||
"dev": "scripty",
|
||||
|
@ -174,6 +176,7 @@
|
|||
"tslint-config-standard": "^7.0.0",
|
||||
"typescript": "^2.5.2",
|
||||
"webtorrent": "^0.100.0",
|
||||
"xliff": "^3.0.1",
|
||||
"youtube-dl": "^1.12.2"
|
||||
},
|
||||
"scripty": {
|
||||
|
|
49
scripts/i18n/create-custom-files.ts
Executable file
49
scripts/i18n/create-custom-files.ts
Executable file
|
@ -0,0 +1,49 @@
|
|||
import * as jsToXliff12 from 'xliff/jsToXliff12'
|
||||
import { writeFile } from 'fs'
|
||||
import { join } from 'path'
|
||||
|
||||
// First, the player
|
||||
const playerSource = join(__dirname, '../../../client/src/locale/source/videojs_en_US.json')
|
||||
const playerTarget = join(__dirname, '../../../client/src/locale/source/player_en_US.xml')
|
||||
|
||||
const videojs = require(playerSource)
|
||||
const playerKeys = {
|
||||
'Quality': 'Quality',
|
||||
'Auto': 'Auto',
|
||||
'Speed': 'Speed',
|
||||
'peers': 'peers',
|
||||
'Go to the video page': 'Go to the video page',
|
||||
'Settings': 'Settings',
|
||||
'Uses P2P, others may know you are watching this video.': 'Uses P2P, others may know you are watching this video.',
|
||||
'Copy the video URL': 'Copy the video URL',
|
||||
'Copy the video URL at the current time': 'Copy the video URL at the current time',
|
||||
'Copy embed code': 'Copy embed code'
|
||||
}
|
||||
|
||||
const obj = {
|
||||
resources: {
|
||||
namespace1: {}
|
||||
}
|
||||
}
|
||||
|
||||
for (const sourceObject of [ videojs, playerKeys ]) {
|
||||
Object.keys(sourceObject).forEach(k => obj.resources.namespace1[ k ] = { source: sourceObject[ k ] })
|
||||
}
|
||||
|
||||
jsToXliff12(obj, (err, res) => {
|
||||
if (err) {
|
||||
console.error(err)
|
||||
process.exit(-1)
|
||||
}
|
||||
|
||||
writeFile(playerTarget, res, err => {
|
||||
if (err) {
|
||||
console.error(err)
|
||||
process.exit(-1)
|
||||
}
|
||||
|
||||
process.exit(0)
|
||||
})
|
||||
})
|
||||
|
||||
// Then, the server strings
|
|
@ -9,4 +9,8 @@ npm run ngx-extractor -- --locale "en-US" -i 'src/**/*.ts' -f xlf -o src/locale/
|
|||
# Zanata does not support inner elements in <source>, so we hack these special elements
|
||||
# This regex translate the Angular elements to special entities (that we will reconvert on pull)
|
||||
#sed -i 's/<x id=\(.\+\?\)\/>/\<x id=\1\/\>/g' src/locale/source/messages_en_US.xml
|
||||
perl -pi -e 's|<x id=(.+?)/>|<x id=\1/>|g' src/locale/source/messages_en_US.xml
|
||||
perl -pi -e 's|<x id=(.+?)/>|<x id=\1/>|g' src/locale/source/messages_en_US.xml
|
||||
|
||||
# Add our strings too
|
||||
cd ../
|
||||
npm run i18n:create-custom-files
|
|
@ -7,5 +7,7 @@ set -eu
|
|||
#sed -i 's/\<x id=\(.\+\?\)\/\>/<x id=\1\/>/g' client/src/locale/target/*
|
||||
|
||||
for i in 1 2 3; do
|
||||
perl -pi -e 's|<x id=(.+?)/>([^"])|<x id=\1/>\2|g' client/src/locale/target/*
|
||||
done
|
||||
perl -pi -e 's|<x id=(.+?)/>([^"])|<x id=\1/>\2|g' client/src/locale/target/*.xml
|
||||
done
|
||||
|
||||
npm run i18n:xliff2json
|
42
scripts/i18n/xliff2json.ts
Executable file
42
scripts/i18n/xliff2json.ts
Executable file
|
@ -0,0 +1,42 @@
|
|||
import * as xliff12ToJs from 'xliff/xliff12ToJs'
|
||||
import { readFileSync, writeFile } from 'fs'
|
||||
import { join } from 'path'
|
||||
|
||||
// First, the player
|
||||
const playerSource = join(__dirname, '../../../client/src/locale/target/player_fr.xml')
|
||||
const playerTarget = join(__dirname, '../../../client/src/locale/target/player_fr.json')
|
||||
|
||||
// Remove the two first lines our xliff module does not like
|
||||
let playerFile = readFileSync(playerSource).toString()
|
||||
playerFile = removeFirstLine(playerFile)
|
||||
playerFile = removeFirstLine(playerFile)
|
||||
|
||||
xliff12ToJs(playerFile, (err, res) => {
|
||||
if (err) {
|
||||
console.error(err)
|
||||
process.exit(-1)
|
||||
}
|
||||
|
||||
const json = createJSONString(res)
|
||||
writeFile(playerTarget, json, err => {
|
||||
if (err) {
|
||||
console.error(err)
|
||||
process.exit(-1)
|
||||
}
|
||||
|
||||
process.exit(0)
|
||||
})
|
||||
})
|
||||
|
||||
function removeFirstLine (str: string) {
|
||||
return str.substring(str.indexOf('\n') + 1)
|
||||
}
|
||||
|
||||
function createJSONString (obj: any) {
|
||||
const res: any = {}
|
||||
const strings = obj.resources['']
|
||||
|
||||
Object.keys(strings).forEach(k => res[k] = strings[k].target)
|
||||
|
||||
return JSON.stringify(res)
|
||||
}
|
|
@ -2,6 +2,11 @@
|
|||
|
||||
set -eu
|
||||
|
||||
# Copy locales
|
||||
mkdir -p "./client/dist"
|
||||
rm -r "./client/dist/locale"
|
||||
cp -r "./client/src/locale/target" "./client/dist/locale"
|
||||
|
||||
NODE_ENV=test concurrently -k \
|
||||
"npm run tsc -- --sourceMap && npm run nodemon -- --delay 2 --watch ./dist dist/server" \
|
||||
"npm run tsc -- --sourceMap --preserveWatchOutput -w"
|
||||
|
|
|
@ -47,6 +47,14 @@ for (const staticClientFile of staticClientFiles) {
|
|||
clientsRouter.use('/client', express.static(distPath, { maxAge: STATIC_MAX_AGE }))
|
||||
clientsRouter.use('/client/assets/images', express.static(assetsImagesPath, { maxAge: STATIC_MAX_AGE }))
|
||||
|
||||
clientsRouter.use('/client/locales/:locale/:file.json', function (req, res) {
|
||||
if (req.params.locale === 'fr' && req.params.file === 'player') {
|
||||
return res.sendFile(join(__dirname, '../../../client/dist/locale/player_fr.json'))
|
||||
}
|
||||
|
||||
return res.sendStatus(404)
|
||||
})
|
||||
|
||||
// 404 for static files not found
|
||||
clientsRouter.use('/client/*', (req: express.Request, res: express.Response, next: express.NextFunction) => {
|
||||
res.sendStatus(404)
|
||||
|
|
|
@ -7,6 +7,10 @@ export function getDefaultLocale () {
|
|||
return 'en-US'
|
||||
}
|
||||
|
||||
export function isDefaultLocale (locale: string) {
|
||||
return locale === getDefaultLocale()
|
||||
}
|
||||
|
||||
const possiblePaths = Object.keys(I18N_LOCALES).map(l => '/' + l)
|
||||
export function is18nPath (path: string) {
|
||||
return possiblePaths.indexOf(path) !== -1
|
||||
|
|
12
yarn.lock
12
yarn.lock
|
@ -8402,6 +8402,18 @@ xhr2@^0.1.4:
|
|||
version "0.1.4"
|
||||
resolved "https://registry.yarnpkg.com/xhr2/-/xhr2-0.1.4.tgz#7f87658847716db5026323812f818cadab387a5f"
|
||||
|
||||
xliff@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/xliff/-/xliff-3.0.1.tgz#ea0f5840011727aecbddf111e5c26d8590dcca9b"
|
||||
dependencies:
|
||||
xml-js "1.6.2"
|
||||
|
||||
xml-js@1.6.2:
|
||||
version "1.6.2"
|
||||
resolved "https://registry.yarnpkg.com/xml-js/-/xml-js-1.6.2.tgz#4c4cb8413998f73701a202a1b8b2f17c985a72c5"
|
||||
dependencies:
|
||||
sax "^1.2.4"
|
||||
|
||||
xml-name-validator@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a"
|
||||
|
|
Loading…
Reference in a new issue