From ed4af258de7dc7ecc5791ade58d28f4f1e55399c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20=C5=A0?= Date: Wed, 21 Nov 2018 16:00:40 +0100 Subject: [PATCH 1/8] Add support for translations (fix sampotts/plyr#1261) --- src/js/config/defaults.js | 50 ++++---------------------------------- src/js/utils/i18n.js | 18 ++++++++++++++ src/locales/en.js | 51 +++++++++++++++++++++++++++++++++++++++ src/locales/index.js | 11 +++++++++ 4 files changed, 85 insertions(+), 45 deletions(-) create mode 100644 src/locales/en.js create mode 100644 src/locales/index.js diff --git a/src/js/config/defaults.js b/src/js/config/defaults.js index c3f97eee1..b733ed477 100644 --- a/src/js/config/defaults.js +++ b/src/js/config/defaults.js @@ -57,6 +57,9 @@ const defaults = { // Disable the standard context menu disableContextMenu: true, + // Language + language: 'en', + // Sprite (for icons) loadSprite: true, iconPrefix: 'plyr', @@ -138,51 +141,8 @@ const defaults = { ], settings: ['captions', 'quality', 'speed'], - // Localisation - i18n: { - restart: 'Restart', - rewind: 'Rewind {seektime}s', - play: 'Play', - pause: 'Pause', - fastForward: 'Forward {seektime}s', - seek: 'Seek', - seekLabel: '{currentTime} of {duration}', - played: 'Played', - buffered: 'Buffered', - currentTime: 'Current time', - duration: 'Duration', - volume: 'Volume', - mute: 'Mute', - unmute: 'Unmute', - enableCaptions: 'Enable captions', - disableCaptions: 'Disable captions', - download: 'Download', - enterFullscreen: 'Enter fullscreen', - exitFullscreen: 'Exit fullscreen', - frameTitle: 'Player for {title}', - captions: 'Captions', - settings: 'Settings', - menuBack: 'Go back to previous menu', - speed: 'Speed', - normal: 'Normal', - quality: 'Quality', - loop: 'Loop', - start: 'Start', - end: 'End', - all: 'All', - reset: 'Reset', - disabled: 'Disabled', - enabled: 'Enabled', - advertisement: 'Ad', - qualityBadge: { - 2160: '4K', - 1440: 'HD', - 1080: 'HD', - 720: 'HD', - 576: 'SD', - 480: 'SD', - }, - }, + // Custom localisation + i18n: {}, // URLs urls: { diff --git a/src/js/utils/i18n.js b/src/js/utils/i18n.js index 758ed695a..b6e7f6e48 100644 --- a/src/js/utils/i18n.js +++ b/src/js/utils/i18n.js @@ -5,6 +5,7 @@ import is from './is'; import { getDeep } from './objects'; import { replaceAll } from './strings'; +import languages from '../../locales'; // Skip i18n for abbreviations and brand names const resources = { @@ -21,6 +22,23 @@ const i18n = { return ''; } + const english = languages.filter(function (elem) { + return elem.code == 'en'; + } + ); + + const locale = languages.filter(function (elem) { + return !is.empty(config.language) && + elem.code == config.language; + } + ); + + if (!is.empty(locale)) { + config.i18n = Object.assign({}, english[0].i18n, locale[0].i18n, config.i18n); + } else { + config.i18n = Object.assign({}, english[0].i18n, config.i18n); + } + let string = getDeep(config.i18n, key); if (is.empty(string)) { diff --git a/src/locales/en.js b/src/locales/en.js new file mode 100644 index 000000000..faa7f54ba --- /dev/null +++ b/src/locales/en.js @@ -0,0 +1,51 @@ +// ========================================================================== +// Plyr English translation +// ========================================================================== + +const i18n = { + restart: 'Restart', + rewind: 'Rewind {seektime}s', + play: 'Play', + pause: 'Pause', + fastForward: 'Forward {seektime}s', + seek: 'Seek', + seekLabel: '{currentTime} of {duration}', + played: 'Played', + buffered: 'Buffered', + currentTime: 'Current time', + duration: 'Duration', + volume: 'Volume', + mute: 'Mute', + unmute: 'Unmute', + enableCaptions: 'Enable captions', + disableCaptions: 'Disable captions', + download: 'Download', + enterFullscreen: 'Enter fullscreen', + exitFullscreen: 'Exit fullscreen', + frameTitle: 'Player for {title}', + captions: 'Captions', + settings: 'Settings', + menuBack: 'Go back to previous menu', + speed: 'Speed', + normal: 'Normal', + quality: 'Quality', + loop: 'Loop', + start: 'Start', + end: 'End', + all: 'All', + reset: 'Reset', + disabled: 'Disabled', + enabled: 'Enabled', + advertisement: 'Ad', + qualityBadge: { + '480': 'SD', + '576': 'SD', + '720': 'HD', + '1080': 'HD', + '1440': 'HD', + '2160': '4K', + }, +}; + +export default i18n; + diff --git a/src/locales/index.js b/src/locales/index.js new file mode 100644 index 000000000..4c2077cc2 --- /dev/null +++ b/src/locales/index.js @@ -0,0 +1,11 @@ +// ========================================================================== +// Plyr supported languages +// ========================================================================== + +import en from './en'; + +const languages = [ + { code: 'en', name: 'English', i18n: en }, +]; + +export default languages; From 58feff7ae2720cd1a0a058f26379a56be9319f7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20=C5=A0?= Date: Wed, 21 Nov 2018 16:01:56 +0100 Subject: [PATCH 2/8] Add support for building translations --- gulpfile.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gulpfile.js b/gulpfile.js index 5a3c24784..7e4f8678a 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -43,7 +43,7 @@ const paths = { // Source paths src: { sass: path.join(root, 'src/sass/**/*.scss'), - js: path.join(root, 'src/js/**/*.js'), + js: path.join(root, 'src/{js,locales}/**/*.js'), sprite: path.join(root, 'src/sprite/*.svg'), }, From 946ff371d00baf15463e5077b863ac90bfb526ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20=C5=A0?= Date: Wed, 21 Nov 2018 16:22:33 +0100 Subject: [PATCH 3/8] Add documentation for translations --- contributing.md | 13 +++++++++++++ readme.md | 9 ++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/contributing.md b/contributing.md index 5759fb048..6d6e77c74 100644 --- a/contributing.md +++ b/contributing.md @@ -11,6 +11,7 @@ If these doesn't answer your question * Use [our Slack](https://bit.ly/plyr-chat) if you need help using Plyr or have questions about Plyr. ## Commenting + When commenting, keep a civil tone and stay on topic. Don't ask for [support](#support), or post "+1" or "I agree" type of comments. Use the emojis instead. Asking for the status on issues is discouraged. Unless someone has explicitly said in an issue that it's work in progress, most likely that means no one is working on it. We have a lot to do, and it may not be a top priority for us. @@ -38,3 +39,15 @@ Please follow the instructions in our issue templates. Don't use github issues t * When finished, push the changes to your GitHub repository and send a pull request to **develop**. Describe what your PR does. * If the Travis build fails, or if you get a code review with change requests, you can fix these by pushing new or rebased commits to the branch. + +## Contributing translations + +* Fork Plyr, and create a new branch in your fork, based on the **develop** branch + +* Make and translate language file `src/locales/{lang}.js`, where `{lang}` is two-letter language code from [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes). It is recommended to copy and edit English translation. + +* Add your language to `src/locales/index.js`. Make sure to import your file and follow the file format. The entry `name` should be native name of language. + +* Test your changes. + +* When finished, commit and push the changes to your GitHub repository and send a pull request to **develop**. diff --git a/readme.md b/readme.md index 281ddd3fc..8a89eb935 100644 --- a/readme.md +++ b/readme.md @@ -21,11 +21,11 @@ A simple, lightweight, accessible and customizable HTML5, YouTube and Vimeo medi - **[Events](#events)** - no messing around with Vimeo and YouTube APIs, all events are standardized across formats - **[Fullscreen](#fullscreen)** - supports native fullscreen with fallback to "full window" modes - **[Shortcuts](#shortcuts)** - supports keyboard shortcuts +- **[Internationalization (i18n)](#internationalization)** - supports internationalization of controls - **Picture-in-Picture** - supports Safari's picture-in-picture mode - **Playsinline** - supports the `playsinline` attribute - **Speed controls** - adjust speed on the fly - **Multiple captions** - support for multiple caption tracks -- **i18n support** - support for internationalization of controls - **No dependencies** - written in "vanilla" ES6 JavaScript, no jQuery required - **SASS** - to include in your build processes @@ -286,6 +286,7 @@ Note the single quotes encapsulating the JSON and double quotes on the object ke | `debug` | Boolean | `false` | Display debugging information in the console | | `controls` | Array, Function or Element | `['play-large', 'play', 'progress', 'current-time', 'mute', 'volume', 'captions', 'settings', 'pip', 'airplay', 'fullscreen']` | If a function is passed, it is assumed your method will return either an element or HTML string for the controls. Three arguments will be passed to your function; `id` (the unique id for the player), `seektime` (the seektime step in seconds), and `title` (the media title). See [controls.md](controls.md) for more info on how the html needs to be structured. | | `settings` | Array | `['captions', 'quality', 'speed', 'loop']` | If you're using the default controls are used then you can specify which settings to show in the menu | +| `language` | String | `en` | Language code (ISO 639-1) for UI internationalization. | | `i18n` | Object | See [defaults.js](/src/js/config/defaults.js) | Used for internationalization (i18n) of the text within the UI. | | `loadSprite` | Boolean | `true` | Load the SVG sprite specified as the `iconUrl` option (if a URL). If `false`, it is assumed you are handling sprite loading yourself. | | `iconUrl` | String | `null` | Specify a URL or path to the SVG sprite. See the [SVG section](#svg) for more info. | @@ -619,6 +620,12 @@ document then the shortcuts will work when any element has focus, apart from an Fullscreen in Plyr is supported by all browsers that [currently support it](http://caniuse.com/#feat=fullscreen). +## Internationalization + +Internationalization (i18n) language could be specified with `language` option. It will translate all controls in Plyr. If the language is not specified, it will default to English. + +If you want custom internationalization values, you should specify them to `i18n` option. + ## Browser support Plyr supports the last 2 versions of most _modern_ browsers. From ac219bea13705662ebc5666ee1ee8692ff712895 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20=C5=A0?= Date: Wed, 21 Nov 2018 16:50:46 +0100 Subject: [PATCH 4/8] Add Slovenian translation --- src/locales/index.js | 2 ++ src/locales/sl.js | 51 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 src/locales/sl.js diff --git a/src/locales/index.js b/src/locales/index.js index 4c2077cc2..77d552f7c 100644 --- a/src/locales/index.js +++ b/src/locales/index.js @@ -3,9 +3,11 @@ // ========================================================================== import en from './en'; +import sl from './sl'; const languages = [ { code: 'en', name: 'English', i18n: en }, + { code: 'sl', name: 'Slovenščina', i18n: sl }, ]; export default languages; diff --git a/src/locales/sl.js b/src/locales/sl.js new file mode 100644 index 000000000..653e66955 --- /dev/null +++ b/src/locales/sl.js @@ -0,0 +1,51 @@ +// ========================================================================== +// Plyr Slovenian translation +// ========================================================================== + +const i18n = { + restart: 'Ponovno predvajaj', + rewind: 'Nazaj za {seektime} sekund', + play: 'Predvajaj', + pause: 'Zaustavi', + fastForward: 'Naprej za {seektime} sekund', + seek: 'Pojdi', + seekLabel: '{currentTime} od {duration}', + played: 'Predvajano', + buffered: 'Predpomnjeno', + currentTime: 'Čas', + duration: 'Dolžina', + volume: 'Glasnost', + mute: 'Izklopi zvok', + unmute: 'Vklopi zvok', + enableCaptions: 'Omogoči podnapise', + disableCaptions: 'Onemogoči podnapise', + download: 'Prenesi', + enterFullscreen: 'Odpri celozaslonski način', + exitFullscreen: 'Zapri celozaslonski način', + frameTitle: 'Predvajalnik za {title}', + captions: 'Podnapisi', + settings: 'Nastavitve', + menuBack: 'Pojdi nazaj v prejšnji meni', + speed: 'Hitrost', + normal: 'Običajna', + quality: 'Kakovost', + loop: 'Zanka', + start: 'Začetek', + end: 'Konec', + all: 'Vse', + reset: 'Ponastavi', + disabled: 'Onemogočeni', + enabled: 'Omogočeni', + advertisement: 'Oglas', + qualityBadge: { + '480': 'SD', + '576': 'SD', + '720': 'HD', + '1080': 'HD', + '1440': 'HD', + '2160': '4K', + }, +}; + +export default i18n; + From 78721fb03fcc42c68e8603883f6ad966925ad238 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20=C5=A0?= Date: Sat, 8 Dec 2018 11:37:14 +0000 Subject: [PATCH 5/8] Coding style fixes --- src/js/utils/i18n.js | 12 ++----- src/locales/en.js | 84 ++++++++++++++++++++++---------------------- src/locales/sl.js | 84 ++++++++++++++++++++++---------------------- 3 files changed, 86 insertions(+), 94 deletions(-) diff --git a/src/js/utils/i18n.js b/src/js/utils/i18n.js index b6e7f6e48..64cba88d4 100644 --- a/src/js/utils/i18n.js +++ b/src/js/utils/i18n.js @@ -22,16 +22,8 @@ const i18n = { return ''; } - const english = languages.filter(function (elem) { - return elem.code == 'en'; - } - ); - - const locale = languages.filter(function (elem) { - return !is.empty(config.language) && - elem.code == config.language; - } - ); + const english = languages.filter(e => e.code === 'en'); + const locale = languages.filter(e => !is.empty(config.language) && e.code === config.language); if (!is.empty(locale)) { config.i18n = Object.assign({}, english[0].i18n, locale[0].i18n, config.i18n); diff --git a/src/locales/en.js b/src/locales/en.js index faa7f54ba..56cf23bcc 100644 --- a/src/locales/en.js +++ b/src/locales/en.js @@ -3,48 +3,48 @@ // ========================================================================== const i18n = { - restart: 'Restart', - rewind: 'Rewind {seektime}s', - play: 'Play', - pause: 'Pause', - fastForward: 'Forward {seektime}s', - seek: 'Seek', - seekLabel: '{currentTime} of {duration}', - played: 'Played', - buffered: 'Buffered', - currentTime: 'Current time', - duration: 'Duration', - volume: 'Volume', - mute: 'Mute', - unmute: 'Unmute', - enableCaptions: 'Enable captions', - disableCaptions: 'Disable captions', - download: 'Download', - enterFullscreen: 'Enter fullscreen', - exitFullscreen: 'Exit fullscreen', - frameTitle: 'Player for {title}', - captions: 'Captions', - settings: 'Settings', - menuBack: 'Go back to previous menu', - speed: 'Speed', - normal: 'Normal', - quality: 'Quality', - loop: 'Loop', - start: 'Start', - end: 'End', - all: 'All', - reset: 'Reset', - disabled: 'Disabled', - enabled: 'Enabled', - advertisement: 'Ad', - qualityBadge: { - '480': 'SD', - '576': 'SD', - '720': 'HD', - '1080': 'HD', - '1440': 'HD', - '2160': '4K', - }, + restart: 'Restart', + rewind: 'Rewind {seektime}s', + play: 'Play', + pause: 'Pause', + fastForward: 'Forward {seektime}s', + seek: 'Seek', + seekLabel: '{currentTime} of {duration}', + played: 'Played', + buffered: 'Buffered', + currentTime: 'Current time', + duration: 'Duration', + volume: 'Volume', + mute: 'Mute', + unmute: 'Unmute', + enableCaptions: 'Enable captions', + disableCaptions: 'Disable captions', + download: 'Download', + enterFullscreen: 'Enter fullscreen', + exitFullscreen: 'Exit fullscreen', + frameTitle: 'Player for {title}', + captions: 'Captions', + settings: 'Settings', + menuBack: 'Go back to previous menu', + speed: 'Speed', + normal: 'Normal', + quality: 'Quality', + loop: 'Loop', + start: 'Start', + end: 'End', + all: 'All', + reset: 'Reset', + disabled: 'Disabled', + enabled: 'Enabled', + advertisement: 'Ad', + qualityBadge: { + '480': 'SD', + '576': 'SD', + '720': 'HD', + '1080': 'HD', + '1440': 'HD', + '2160': '4K', + }, }; export default i18n; diff --git a/src/locales/sl.js b/src/locales/sl.js index 653e66955..ce40d763d 100644 --- a/src/locales/sl.js +++ b/src/locales/sl.js @@ -3,48 +3,48 @@ // ========================================================================== const i18n = { - restart: 'Ponovno predvajaj', - rewind: 'Nazaj za {seektime} sekund', - play: 'Predvajaj', - pause: 'Zaustavi', - fastForward: 'Naprej za {seektime} sekund', - seek: 'Pojdi', - seekLabel: '{currentTime} od {duration}', - played: 'Predvajano', - buffered: 'Predpomnjeno', - currentTime: 'Čas', - duration: 'Dolžina', - volume: 'Glasnost', - mute: 'Izklopi zvok', - unmute: 'Vklopi zvok', - enableCaptions: 'Omogoči podnapise', - disableCaptions: 'Onemogoči podnapise', - download: 'Prenesi', - enterFullscreen: 'Odpri celozaslonski način', - exitFullscreen: 'Zapri celozaslonski način', - frameTitle: 'Predvajalnik za {title}', - captions: 'Podnapisi', - settings: 'Nastavitve', - menuBack: 'Pojdi nazaj v prejšnji meni', - speed: 'Hitrost', - normal: 'Običajna', - quality: 'Kakovost', - loop: 'Zanka', - start: 'Začetek', - end: 'Konec', - all: 'Vse', - reset: 'Ponastavi', - disabled: 'Onemogočeni', - enabled: 'Omogočeni', - advertisement: 'Oglas', - qualityBadge: { - '480': 'SD', - '576': 'SD', - '720': 'HD', - '1080': 'HD', - '1440': 'HD', - '2160': '4K', - }, + restart: 'Ponovno predvajaj', + rewind: 'Nazaj za {seektime} sekund', + play: 'Predvajaj', + pause: 'Zaustavi', + fastForward: 'Naprej za {seektime} sekund', + seek: 'Pojdi', + seekLabel: '{currentTime} od {duration}', + played: 'Predvajano', + buffered: 'Predpomnjeno', + currentTime: 'Čas', + duration: 'Dolžina', + volume: 'Glasnost', + mute: 'Izklopi zvok', + unmute: 'Vklopi zvok', + enableCaptions: 'Omogoči podnapise', + disableCaptions: 'Onemogoči podnapise', + download: 'Prenesi', + enterFullscreen: 'Odpri celozaslonski način', + exitFullscreen: 'Zapri celozaslonski način', + frameTitle: 'Predvajalnik za {title}', + captions: 'Podnapisi', + settings: 'Nastavitve', + menuBack: 'Pojdi nazaj v prejšnji meni', + speed: 'Hitrost', + normal: 'Običajna', + quality: 'Kakovost', + loop: 'Zanka', + start: 'Začetek', + end: 'Konec', + all: 'Vse', + reset: 'Ponastavi', + disabled: 'Onemogočeni', + enabled: 'Omogočeni', + advertisement: 'Oglas', + qualityBadge: { + '480': 'SD', + '576': 'SD', + '720': 'HD', + '1080': 'HD', + '1440': 'HD', + '2160': '4K', + }, }; export default i18n; From c37c5b806264a9f0dab526c2bc1048bead7358ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20=C5=A0?= Date: Fri, 15 Mar 2019 16:27:56 +0100 Subject: [PATCH 6/8] Change language code standard --- contributing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contributing.md b/contributing.md index 6d6e77c74..036a71f32 100644 --- a/contributing.md +++ b/contributing.md @@ -44,7 +44,7 @@ Please follow the instructions in our issue templates. Don't use github issues t * Fork Plyr, and create a new branch in your fork, based on the **develop** branch -* Make and translate language file `src/locales/{lang}.js`, where `{lang}` is two-letter language code from [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes). It is recommended to copy and edit English translation. +* Make and translate language file `src/locales/{lang}.js`, where `{lang}` is [IETF BCP 47](https://en.wikipedia.org/wiki/IETF_language_tag) language tag. The language tag should have language and script subtags, seperated by a hyphen (for example `en-GB`). It is recommended to copy and edit English translation. * Add your language to `src/locales/index.js`. Make sure to import your file and follow the file format. The entry `name` should be native name of language. From 9d63b622445cf97345782b2e4ee8743056e2a8c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20=C5=A0?= Date: Fri, 15 Mar 2019 16:31:27 +0100 Subject: [PATCH 7/8] Add more details about language tag --- contributing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contributing.md b/contributing.md index 036a71f32..c6e678ad8 100644 --- a/contributing.md +++ b/contributing.md @@ -44,7 +44,7 @@ Please follow the instructions in our issue templates. Don't use github issues t * Fork Plyr, and create a new branch in your fork, based on the **develop** branch -* Make and translate language file `src/locales/{lang}.js`, where `{lang}` is [IETF BCP 47](https://en.wikipedia.org/wiki/IETF_language_tag) language tag. The language tag should have language and script subtags, seperated by a hyphen (for example `en-GB`). It is recommended to copy and edit English translation. +* Make and translate language file `src/locales/{lang}.js`, where `{lang}` is [IETF BCP 47](https://en.wikipedia.org/wiki/IETF_language_tag) language tag. The language tag should have language and region subtags, seperated by a hyphen. The region subtag should be written in upper case. Other subtags can also be added if needed. Example of valid language tag is `en-GB`. It is recommended to copy and edit English translation. * Add your language to `src/locales/index.js`. Make sure to import your file and follow the file format. The entry `name` should be native name of language. From eefdb8dc401011edd3efe81f4f5f4bfe5504d4e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20=C5=A0?= Date: Sat, 18 Jan 2020 22:58:00 +0100 Subject: [PATCH 8/8] Fix merge --- src/js/config/defaults.js | 49 --------------------------------------- 1 file changed, 49 deletions(-) diff --git a/src/js/config/defaults.js b/src/js/config/defaults.js index c5511f0a6..d85a551da 100644 --- a/src/js/config/defaults.js +++ b/src/js/config/defaults.js @@ -145,57 +145,8 @@ const defaults = { ], settings: ['captions', 'quality', 'speed'], -<<<<<<< HEAD // Custom localisation i18n: {}, -======= - // Localisation - i18n: { - restart: 'Restart', - rewind: 'Rewind {seektime}s', - play: 'Play', - pause: 'Pause', - fastForward: 'Forward {seektime}s', - seek: 'Seek', - seekLabel: '{currentTime} of {duration}', - played: 'Played', - buffered: 'Buffered', - currentTime: 'Current time', - duration: 'Duration', - volume: 'Volume', - mute: 'Mute', - unmute: 'Unmute', - enableCaptions: 'Enable captions', - disableCaptions: 'Disable captions', - download: 'Download', - enterFullscreen: 'Enter fullscreen', - exitFullscreen: 'Exit fullscreen', - frameTitle: 'Player for {title}', - captions: 'Captions', - settings: 'Settings', - pip: 'PIP', - menuBack: 'Go back to previous menu', - speed: 'Speed', - normal: 'Normal', - quality: 'Quality', - loop: 'Loop', - start: 'Start', - end: 'End', - all: 'All', - reset: 'Reset', - disabled: 'Disabled', - enabled: 'Enabled', - advertisement: 'Ad', - qualityBadge: { - 2160: '4K', - 1440: 'HD', - 1080: 'HD', - 720: 'HD', - 576: 'SD', - 480: 'SD', - }, - }, ->>>>>>> a77d2d56f67d6b601940d89bd8ac9831e0949963 // URLs urls: {