From 29ae08ffb4fe4ffcf8a163b500cd31ae55e4dcc1 Mon Sep 17 00:00:00 2001 From: Cameron Date: Sun, 19 Jul 2020 10:52:15 +0100 Subject: [PATCH 001/196] Migration of musicrecommended to ES6 module --- package.json | 1 + src/controllers/music/musicrecommended.js | 102 +++++++++++++--------- 2 files changed, 62 insertions(+), 41 deletions(-) diff --git a/package.json b/package.json index 5d4742686d..9181dcb9b2 100644 --- a/package.json +++ b/package.json @@ -116,6 +116,7 @@ "src/components/syncPlay/timeSyncManager.js", "src/controllers/dashboard/logs.js", "src/controllers/dashboard/plugins/repositories.js", + "src/controllers/music/musicrecommended.js", "src/controllers/user/display.js", "src/controllers/user/home.js", "src/controllers/user/playback.js", diff --git a/src/controllers/music/musicrecommended.js b/src/controllers/music/musicrecommended.js index 3f025799f6..f92ee588b8 100644 --- a/src/controllers/music/musicrecommended.js +++ b/src/controllers/music/musicrecommended.js @@ -1,8 +1,25 @@ -define(['browser', 'layoutManager', 'userSettings', 'inputManager', 'loading', 'cardBuilder', 'dom', 'apphost', 'imageLoader', 'libraryMenu', 'playbackManager', 'mainTabsManager', 'globalize', 'scrollStyles', 'emby-itemscontainer', 'emby-tabs', 'emby-button', 'flexStyles'], function (browser, layoutManager, userSettings, inputManager, loading, cardBuilder, dom, appHost, imageLoader, libraryMenu, playbackManager, mainTabsManager, globalize) { - 'use strict'; +import browser from 'browser'; +import layoutManager from 'layoutManager'; +import * as userSettings from 'userSettings'; +import inputManager from 'inputManager'; +import loading from 'loading'; +import cardBuilder from 'cardBuilder'; +import dom from 'dom'; +import appHost from 'apphost'; +import imageLoader from 'imageLoader'; +import libraryMenu from 'libraryMenu'; +import mainTabsManager from 'mainTabsManager'; +import globalize from 'globalize'; +import 'scrollStyles'; +import 'emby-itemscontainer'; +import 'emby-tabs'; +import 'emby-button'; +import 'flexStyles'; + +/* eslint-disable indent */ function itemsPerRow() { - var screenWidth = dom.getWindowSize().innerWidth; + const screenWidth = dom.getWindowSize().innerWidth; if (screenWidth >= 1920) { return 9; @@ -29,8 +46,8 @@ define(['browser', 'layoutManager', 'userSettings', 'inputManager', 'loading', ' function loadLatest(page, parentId) { loading.show(); - var userId = ApiClient.getCurrentUserId(); - var options = { + const userId = ApiClient.getCurrentUserId(); + const options = { IncludeItemTypes: 'Audio', Limit: enableScrollX() ? 3 * itemsPerRow() : 2 * itemsPerRow(), Fields: 'PrimaryImageAspectRatio,BasicSyncInfo', @@ -40,8 +57,8 @@ define(['browser', 'layoutManager', 'userSettings', 'inputManager', 'loading', ' EnableTotalRecordCount: false }; ApiClient.getJSON(ApiClient.getUrl('Users/' + userId + '/Items/Latest', options)).then(function (items) { - var elem = page.querySelector('#recentlyAddedSongs'); - var supportsImageAnalysis = appHost.supports('imageanalysis'); + const elem = page.querySelector('#recentlyAddedSongs'); + let supportsImageAnalysis = appHost.supports('imageanalysis'); supportsImageAnalysis = false; elem.innerHTML = cardBuilder.getCardsHtml({ items: items, @@ -60,14 +77,14 @@ define(['browser', 'layoutManager', 'userSettings', 'inputManager', 'loading', ' imageLoader.lazyChildren(elem); loading.hide(); - require(['autoFocuser'], function (autoFocuser) { + import('autoFocuser').then(({default: autoFocuser}) => { autoFocuser.autoFocus(page); }); }); } function loadRecentlyPlayed(page, parentId) { - var options = { + const options = { SortBy: 'DatePlayed', SortOrder: 'Descending', IncludeItemTypes: 'Audio', @@ -81,7 +98,7 @@ define(['browser', 'layoutManager', 'userSettings', 'inputManager', 'loading', ' EnableTotalRecordCount: false }; ApiClient.getItems(ApiClient.getCurrentUserId(), options).then(function (result) { - var elem = page.querySelector('#recentlyPlayed'); + const elem = page.querySelector('#recentlyPlayed'); if (result.Items.length) { elem.classList.remove('hide'); @@ -89,8 +106,8 @@ define(['browser', 'layoutManager', 'userSettings', 'inputManager', 'loading', ' elem.classList.add('hide'); } - var itemsContainer = elem.querySelector('.itemsContainer'); - var supportsImageAnalysis = appHost.supports('imageanalysis'); + const itemsContainer = elem.querySelector('.itemsContainer'); + let supportsImageAnalysis = appHost.supports('imageanalysis'); supportsImageAnalysis = false; itemsContainer.innerHTML = cardBuilder.getCardsHtml({ items: result.Items, @@ -111,7 +128,7 @@ define(['browser', 'layoutManager', 'userSettings', 'inputManager', 'loading', ' } function loadFrequentlyPlayed(page, parentId) { - var options = { + const options = { SortBy: 'PlayCount', SortOrder: 'Descending', IncludeItemTypes: 'Audio', @@ -125,7 +142,7 @@ define(['browser', 'layoutManager', 'userSettings', 'inputManager', 'loading', ' EnableTotalRecordCount: false }; ApiClient.getItems(ApiClient.getCurrentUserId(), options).then(function (result) { - var elem = page.querySelector('#topPlayed'); + const elem = page.querySelector('#topPlayed'); if (result.Items.length) { elem.classList.remove('hide'); @@ -133,8 +150,8 @@ define(['browser', 'layoutManager', 'userSettings', 'inputManager', 'loading', ' elem.classList.add('hide'); } - var itemsContainer = elem.querySelector('.itemsContainer'); - var supportsImageAnalysis = appHost.supports('imageanalysis'); + const itemsContainer = elem.querySelector('.itemsContainer'); + let supportsImageAnalysis = appHost.supports('imageanalysis'); supportsImageAnalysis = false; itemsContainer.innerHTML = cardBuilder.getCardsHtml({ items: result.Items, @@ -160,7 +177,7 @@ define(['browser', 'layoutManager', 'userSettings', 'inputManager', 'loading', ' loadRecentlyPlayed(tabContent, parentId); loadFrequentlyPlayed(tabContent, parentId); - require(['components/favoriteitems'], function (favoriteItems) { + import('components/favoriteitems').then(({default: favoriteItems}) => { favoriteItems.render(tabContent, ApiClient.getCurrentUserId(), parentId, ['favoriteArtists', 'favoriteAlbums', 'favoriteSongs']); }); } @@ -211,10 +228,10 @@ define(['browser', 'layoutManager', 'userSettings', 'inputManager', 'loading', ' } } - return function (view, params) { + export default function (view, params) { function reload() { loading.show(); - var tabContent = view.querySelector(".pageTabContent[data-index='0']"); + const tabContent = view.querySelector(".pageTabContent[data-index='0']"); loadSuggestionsTab(view, tabContent, params.topParentId); } @@ -257,46 +274,48 @@ define(['browser', 'layoutManager', 'userSettings', 'inputManager', 'loading', ' } function getTabController(page, index, callback) { - var depends = []; + let depends; switch (index) { case 0: + depends = 'controllers/music/musicrecommended'; break; case 1: - depends.push('controllers/music/musicalbums'); + depends = 'controllers/music/musicalbums'; break; case 2: case 3: - depends.push('controllers/music/musicartists'); + depends = 'controllers/music/musicartists'; break; case 4: - depends.push('controllers/music/musicplaylists'); + depends = 'controllers/music/musicplaylists'; break; case 5: - depends.push('controllers/music/songs'); + depends = 'controllers/music/songs'; break; case 6: - depends.push('controllers/music/musicgenres'); + depends = 'controllers/music/musicgenres'; break; case 7: - depends.push('scripts/searchtab'); + depends = 'scripts/searchtab'; + break; } - require(depends, function (controllerFactory) { - var tabContent; + import(depends).then(({default: controllerFactory}) => { + let tabContent; if (0 == index) { tabContent = view.querySelector(".pageTabContent[data-index='" + index + "']"); self.tabContent = tabContent; } - var controller = tabControllers[index]; + let controller = tabControllers[index]; if (!controller) { tabContent = view.querySelector(".pageTabContent[data-index='" + index + "']"); @@ -356,16 +375,16 @@ define(['browser', 'layoutManager', 'userSettings', 'inputManager', 'loading', ' } } - var isViewRestored; - var self = this; - var currentTabIndex = parseInt(params.tab || getDefaultTabIndex(params.topParentId)); - var initialTabIndex = currentTabIndex; + let isViewRestored; + const self = this; + let currentTabIndex = parseInt(params.tab || getDefaultTabIndex(params.topParentId)); + let initialTabIndex = currentTabIndex; self.initTab = function () { - var tabContent = view.querySelector(".pageTabContent[data-index='0']"); - var containers = tabContent.querySelectorAll('.itemsContainer'); + const tabContent = view.querySelector(".pageTabContent[data-index='0']"); + const containers = tabContent.querySelectorAll('.itemsContainer'); - for (var i = 0, length = containers.length; i < length; i++) { + for (let i = 0, length = containers.length; i < length; i++) { setScrollClasses(containers[i], enableScrollX()); } }; @@ -374,13 +393,13 @@ define(['browser', 'layoutManager', 'userSettings', 'inputManager', 'loading', ' reload(); }; - var tabControllers = []; - var renderedTabs = []; + const tabControllers = []; + const renderedTabs = []; view.addEventListener('viewshow', function (e) { isViewRestored = e.detail.isRestored; initTabs(); if (!view.getAttribute('data-title')) { - var parentId = params.topParentId; + const parentId = params.topParentId; if (parentId) { ApiClient.getItem(ApiClient.getCurrentUserId(), parentId).then(function (item) { @@ -405,5 +424,6 @@ define(['browser', 'layoutManager', 'userSettings', 'inputManager', 'loading', ' } }); }); - }; -}); + } + +/* eslint-enable indent */ From d9b777bb9659babf6d3856c27ee776ed7223ecfc Mon Sep 17 00:00:00 2001 From: Cameron Date: Sun, 19 Jul 2020 10:54:00 +0100 Subject: [PATCH 002/196] Migration of musicalbums to ES6 module --- package.json | 1 + src/controllers/music/musicalbums.js | 78 ++++++++++++++++------------ 2 files changed, 45 insertions(+), 34 deletions(-) diff --git a/package.json b/package.json index 9181dcb9b2..b02547fc0e 100644 --- a/package.json +++ b/package.json @@ -116,6 +116,7 @@ "src/components/syncPlay/timeSyncManager.js", "src/controllers/dashboard/logs.js", "src/controllers/dashboard/plugins/repositories.js", + "src/controllers/music/musicalbums.js", "src/controllers/music/musicrecommended.js", "src/controllers/user/display.js", "src/controllers/user/home.js", diff --git a/src/controllers/music/musicalbums.js b/src/controllers/music/musicalbums.js index 645daf4ad9..bc6d2c4e37 100644 --- a/src/controllers/music/musicalbums.js +++ b/src/controllers/music/musicalbums.js @@ -1,7 +1,18 @@ -define(['layoutManager', 'playbackManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', 'alphaPicker', 'listView', 'cardBuilder', 'userSettings', 'globalize', 'emby-itemscontainer'], function (layoutManager, playbackManager, loading, events, libraryBrowser, imageLoader, alphaPicker, listView, cardBuilder, userSettings, globalize) { - 'use strict'; +import playbackManager from 'playbackManager'; +import loading from 'loading'; +import events from 'events'; +import libraryBrowser from 'libraryBrowser'; +import imageLoader from 'imageLoader'; +import AlphaPicker from 'alphaPicker'; +import listView from 'listView'; +import cardBuilder from 'cardBuilder'; +import * as userSettings from 'userSettings'; +import globalize from 'globalize'; +import 'emby-itemscontainer'; - return function (view, params, tabContent) { +/* eslint-disable indent */ + + export default function (view, params, tabContent) { function playAll() { ApiClient.getItem(ApiClient.getCurrentUserId(), params.topParentId).then(function (item) { playbackManager.play({ @@ -18,7 +29,7 @@ define(['layoutManager', 'playbackManager', 'loading', 'events', 'libraryBrowser } function getPageData() { - var key = getSavedQueryKey(); + const key = getSavedQueryKey(); if (!pageData) { pageData = { @@ -59,8 +70,8 @@ define(['layoutManager', 'playbackManager', 'loading', 'events', 'libraryBrowser } function onViewStyleChange() { - var viewStyle = self.getCurrentViewStyle(); - var itemsContainer = tabContent.querySelector('.itemsContainer'); + const viewStyle = self.getCurrentViewStyle(); + const itemsContainer = tabContent.querySelector('.itemsContainer'); if ('List' == viewStyle) { itemsContainer.classList.add('vertical-list'); @@ -76,7 +87,7 @@ define(['layoutManager', 'playbackManager', 'loading', 'events', 'libraryBrowser function reloadItems(page) { loading.show(); isLoading = true; - var query = getQuery(); + const query = getQuery(); ApiClient.getItems(ApiClient.getCurrentUserId(), query).then(function (result) { function onNextPageClick() { if (isLoading) { @@ -102,8 +113,8 @@ define(['layoutManager', 'playbackManager', 'loading', 'events', 'libraryBrowser window.scrollTo(0, 0); updateFilterControls(page); - var html; - var pagingHtml = libraryBrowser.getQueryPagingHtml({ + let html; + const pagingHtml = libraryBrowser.getQueryPagingHtml({ startIndex: query.StartIndex, limit: query.Limit, totalRecordCount: result.TotalRecordCount, @@ -113,7 +124,7 @@ define(['layoutManager', 'playbackManager', 'loading', 'events', 'libraryBrowser sortButton: false, filterButton: false }); - var viewStyle = self.getCurrentViewStyle(); + const viewStyle = self.getCurrentViewStyle(); if (viewStyle == 'List') { html = listView.getListViewHtml({ items: result.Items, @@ -144,50 +155,48 @@ define(['layoutManager', 'playbackManager', 'loading', 'events', 'libraryBrowser overlayPlayButton: true }); } - var i; - var length; - var elems = tabContent.querySelectorAll('.paging'); + let elems = tabContent.querySelectorAll('.paging'); - for (i = 0, length = elems.length; i < length; i++) { + for (let i = 0, length = elems.length; i < length; i++) { elems[i].innerHTML = pagingHtml; } elems = tabContent.querySelectorAll('.btnNextPage'); - for (i = 0, length = elems.length; i < length; i++) { + for (let i = 0, length = elems.length; i < length; i++) { elems[i].addEventListener('click', onNextPageClick); } elems = tabContent.querySelectorAll('.btnPreviousPage'); - for (i = 0, length = elems.length; i < length; i++) { + for (let i = 0, length = elems.length; i < length; i++) { elems[i].addEventListener('click', onPreviousPageClick); } - var itemsContainer = tabContent.querySelector('.itemsContainer'); + const itemsContainer = tabContent.querySelector('.itemsContainer'); itemsContainer.innerHTML = html; imageLoader.lazyChildren(itemsContainer); libraryBrowser.saveQueryValues(getSavedQueryKey(), query); loading.hide(); isLoading = false; - require(['autoFocuser'], function (autoFocuser) { + import('autoFocuser').then(({default: autoFocuser}) => { autoFocuser.autoFocus(tabContent); }); }); } function updateFilterControls(tabContent) { - var query = getQuery(); + const query = getQuery(); self.alphaPicker.value(query.NameStartsWithOrGreater); } - var savedQueryKey; - var pageData; - var self = this; - var isLoading = false; + let savedQueryKey; + let pageData; + const self = this; + let isLoading = false; self.showFilterMenu = function () { - require(['components/filterdialog/filterdialog'], function ({default: filterDialogFactory}) { - var filterDialog = new filterDialogFactory({ + import('components/filterdialog/filterdialog').then(({default: filterDialogFactory}) => { + const filterDialog = new filterDialogFactory({ query: getQuery(), mode: 'albums', serverId: ApiClient.serverId() @@ -205,17 +214,17 @@ define(['layoutManager', 'playbackManager', 'loading', 'events', 'libraryBrowser }; function initPage(tabContent) { - var alphaPickerElement = tabContent.querySelector('.alphaPicker'); - var itemsContainer = tabContent.querySelector('.itemsContainer'); + const alphaPickerElement = tabContent.querySelector('.alphaPicker'); + const itemsContainer = tabContent.querySelector('.itemsContainer'); alphaPickerElement.addEventListener('alphavaluechanged', function (e) { - var newValue = e.detail.value; - var query = getQuery(); + const newValue = e.detail.value; + const query = getQuery(); query.NameStartsWithOrGreater = newValue; query.StartIndex = 0; reloadItems(tabContent); }); - self.alphaPicker = new alphaPicker({ + self.alphaPicker = new AlphaPicker({ element: alphaPickerElement, valueChangeEvent: 'click' }); @@ -259,12 +268,12 @@ define(['layoutManager', 'playbackManager', 'loading', 'events', 'libraryBrowser button: e.target }); }); - var btnSelectView = tabContent.querySelector('.btnSelectView'); + const btnSelectView = tabContent.querySelector('.btnSelectView'); btnSelectView.addEventListener('click', function (e) { libraryBrowser.showLayoutMenu(e.target, self.getCurrentViewStyle(), 'List,Poster,PosterCard'.split(',')); }); btnSelectView.addEventListener('layoutchange', function (e) { - var viewStyle = e.detail.viewStyle; + const viewStyle = e.detail.viewStyle; getPageData().view = viewStyle; libraryBrowser.saveViewSetting(getSavedQueryKey(), viewStyle); getQuery().StartIndex = 0; @@ -284,5 +293,6 @@ define(['layoutManager', 'playbackManager', 'loading', 'events', 'libraryBrowser }; self.destroy = function () {}; - }; -}); + } + +/* eslint-enable indent */ From 338f678000935a76162f5c2bde6c24b3fa0bc2c1 Mon Sep 17 00:00:00 2001 From: Cameron Date: Sun, 19 Jul 2020 10:55:06 +0100 Subject: [PATCH 003/196] Migration of musicartists to ES6 modules --- package.json | 1 + src/controllers/music/musicartists.js | 80 +++++++++++++++------------ 2 files changed, 45 insertions(+), 36 deletions(-) diff --git a/package.json b/package.json index b02547fc0e..037953f3a4 100644 --- a/package.json +++ b/package.json @@ -118,6 +118,7 @@ "src/controllers/dashboard/plugins/repositories.js", "src/controllers/music/musicalbums.js", "src/controllers/music/musicrecommended.js", + "src/controllers/music/musicartists.js", "src/controllers/user/display.js", "src/controllers/user/home.js", "src/controllers/user/playback.js", diff --git a/src/controllers/music/musicartists.js b/src/controllers/music/musicartists.js index 7a889ff8b9..985c629103 100644 --- a/src/controllers/music/musicartists.js +++ b/src/controllers/music/musicartists.js @@ -1,13 +1,22 @@ -define(['layoutManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', 'alphaPicker', 'listView', 'cardBuilder', 'apphost', 'userSettings', 'emby-itemscontainer'], function (layoutManager, loading, events, libraryBrowser, imageLoader, alphaPicker, listView, cardBuilder, appHost, userSettings) { - 'use strict'; +import loading from 'loading'; +import events from 'events'; +import libraryBrowser from 'libraryBrowser'; +import imageLoader from 'imageLoader'; +import AlphaPicker from 'alphaPicker'; +import listView from 'listView'; +import cardBuilder from 'cardBuilder'; +import * as userSettings from 'userSettings'; +import 'emby-itemscontainer'; - return function (view, params, tabContent) { +/* eslint-disable indent */ + + export default function (view, params, tabContent) { function getPageData(context) { - var key = getSavedQueryKey(context); - var pageData = data[key]; + const key = getSavedQueryKey(context); + let pageData = data[key]; if (!pageData) { - var queryValues = { + const queryValues = { SortBy: 'SortName', SortOrder: 'Ascending', Recursive: true, @@ -45,8 +54,8 @@ define(['layoutManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', ' } function onViewStyleChange() { - var viewStyle = self.getCurrentViewStyle(); - var itemsContainer = tabContent.querySelector('.itemsContainer'); + const viewStyle = self.getCurrentViewStyle(); + const itemsContainer = tabContent.querySelector('.itemsContainer'); if ('List' == viewStyle) { itemsContainer.classList.add('vertical-list'); @@ -62,8 +71,8 @@ define(['layoutManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', ' function reloadItems(page) { loading.show(); isLoading = true; - var query = getQuery(page); - var promise = self.mode == 'albumartists' ? + const query = getQuery(page); + const promise = self.mode == 'albumartists' ? ApiClient.getAlbumArtists(ApiClient.getCurrentUserId(), query) : ApiClient.getArtists(ApiClient.getCurrentUserId(), query); promise.then(function (result) { @@ -91,8 +100,8 @@ define(['layoutManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', ' window.scrollTo(0, 0); updateFilterControls(page); - var html; - var pagingHtml = libraryBrowser.getQueryPagingHtml({ + let html; + const pagingHtml = libraryBrowser.getQueryPagingHtml({ startIndex: query.StartIndex, limit: query.Limit, totalRecordCount: result.TotalRecordCount, @@ -102,7 +111,7 @@ define(['layoutManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', ' sortButton: false, filterButton: false }); - var viewStyle = self.getCurrentViewStyle(); + const viewStyle = self.getCurrentViewStyle(); if (viewStyle == 'List') { html = listView.getListViewHtml({ items: result.Items, @@ -129,49 +138,47 @@ define(['layoutManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', ' overlayPlayButton: true }); } - var i; - var length; - var elems = tabContent.querySelectorAll('.paging'); + let elems = tabContent.querySelectorAll('.paging'); - for (i = 0, length = elems.length; i < length; i++) { + for (let i = 0, length = elems.length; i < length; i++) { elems[i].innerHTML = pagingHtml; } elems = tabContent.querySelectorAll('.btnNextPage'); - for (i = 0, length = elems.length; i < length; i++) { + for (let i = 0, length = elems.length; i < length; i++) { elems[i].addEventListener('click', onNextPageClick); } elems = tabContent.querySelectorAll('.btnPreviousPage'); - for (i = 0, length = elems.length; i < length; i++) { + for (let i = 0, length = elems.length; i < length; i++) { elems[i].addEventListener('click', onPreviousPageClick); } - var itemsContainer = tabContent.querySelector('.itemsContainer'); + const itemsContainer = tabContent.querySelector('.itemsContainer'); itemsContainer.innerHTML = html; imageLoader.lazyChildren(itemsContainer); libraryBrowser.saveQueryValues(getSavedQueryKey(page), query); loading.hide(); isLoading = false; - require(['autoFocuser'], function (autoFocuser) { + import('autoFocuser').then(({default: autoFocuser}) => { autoFocuser.autoFocus(tabContent); }); }); } function updateFilterControls(tabContent) { - var query = getQuery(tabContent); + const query = getQuery(tabContent); self.alphaPicker.value(query.NameStartsWithOrGreater); } - var self = this; - var data = {}; - var isLoading = false; + const self = this; + const data = {}; + let isLoading = false; self.showFilterMenu = function () { - require(['components/filterdialog/filterdialog'], function ({default: filterDialogFactory}) { - var filterDialog = new filterDialogFactory({ + import('components/filterdialog/filterdialog').then(({default: filterDialogFactory}) => { + const filterDialog = new filterDialogFactory({ query: getQuery(tabContent), mode: self.mode, serverId: ApiClient.serverId() @@ -189,17 +196,17 @@ define(['layoutManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', ' }; function initPage(tabContent) { - var alphaPickerElement = tabContent.querySelector('.alphaPicker'); - var itemsContainer = tabContent.querySelector('.itemsContainer'); + const alphaPickerElement = tabContent.querySelector('.alphaPicker'); + const itemsContainer = tabContent.querySelector('.itemsContainer'); alphaPickerElement.addEventListener('alphavaluechanged', function (e) { - var newValue = e.detail.value; - var query = getQuery(tabContent); + const newValue = e.detail.value; + const query = getQuery(tabContent); query.NameStartsWithOrGreater = newValue; query.StartIndex = 0; reloadItems(tabContent); }); - self.alphaPicker = new alphaPicker({ + self.alphaPicker = new AlphaPicker({ element: alphaPickerElement, valueChangeEvent: 'click' }); @@ -211,12 +218,12 @@ define(['layoutManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', ' tabContent.querySelector('.btnFilter').addEventListener('click', function () { self.showFilterMenu(); }); - var btnSelectView = tabContent.querySelector('.btnSelectView'); + const btnSelectView = tabContent.querySelector('.btnSelectView'); btnSelectView.addEventListener('click', function (e) { libraryBrowser.showLayoutMenu(e.target, self.getCurrentViewStyle(), 'List,Poster,PosterCard'.split(',')); }); btnSelectView.addEventListener('layoutchange', function (e) { - var viewStyle = e.detail.viewStyle; + const viewStyle = e.detail.viewStyle; getPageData(tabContent).view = viewStyle; libraryBrowser.saveViewSetting(getSavedQueryKey(tabContent), viewStyle); getQuery(tabContent).StartIndex = 0; @@ -234,5 +241,6 @@ define(['layoutManager', 'loading', 'events', 'libraryBrowser', 'imageLoader', ' }; self.destroy = function () {}; - }; -}); + } + +/* eslint-enable indent */ From c683d96bc3ad6ba6cf191a21578c93ff34efb91b Mon Sep 17 00:00:00 2001 From: Cameron Date: Sun, 19 Jul 2020 10:57:03 +0100 Subject: [PATCH 004/196] Migration of musicgenres to ES6 modules --- package.json | 3 ++- src/controllers/music/musicgenres.js | 37 ++++++++++++++++------------ 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/package.json b/package.json index 037953f3a4..79c7228684 100644 --- a/package.json +++ b/package.json @@ -117,8 +117,9 @@ "src/controllers/dashboard/logs.js", "src/controllers/dashboard/plugins/repositories.js", "src/controllers/music/musicalbums.js", - "src/controllers/music/musicrecommended.js", "src/controllers/music/musicartists.js", + "src/controllers/music/musicgenres.js", + "src/controllers/music/musicrecommended.js", "src/controllers/user/display.js", "src/controllers/user/home.js", "src/controllers/user/playback.js", diff --git a/src/controllers/music/musicgenres.js b/src/controllers/music/musicgenres.js index 82f2eba574..29e0d888e4 100644 --- a/src/controllers/music/musicgenres.js +++ b/src/controllers/music/musicgenres.js @@ -1,10 +1,14 @@ -define(['libraryBrowser', 'cardBuilder', 'apphost', 'imageLoader', 'loading'], function (libraryBrowser, cardBuilder, appHost, imageLoader, loading) { - 'use strict'; +import libraryBrowser from 'libraryBrowser'; +import cardBuilder from 'cardBuilder'; +import imageLoader from 'imageLoader'; +import loading from 'loading'; - return function (view, params, tabContent) { +/* eslint-disable indent */ + + export default function (view, params, tabContent) { function getPageData() { - var key = getSavedQueryKey(); - var pageData = data[key]; + const key = getSavedQueryKey(); + let pageData = data[key]; if (!pageData) { pageData = data[key] = { @@ -34,15 +38,15 @@ define(['libraryBrowser', 'cardBuilder', 'apphost', 'imageLoader', 'loading'], f function getPromise() { loading.show(); - var query = getQuery(); + const query = getQuery(); return ApiClient.getGenres(ApiClient.getCurrentUserId(), query); } function reloadItems(context, promise) { - var query = getQuery(); + const query = getQuery(); promise.then(function (result) { - var html = ''; - var viewStyle = self.getCurrentViewStyle(); + let html = ''; + const viewStyle = self.getCurrentViewStyle(); if (viewStyle == 'Thumb') { html = cardBuilder.getCardsHtml({ @@ -82,13 +86,13 @@ define(['libraryBrowser', 'cardBuilder', 'apphost', 'imageLoader', 'loading'], f }); } - var elem = context.querySelector('#items'); + const elem = context.querySelector('#items'); elem.innerHTML = html; imageLoader.lazyChildren(elem); libraryBrowser.saveQueryValues(getSavedQueryKey(), query); loading.hide(); - require(['autoFocuser'], function (autoFocuser) { + import('autoFocuser').then(({default: autoFocuser}) => { autoFocuser.autoFocus(context); }); }); @@ -99,8 +103,8 @@ define(['libraryBrowser', 'cardBuilder', 'apphost', 'imageLoader', 'loading'], f self.renderTab(); } - var self = this; - var data = {}; + const self = this; + const data = {}; self.getViewStyles = function () { return 'Poster,PosterCard,Thumb,ThumbCard'.split(','); @@ -117,7 +121,7 @@ define(['libraryBrowser', 'cardBuilder', 'apphost', 'imageLoader', 'loading'], f }; self.enableViewSelection = true; - var promise; + let promise; self.preRender = function () { promise = getPromise(); @@ -126,5 +130,6 @@ define(['libraryBrowser', 'cardBuilder', 'apphost', 'imageLoader', 'loading'], f self.renderTab = function () { reloadItems(tabContent, promise); }; - }; -}); + } + +/* eslint-enable indent */ From 4bf11489cdc5b3519f478902f714c9a43d155a1c Mon Sep 17 00:00:00 2001 From: Cameron Date: Sun, 19 Jul 2020 10:58:00 +0100 Subject: [PATCH 005/196] Migration of musicplaylists to ES6 modules --- package.json | 1 + src/controllers/music/musicplaylists.js | 35 ++++++++++++++----------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index 79c7228684..80d4a8ed0b 100644 --- a/package.json +++ b/package.json @@ -119,6 +119,7 @@ "src/controllers/music/musicalbums.js", "src/controllers/music/musicartists.js", "src/controllers/music/musicgenres.js", + "src/controllers/music/musicplaylists.js", "src/controllers/music/musicrecommended.js", "src/controllers/user/display.js", "src/controllers/user/home.js", diff --git a/src/controllers/music/musicplaylists.js b/src/controllers/music/musicplaylists.js index f508489216..befeafcf4c 100644 --- a/src/controllers/music/musicplaylists.js +++ b/src/controllers/music/musicplaylists.js @@ -1,10 +1,14 @@ -define(['libraryBrowser', 'cardBuilder', 'apphost', 'imageLoader', 'loading'], function (libraryBrowser, cardBuilder, appHost, imageLoader, loading) { - 'use strict'; +import libraryBrowser from 'libraryBrowser'; +import cardBuilder from 'cardBuilder'; +import imageLoader from 'imageLoader'; +import loading from 'loading'; - return function (view, params, tabContent) { +/* eslint-disable indent */ + + export default function (view, params, tabContent) { function getPageData() { - var key = getSavedQueryKey(); - var pageData = data[key]; + const key = getSavedQueryKey(); + let pageData = data[key]; if (!pageData) { pageData = data[key] = { @@ -35,14 +39,14 @@ define(['libraryBrowser', 'cardBuilder', 'apphost', 'imageLoader', 'loading'], f function getPromise() { loading.show(); - var query = getQuery(); + const query = getQuery(); return ApiClient.getItems(ApiClient.getCurrentUserId(), query); } function reloadItems(context, promise) { - var query = getQuery(); + const query = getQuery(); promise.then(function (result) { - var html = ''; + let html = ''; html = cardBuilder.getCardsHtml({ items: result.Items, shape: 'square', @@ -53,26 +57,26 @@ define(['libraryBrowser', 'cardBuilder', 'apphost', 'imageLoader', 'loading'], f allowBottomPadding: true, cardLayout: false }); - var elem = context.querySelector('#items'); + const elem = context.querySelector('#items'); elem.innerHTML = html; imageLoader.lazyChildren(elem); libraryBrowser.saveQueryValues(getSavedQueryKey(), query); loading.hide(); - require(['autoFocuser'], function (autoFocuser) { + import('autoFocuser').then(({default: autoFocuser}) => { autoFocuser.autoFocus(context); }); }); } - var self = this; - var data = {}; + const self = this; + const data = {}; self.getCurrentViewStyle = function () { return getPageData().view; }; - var promise; + let promise; self.preRender = function () { promise = getPromise(); @@ -81,5 +85,6 @@ define(['libraryBrowser', 'cardBuilder', 'apphost', 'imageLoader', 'loading'], f self.renderTab = function () { reloadItems(tabContent, promise); }; - }; -}); + } + +/* eslint-enable indent */ From b042e429d7085582d7474845a02318ed79ce8f99 Mon Sep 17 00:00:00 2001 From: Cameron Date: Sun, 19 Jul 2020 10:59:03 +0100 Subject: [PATCH 006/196] Migration of songs to ES6 module --- package.json | 1 + src/controllers/music/songs.js | 53 +++++++++++++++++++--------------- 2 files changed, 31 insertions(+), 23 deletions(-) diff --git a/package.json b/package.json index 80d4a8ed0b..52ead1b36e 100644 --- a/package.json +++ b/package.json @@ -121,6 +121,7 @@ "src/controllers/music/musicgenres.js", "src/controllers/music/musicplaylists.js", "src/controllers/music/musicrecommended.js", + "src/controllers/music/songs.js", "src/controllers/user/display.js", "src/controllers/user/home.js", "src/controllers/user/playback.js", diff --git a/src/controllers/music/songs.js b/src/controllers/music/songs.js index aa63ec51fe..4c4f229e58 100644 --- a/src/controllers/music/songs.js +++ b/src/controllers/music/songs.js @@ -1,10 +1,18 @@ -define(['events', 'libraryBrowser', 'imageLoader', 'listView', 'loading', 'userSettings', 'globalize', 'emby-itemscontainer'], function (events, libraryBrowser, imageLoader, listView, loading, userSettings, globalize) { - 'use strict'; +import events from 'events'; +import libraryBrowser from 'libraryBrowser'; +import imageLoader from 'imageLoader'; +import listView from 'listView'; +import loading from 'loading'; +import * as userSettings from 'userSettings'; +import globalize from 'globalize'; +import 'emby-itemscontainer'; - return function (view, params, tabContent) { +/* eslint-disable indent */ + + export default function (view, params, tabContent) { function getPageData(context) { - var key = getSavedQueryKey(context); - var pageData = data[key]; + const key = getSavedQueryKey(context); + let pageData = data[key]; if (!pageData) { pageData = data[key] = { @@ -46,7 +54,7 @@ define(['events', 'libraryBrowser', 'imageLoader', 'listView', 'loading', 'userS function reloadItems(page) { loading.show(); isLoading = true; - var query = getQuery(page); + const query = getQuery(page); ApiClient.getItems(Dashboard.getCurrentUserId(), query).then(function (result) { function onNextPageClick() { if (isLoading) { @@ -71,9 +79,7 @@ define(['events', 'libraryBrowser', 'imageLoader', 'listView', 'loading', 'userS } window.scrollTo(0, 0); - var i; - var length; - var pagingHtml = libraryBrowser.getQueryPagingHtml({ + const pagingHtml = libraryBrowser.getQueryPagingHtml({ startIndex: query.StartIndex, limit: query.Limit, totalRecordCount: result.TotalRecordCount, @@ -83,49 +89,49 @@ define(['events', 'libraryBrowser', 'imageLoader', 'listView', 'loading', 'userS sortButton: false, filterButton: false }); - var html = listView.getListViewHtml({ + const html = listView.getListViewHtml({ items: result.Items, action: 'playallfromhere', smallIcon: true, artist: true, addToListButton: true }); - var elems = tabContent.querySelectorAll('.paging'); + let elems = tabContent.querySelectorAll('.paging'); - for (i = 0, length = elems.length; i < length; i++) { + for (let i = 0, length = elems.length; i < length; i++) { elems[i].innerHTML = pagingHtml; } elems = tabContent.querySelectorAll('.btnNextPage'); - for (i = 0, length = elems.length; i < length; i++) { + for (let i = 0, length = elems.length; i < length; i++) { elems[i].addEventListener('click', onNextPageClick); } elems = tabContent.querySelectorAll('.btnPreviousPage'); - for (i = 0, length = elems.length; i < length; i++) { + for (let i = 0, length = elems.length; i < length; i++) { elems[i].addEventListener('click', onPreviousPageClick); } - var itemsContainer = tabContent.querySelector('.itemsContainer'); + const itemsContainer = tabContent.querySelector('.itemsContainer'); itemsContainer.innerHTML = html; imageLoader.lazyChildren(itemsContainer); libraryBrowser.saveQueryValues(getSavedQueryKey(page), query); loading.hide(); isLoading = false; - require(['autoFocuser'], function (autoFocuser) { + import('autoFocuser').then(({default: autoFocuser}) => { autoFocuser.autoFocus(page); }); }); } - var self = this; - var data = {}; - var isLoading = false; + const self = this; + const data = {}; + let isLoading = false; self.showFilterMenu = function () { - require(['components/filterdialog/filterdialog'], function ({default: filterDialogFactory}) { - var filterDialog = new filterDialogFactory({ + import('components/filterdialog/filterdialog').then(({default: filterDialogFactory}) => { + const filterDialog = new filterDialogFactory({ query: getQuery(tabContent), mode: 'songs', serverId: ApiClient.serverId() @@ -193,5 +199,6 @@ define(['events', 'libraryBrowser', 'imageLoader', 'listView', 'loading', 'userS }; self.destroy = function () {}; - }; -}); + } + +/* eslint-enable indent */ From 6bc599aacea0b2939ebfcaba01247041e2c6500c Mon Sep 17 00:00:00 2001 From: Cromefire_ Date: Wed, 15 Apr 2020 12:27:04 +0200 Subject: [PATCH 007/196] Migrated src/components/htmlvideoplay/plugin.js --- src/plugins/htmlVideoPlayer/plugin.js | 1399 +++++++++++++------------ 1 file changed, 747 insertions(+), 652 deletions(-) diff --git a/src/plugins/htmlVideoPlayer/plugin.js b/src/plugins/htmlVideoPlayer/plugin.js index cc312bb956..2c9de26897 100644 --- a/src/plugins/htmlVideoPlayer/plugin.js +++ b/src/plugins/htmlVideoPlayer/plugin.js @@ -1,11 +1,24 @@ -define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackManager', 'appRouter', 'appSettings', 'connectionManager', 'htmlMediaHelper', 'itemHelper', 'screenfull', 'globalize'], function (browser, require, events, appHost, loading, dom, playbackManager, appRouter, appSettings, connectionManager, htmlMediaHelper, itemHelper, screenfull, globalize) { - 'use strict'; +import browser from "browser"; +import events from "events"; +import appHost from "apphost"; +import loading from "loading"; +import dom from "dom"; +import playbackManager from "playbackManager"; +import appRouter from "appRouter"; +import connectionManager from "connectionManager"; +import htmlMediaHelper from "htmlMediaHelper"; +import itemHelper from "itemHelper"; +import screenfull from "screenfull"; +import globalize from "globalize"; + +/* eslint-disable indent */ + /* globals cast */ - var mediaManager; +let mediaManager; - function tryRemoveElement(elem) { - var parentNode = elem.parentNode; +function tryRemoveElement(elem) { + const parentNode = elem.parentNode; if (parentNode) { // Seeing crashes in edge webview @@ -17,8 +30,9 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa } } - var _supportsTextTracks; - function supportsTextTracks() { +let _supportsTextTracks; + +function supportsTextTracks() { if (_supportsTextTracks == null) { _supportsTextTracks = document.createElement('video').textTracks != null; @@ -78,7 +92,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa } if (track) { - var format = (track.Codec || '').toLowerCase(); + const format = (track.Codec || "").toLowerCase(); if (format === 'ssa' || format === 'ass') { return false; } @@ -115,7 +129,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa function zoomIn(elem) { return new Promise(function (resolve, reject) { - var duration = 240; + const duration = 240; elem.style.animation = 'htmlvideoplayer-zoomin ' + duration + 'ms ease-in normal'; hidePrePlaybackPage(); dom.addEventListener(elem, dom.whichAnimationEvent(), resolve, { @@ -125,7 +139,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa } function normalizeTrackEventText(text, useHtml) { - var result = text.replace(/\\N/gi, '\n').replace(/\r/gi, ''); + const result = text.replace(/\\N/gi, "\n").replace(/\r/gi, ""); return useHtml ? result.replace(/\n/gi, '
') : result; } @@ -140,7 +154,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa return track.Path; } - var url = playbackManager.getSubtitleUrl(track, item.ServerId); + let url = playbackManager.getSubtitleUrl(track, item.ServerId); if (format) { url = url.replace('.vtt', format); } @@ -155,99 +169,100 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa return ''; } - var defaultAttribute = mediaSource.DefaultSubtitleStreamIndex === t.Index ? ' default' : ''; + const defaultAttribute = mediaSource.DefaultSubtitleStreamIndex === t.Index ? " default" : ""; - var language = t.Language || 'und'; - var label = t.Language || 'und'; + const language = t.Language || "und"; + const label = t.Language || "und"; return ''; }).join(''); } function getDefaultProfile() { + return import("browserdeviceprofile").then(profileBuilder => { - return new Promise(function (resolve, reject) { - - require(['browserdeviceprofile'], function (profileBuilder) { - - resolve(profileBuilder({})); - }); + return profileBuilder({}); }); } - function HtmlVideoPlayer() { - - if (browser.edgeUwp) { - this.name = 'Windows Video Player'; - } else { - this.name = 'Html Video Player'; - } - - this.type = 'mediaplayer'; - this.id = 'htmlvideoplayer'; - - // Let any players created by plugins take priority - this.priority = 1; - - var videoDialog; - - var winJsPlaybackItem; - - var subtitleTrackIndexToSetOnPlaying; - var audioTrackIndexToSetOnPlaying; - - var lastCustomTrackMs = 0; - var currentClock; - var currentSubtitlesOctopus; - var currentAssRenderer; - var customTrackIndex = -1; - - var showTrackOffset; - var currentTrackOffset; - - var videoSubtitlesElem; - var currentTrackEvents; - - var self = this; - - self.currentSrc = function () { - return self._currentSrc; - }; - - self._fetchQueue = 0; - self.isFetching = false; - - function incrementFetchQueue() { - if (self._fetchQueue <= 0) { - self.isFetching = true; - events.trigger(self, 'beginFetch'); + /** + * Private: + * - videoDialog + * - winJsPlaybackItem + * - subtitleTrackIndexToSetOnPlaying + * - audioTrackIndexToSetOnPlaying + * - lastCustomTrackMs + * - currentClock + * - currentSubtitlesOctopus + * - currentAssRenderer + * - customTrackIndex + * - showTrackOffset + * - currentTrackOffset + * - videoSubtitlesElem + * - currentTrackEvents + * - supportedFeatures + */ + export class HtmlVideoPlayer { + constructor() { + if (browser.edgeUwp) { + this.name = 'Windows Video Player'; + } else { + this.name = 'Html Video Player'; } - self._fetchQueue++; + this.type = 'mediaplayer'; + this.id = 'htmlvideoplayer'; + + // Let any players created by plugins take priority + this.priority = 1; + + this._fetchQueue = 0; + this.isFetching = false; } - function decrementFetchQueue() { - self._fetchQueue--; + currentSrc() { + return this._currentSrc; + } - if (self._fetchQueue <= 0) { - self.isFetching = false; - events.trigger(self, 'endFetch'); + /** + * @private + */ + incrementFetchQueue() { + if (this._fetchQueue <= 0) { + this.isFetching = true; + events.trigger(this, "beginFetch"); + } + + this._fetchQueue++; + } + + /** + * @private + */ + decrementFetchQueue() { + this._fetchQueue--; + + if (this._fetchQueue <= 0) { + this.isFetching = false; + events.trigger(this, "endFetch"); } } - function updateVideoUrl(streamInfo) { + /** + * @private + */ + updateVideoUrl(streamInfo) { + const isHls = streamInfo.url.toLowerCase().indexOf(".m3u8") !== -1; - var isHls = streamInfo.url.toLowerCase().indexOf('.m3u8') !== -1; - - var mediaSource = streamInfo.mediaSource; - var item = streamInfo.item; + const mediaSource = streamInfo.mediaSource; + const item = streamInfo.item; // Huge hack alert. Safari doesn't seem to like if the segments aren't available right away when playback starts // This will start the transcoding process before actually feeding the video url into the player // Edit: Also seeing stalls from hls.js if (mediaSource && item && !mediaSource.RunTimeTicks && isHls && streamInfo.playMethod === 'Transcode' && (browser.iOS || browser.osx)) { - var hlsPlaylistUrl = streamInfo.url.replace('master.m3u8', 'live.m3u8'); + const hlsPlaylistUrl = streamInfo.url.replace("master.m3u8", "live.m3u8"); loading.show(); @@ -259,20 +274,14 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa url: hlsPlaylistUrl }).then(function () { - console.debug('completed prefetching hls playlist: ' + hlsPlaylistUrl); loading.hide(); streamInfo.url = hlsPlaylistUrl; - - return Promise.resolve(); - }, function () { - console.error('error prefetching hls playlist: ' + hlsPlaylistUrl); loading.hide(); - return Promise.resolve(); }); } else { @@ -280,58 +289,58 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa } } - self.play = function (options) { - self._started = false; - self._timeUpdated = false; + play(options) { + this._started = false; + this._timeUpdated = false; - self._currentTime = null; + this._currentTime = null; - self.resetSubtitleOffset(); + this.resetSubtitleOffset(); - return createMediaElement(options).then(function (elem) { - - return updateVideoUrl(options).then(function () { - return setCurrentSrc(elem, options); - }); - }); - }; - - function setSrcWithFlvJs(instance, elem, options, url) { - - return new Promise(function (resolve, reject) { - - require(['flvjs'], function (flvjs) { - - var flvPlayer = flvjs.createPlayer({ - type: 'flv', - url: url - }, - { - seekType: 'range', - lazyLoad: false - }); - - flvPlayer.attachMediaElement(elem); - flvPlayer.load(); - - flvPlayer.play().then(resolve, reject); - instance._flvPlayer = flvPlayer; - - // This is needed in setCurrentTrackElement - self._currentSrc = url; + return this.createMediaElement(options).then(elem => { + return this.updateVideoUrl(options).then(() => { + return this.setCurrentSrc(elem, options); }); }); } - function setSrcWithHlsJs(instance, elem, options, url) { + /** + * @private + */ + setSrcWithFlvJs(instance, elem, options, url) { + return import('flvjs').then(flvjs => { + const flvPlayer = flvjs.createPlayer({ + type: "flv", + url: url + }, + { + seekType: "range", + lazyLoad: false + }); + + flvPlayer.attachMediaElement(elem); + flvPlayer.load(); + + instance._flvPlayer = flvPlayer; + + // This is needed in setCurrentTrackElement + this._currentSrc = url; + + return flvPlayer.play(); + }); + } + + /** + * @private + */ + setSrcWithHlsJs(instance, elem, options, url) { return new Promise(function (resolve, reject) { - requireHlsPlayer(function () { - - var hls = new Hls({ + requireHlsPlayer(() => { + const hls = new Hls({ manifestLoadingTimeOut: 20000, - xhrSetup: function(xhr, xhr_url) { + xhrSetup(xhr, xhr_url) { xhr.withCredentials = true; } //appendErrorMaxRetry: 6, @@ -340,70 +349,70 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa hls.loadSource(url); hls.attachMedia(elem); - htmlMediaHelper.bindEventsToHlsPlayer(self, hls, elem, onError, resolve, reject); + htmlMediaHelper.bindEventsToHlsPlayer(this, hls, elem, this.onError.bind(this), resolve, reject); - self._hlsPlayer = hls; + this._hlsPlayer = hls; // This is needed in setCurrentTrackElement - self._currentSrc = url; + this._currentSrc = url; }); }); } - function onShakaError(event) { + /** + * @private + */ + onShakaError(event) { - var error = event.detail; + const error = event.detail; console.error('Error code', error.code, 'object', error); } - function setSrcWithShakaPlayer(instance, elem, options, url) { + /** + * @private + */ + setSrcWithShakaPlayer(instance, elem, options, url) { + return import('shaka').then(() => { + /* globals shaka */ - return new Promise(function (resolve, reject) { + const player = new shaka.Player(elem); - require(['shaka'], function () { - /* globals shaka */ + //player.configure({ + // abr: { + // enabled: false + // }, + // streaming: { - var player = new shaka.Player(elem); + // failureCallback: function () { + // alert(2); + // } + // } + //}); - //player.configure({ - // abr: { - // enabled: false - // }, - // streaming: { + //shaka.log.setLevel(6); - // failureCallback: function () { - // alert(2); - // } - // } - //}); + // Listen for error events. + player.addEventListener('error', this.onShakaError.bind(this)); - //shaka.log.setLevel(6); + self._shakaPlayer = player; - // Listen for error events. - player.addEventListener('error', onShakaError); + // This is needed in setCurrentTrackElement + self._currentSrc = url; - // Try to load a manifest. - // This is an asynchronous process. - player.load(url).then(function () { - - // This runs if the asynchronous load is successful. - resolve(); - - }, reject); - - self._shakaPlayer = player; - - // This is needed in setCurrentTrackElement - self._currentSrc = url; - }); + // Try to load a manifest. + // This is an asynchronous process. + return player.load(url); }); } - function setCurrentSrcChromecast(instance, elem, options, url) { + /** + * @private + */ + setCurrentSrcChromecast(instance, elem, options, url) { elem.autoplay = true; - var lrd = new cast.receiver.MediaManager.LoadRequestData(); + const lrd = new cast.receiver.MediaManager.LoadRequestData(); lrd.currentTime = (options.playerStartPositionTicks || 0) / 10000000; lrd.autoplay = true; lrd.media = new cast.receiver.media.MediaInformation(); @@ -418,7 +427,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa try { mediaManager.load(lrd); // This is needed in setCurrentTrackElement - self._currentSrc = url; + this._currentSrc = url; return Promise.resolve(); } catch (err) { @@ -428,29 +437,32 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa } } - // Adapted from : https://github.com/googlecast/CastReferencePlayer/blob/master/player.js - function onMediaManagerLoadMedia(event) { + /** + * Adapted from : https://github.com/googlecast/CastReferencePlayer/blob/master/player.js + * @private + */ + onMediaManagerLoadMedia(event) { - if (self._castPlayer) { - self._castPlayer.unload(); // Must unload before starting again. + if (this._castPlayer) { + this._castPlayer.unload(); // Must unload before starting again. } - self._castPlayer = null; + this._castPlayer = null; - var data = event.data; + const data = event.data; - var media = event.data.media || {}; - var url = media.contentId; - var contentType = media.contentType.toLowerCase(); - var options = media.customData; + const media = event.data.media || {}; + const url = media.contentId; + const contentType = media.contentType.toLowerCase(); + const options = media.customData; - var protocol; - var ext = 'm3u8'; + let protocol; + const ext = "m3u8"; - var mediaElement = self._mediaElement; + const mediaElement = this._mediaElement; - var host = new cast.player.api.Host({ - 'url': url, - 'mediaElement': mediaElement + const host = new cast.player.api.Host({ + "url": url, + "mediaElement": mediaElement }); if (ext === 'm3u8' || @@ -474,17 +486,19 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa mediaElement.autoplay = false; - self._castPlayer = new cast.player.api.Player(host); + this._castPlayer = new cast.player.api.Player(host); - self._castPlayer.load(protocol, data.currentTime || 0); + this._castPlayer.load(protocol, data.currentTime || 0); - self._castPlayer.playWhenHaveEnoughData(); + this._castPlayer.playWhenHaveEnoughData(); } - function initMediaManager() { - + /** + * @private + */ + initMediaManager() { mediaManager.defaultOnLoad = mediaManager.onLoad.bind(mediaManager); - mediaManager.onLoad = onMediaManagerLoadMedia.bind(self); + mediaManager.onLoad = this.onMediaManagerLoadMedia.bind(this); //mediaManager.defaultOnPlay = mediaManager.onPlay.bind(mediaManager); //mediaManager.onPlay = function (event) { @@ -499,38 +513,40 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa }; } - function setCurrentSrc(elem, options) { + /** + * @private + */ + setCurrentSrc(elem, options) { + elem.removeEventListener('error', this.onError.bind(this)); - elem.removeEventListener('error', onError); - - var val = options.url; + let val = options.url; console.debug('playing url: ' + val); // Convert to seconds - var seconds = (options.playerStartPositionTicks || 0) / 10000000; + const seconds = (options.playerStartPositionTicks || 0) / 10000000; if (seconds) { val += '#t=' + seconds; } - htmlMediaHelper.destroyHlsPlayer(self); - htmlMediaHelper.destroyFlvPlayer(self); - htmlMediaHelper.destroyCastPlayer(self); + htmlMediaHelper.destroyHlsPlayer(this); + htmlMediaHelper.destroyFlvPlayer(this); + htmlMediaHelper.destroyCastPlayer(this); - var tracks = getMediaStreamTextTracks(options.mediaSource); + const tracks = getMediaStreamTextTracks(options.mediaSource); - subtitleTrackIndexToSetOnPlaying = options.mediaSource.DefaultSubtitleStreamIndex == null ? -1 : options.mediaSource.DefaultSubtitleStreamIndex; - if (subtitleTrackIndexToSetOnPlaying != null && subtitleTrackIndexToSetOnPlaying >= 0) { - var initialSubtitleStream = options.mediaSource.MediaStreams[subtitleTrackIndexToSetOnPlaying]; + this.subtitleTrackIndexToSetOnPlaying = options.mediaSource.DefaultSubtitleStreamIndex == null ? -1 : options.mediaSource.DefaultSubtitleStreamIndex; + if (this.subtitleTrackIndexToSetOnPlaying != null && this.subtitleTrackIndexToSetOnPlaying >= 0) { + const initialSubtitleStream = options.mediaSource.MediaStreams[this.subtitleTrackIndexToSetOnPlaying]; if (!initialSubtitleStream || initialSubtitleStream.DeliveryMethod === 'Encode') { - subtitleTrackIndexToSetOnPlaying = -1; + this.subtitleTrackIndexToSetOnPlaying = -1; } } - audioTrackIndexToSetOnPlaying = options.playMethod === 'Transcode' ? null : options.mediaSource.DefaultAudioStreamIndex; + this.audioTrackIndexToSetOnPlaying = options.playMethod === 'Transcode' ? null : options.mediaSource.DefaultAudioStreamIndex; - self._currentPlayOptions = options; + this._currentPlayOptions = options; - var crossOrigin = htmlMediaHelper.getCrossOriginValue(options.mediaSource); + const crossOrigin = htmlMediaHelper.getCrossOriginValue(options.mediaSource); if (crossOrigin) { elem.crossOrigin = crossOrigin; } @@ -541,58 +557,57 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa return setSrcWithShakaPlayer(self, elem, options, val); - } else*/ if (browser.chromecast && val.indexOf('.m3u8') !== -1 && options.mediaSource.RunTimeTicks) { + } else*/ + if (browser.chromecast && val.indexOf('.m3u8') !== -1 && options.mediaSource.RunTimeTicks) { - return setCurrentSrcChromecast(self, elem, options, val); + return this.setCurrentSrcChromecast(this, elem, options, val); } else if (htmlMediaHelper.enableHlsJsPlayer(options.mediaSource.RunTimeTicks, 'Video') && val.indexOf('.m3u8') !== -1) { - return setSrcWithHlsJs(self, elem, options, val); + return this.setSrcWithHlsJs(this, elem, options, val); } else if (options.playMethod !== 'Transcode' && options.mediaSource.Container === 'flv') { - - return setSrcWithFlvJs(self, elem, options, val); - + return this.setSrcWithFlvJs(this, elem, options, val); } else { - elem.autoplay = true; // Safari will not send cookies without this elem.crossOrigin = 'use-credentials'; - return htmlMediaHelper.applySrc(elem, val, options).then(function () { + return htmlMediaHelper.applySrc(elem, val, options).then(() => { + this._currentSrc = val; - self._currentSrc = val; - - return htmlMediaHelper.playWithPromise(elem, onError); + return htmlMediaHelper.playWithPromise(elem, this.onError.bind(this)); }); } } - self.setSubtitleStreamIndex = function (index) { + setSubtitleStreamIndex(index) { + this.setCurrentTrackElement(index); + } - setCurrentTrackElement(index); - }; + resetSubtitleOffset() { + this.currentTrackOffset = 0; + this.showTrackOffset = false; + } - self.resetSubtitleOffset = function() { - currentTrackOffset = 0; - showTrackOffset = false; - }; + enableShowingSubtitleOffset() { + this.showTrackOffset = true; + } - self.enableShowingSubtitleOffset = function() { - showTrackOffset = true; - }; + disableShowingSubtitleOffset() { + this.showTrackOffset = false; + } - self.disableShowingSubtitleOffset = function() { - showTrackOffset = false; - }; + isShowingSubtitleOffsetEnabled() { + return this.showTrackOffset; + } - self.isShowingSubtitleOffsetEnabled = function() { - return showTrackOffset; - }; - - function getTextTrack() { - var videoElement = self._mediaElement; + /** + * @private + */ + getTextTrack() { + const videoElement = this._mediaElement; if (videoElement) { return Array.from(videoElement.textTracks) - .find(function(trackElement) { + .find(function (trackElement) { // get showing .vtt textTack return trackElement.mode === 'showing'; }); @@ -601,69 +616,80 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa } } - self.setSubtitleOffset = function(offset) { - - var offsetValue = parseFloat(offset); + /** + * @private + */ + setSubtitleOffset(offset) { + const offsetValue = parseFloat(offset); // if .ass currently rendering - if (currentSubtitlesOctopus) { - updateCurrentTrackOffset(offsetValue); - currentSubtitlesOctopus.timeOffset = (self._currentPlayOptions.transcodingOffsetTicks || 0) / 10000000 + offsetValue; + if (this.currentSubtitlesOctopus) { + this.updateCurrentTrackOffset(offsetValue); + this.currentSubtitlesOctopus.timeOffset = (this._currentPlayOptions.transcodingOffsetTicks || 0) / 10000000 + offsetValue;; } else { - var trackElement = getTextTrack(); + const trackElement = this.getTextTrack(); // if .vtt currently rendering if (trackElement) { - setTextTrackSubtitleOffset(trackElement, offsetValue); - } else if (currentTrackEvents) { - setTrackEventsSubtitleOffset(currentTrackEvents, offsetValue); + this.setTextTrackSubtitleOffset(trackElement, offsetValue); + } else if (this.currentTrackEvents) { + this.setTrackEventsSubtitleOffset(this.currentTrackEvents, offsetValue); } else { console.debug('No available track, cannot apply offset: ', offsetValue); } } - }; + } - function updateCurrentTrackOffset(offsetValue) { - - var relativeOffset = offsetValue; - var newTrackOffset = offsetValue; - if (currentTrackOffset) { - relativeOffset -= currentTrackOffset; + /** + * @private + */ + updateCurrentTrackOffset(offsetValue) { + let relativeOffset = offsetValue; + const newTrackOffset = offsetValue; + if (this.currentTrackOffset) { + relativeOffset -= this.currentTrackOffset; } - currentTrackOffset = newTrackOffset; + this.currentTrackOffset = newTrackOffset; // relative to currentTrackOffset return relativeOffset; } - function setTextTrackSubtitleOffset(currentTrack, offsetValue) { - + /** + * @private + */ + setTextTrackSubtitleOffset(currentTrack, offsetValue) { if (currentTrack.cues) { - offsetValue = updateCurrentTrackOffset(offsetValue); + offsetValue = this.updateCurrentTrackOffset(offsetValue); Array.from(currentTrack.cues) - .forEach(function(cue) { + .forEach(function (cue) { cue.startTime -= offsetValue; cue.endTime -= offsetValue; }); } } - function setTrackEventsSubtitleOffset(trackEvents, offsetValue) { - + /** + * @private + */ + setTrackEventsSubtitleOffset(trackEvents, offsetValue) { if (Array.isArray(trackEvents)) { - offsetValue = updateCurrentTrackOffset(offsetValue) * 1e7; // ticks - trackEvents.forEach(function(trackEvent) { + offsetValue = this.updateCurrentTrackOffset(offsetValue) * 1e7; // ticks + trackEvents.forEach(function (trackEvent) { trackEvent.StartPositionTicks -= offsetValue; trackEvent.EndPositionTicks -= offsetValue; }); } } - self.getSubtitleOffset = function() { - return currentTrackOffset; - }; + getSubtitleOffset() { + return this.currentTrackOffset; + } - function isAudioStreamSupported(stream, deviceProfile) { + /** + * @private + */ + isAudioStreamSupported(stream, deviceProfile) { - var codec = (stream.Codec || '').toLowerCase(); + const codec = (stream.Codec || "").toLowerCase(); if (!codec) { return true; @@ -674,7 +700,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa return true; } - var profiles = deviceProfile.DirectPlayProfiles || []; + const profiles = deviceProfile.DirectPlayProfiles || []; return profiles.filter(function (p) { @@ -692,27 +718,30 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa }).length > 0; } - function getSupportedAudioStreams() { - var profile = self._lastProfile; + /** + * @private + */ + getSupportedAudioStreams() { + const profile = self._lastProfile; - return getMediaStreamAudioTracks(self._currentPlayOptions.mediaSource).filter(function (stream) { - return isAudioStreamSupported(stream, profile); + return getMediaStreamAudioTracks(self._currentPlayOptions.mediaSource).filter((stream) => { + return this.isAudioStreamSupported(stream, profile); }); } - self.setAudioStreamIndex = function (index) { + setAudioStreamIndex(index) { - var streams = getSupportedAudioStreams(); + const streams = this.getSupportedAudioStreams(); if (streams.length < 2) { // If there's only one supported stream then trust that the player will handle it on it's own return; } - var audioIndex = -1; - var i; - var length; - var stream; + let audioIndex = -1; + let i; + let length; + let stream; for (i = 0, length = streams.length; i < length; i++) { stream = streams[i]; @@ -728,14 +757,14 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa return; } - var elem = self._mediaElement; + const elem = self._mediaElement; if (!elem) { return; } // https://msdn.microsoft.com/en-us/library/hh772507(v=vs.85).aspx - var elemAudioTracks = elem.audioTracks || []; + const elemAudioTracks = elem.audioTracks || []; console.debug('found ' + elemAudioTracks.length + ' audio tracks'); for (i = 0, length = elemAudioTracks.length; i < length; i++) { @@ -748,188 +777,222 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa elemAudioTracks[i].enabled = false; } } - }; + } - self.stop = function (destroyPlayer) { - var elem = self._mediaElement; - var src = self._currentSrc; + stop(destroyPlayer) { + const elem = this._mediaElement; + const src = this._currentSrc; if (elem) { if (src) { elem.pause(); } - htmlMediaHelper.onEndedInternal(self, elem, onError); + htmlMediaHelper.onEndedInternal(this, elem, this.onError.bind(this)); if (destroyPlayer) { - self.destroy(); + this.destroy(); } } - destroyCustomTrack(elem); + this.destroyCustomTrack(elem); return Promise.resolve(); - }; + } - self.destroy = function () { - htmlMediaHelper.destroyHlsPlayer(self); - htmlMediaHelper.destroyFlvPlayer(self); + destroy() { + htmlMediaHelper.destroyHlsPlayer(this); + htmlMediaHelper.destroyFlvPlayer(this); appRouter.setTransparency('none'); - var videoElement = self._mediaElement; + const videoElement = this._mediaElement; if (videoElement) { - self._mediaElement = null; + this._mediaElement = null; - destroyCustomTrack(videoElement); - videoElement.removeEventListener('timeupdate', onTimeUpdate); - videoElement.removeEventListener('ended', onEnded); - videoElement.removeEventListener('volumechange', onVolumeChange); - videoElement.removeEventListener('pause', onPause); - videoElement.removeEventListener('playing', onPlaying); - videoElement.removeEventListener('play', onPlay); - videoElement.removeEventListener('click', onClick); - videoElement.removeEventListener('dblclick', onDblClick); - videoElement.removeEventListener('waiting', onWaiting); + this.destroyCustomTrack(videoElement); + videoElement.removeEventListener('timeupdate', this.onTimeUpdate.bind(this)); + videoElement.removeEventListener('ended', this.onEnded.bind(this)); + videoElement.removeEventListener('volumechange', this.onVolumeChange.bind(this)); + videoElement.removeEventListener('pause', this.onPause.bind(this)); + videoElement.removeEventListener('playing', this.onPlaying.bind(this)); + videoElement.removeEventListener('play', this.onPlay.bind(this)); + videoElement.removeEventListener('click', this.onClick.bind(this)); + videoElement.removeEventListener('dblclick', this.onDblClick.bind(this)); + videoElement.removeEventListener('waiting', this.onWaiting.bind(this)); videoElement.parentNode.removeChild(videoElement); } - var dlg = videoDialog; + const dlg = this.videoDialog; if (dlg) { - videoDialog = null; + this.videoDialog = null; dlg.parentNode.removeChild(dlg); } if (screenfull.isEnabled) { screenfull.exit(); } - }; - - function onEnded() { - - destroyCustomTrack(this); - htmlMediaHelper.onEndedInternal(self, this, onError); } - function onTimeUpdate(e) { - // get the player position and the transcoding offset - var time = this.currentTime; + /** + * @private + */ + onEnded() { + this.destroyCustomTrack(this); + htmlMediaHelper.onEndedInternal(this, this.onEnded.bind(this), this.onError.bind(this)); + } - if (time && !self._timeUpdated) { - self._timeUpdated = true; - ensureValidVideo(this); + /** + * @private + */ + onTimeUpdate(e) { + // get the player position and the transcoding offset + const time = this.currentTime; + + if (time && !this._timeUpdated) { + this._timeUpdated = true; + this.ensureValidVideo(this); } - self._currentTime = time; + this._currentTime = time; - var currentPlayOptions = self._currentPlayOptions; + const currentPlayOptions = this._currentPlayOptions; // Not sure yet how this is coming up null since we never null it out, but it is causing app crashes if (currentPlayOptions) { - var timeMs = time * 1000; + let timeMs = time * 1000; timeMs += ((currentPlayOptions.transcodingOffsetTicks || 0) / 10000); - updateSubtitleText(timeMs); + this.updateSubtitleText(timeMs); } - events.trigger(self, 'timeupdate'); + events.trigger(this, 'timeupdate'); } - function onVolumeChange() { + /** + * @private + */ + onVolumeChange() { htmlMediaHelper.saveVolume(this.volume); - events.trigger(self, 'volumechange'); + events.trigger(this, 'volumechange'); } - function onNavigatedToOsd() { - var dlg = videoDialog; + /** + * @private + */ + onNavigatedToOsd() { + const dlg = this.videoDialog; if (dlg) { dlg.classList.remove('videoPlayerContainer-onTop'); - onStartedAndNavigatedToOsd(); + this.onStartedAndNavigatedToOsd(); } } - function onStartedAndNavigatedToOsd() { + /** + * @private + */ + onStartedAndNavigatedToOsd() { // If this causes a failure during navigation we end up in an awkward UI state - setCurrentTrackElement(subtitleTrackIndexToSetOnPlaying); + this.setCurrentTrackElement(this.subtitleTrackIndexToSetOnPlaying); - if (audioTrackIndexToSetOnPlaying != null && self.canSetAudioStreamIndex()) { - self.setAudioStreamIndex(audioTrackIndexToSetOnPlaying); + if (this.audioTrackIndexToSetOnPlaying != null && self.canSetAudioStreamIndex()) { + self.setAudioStreamIndex(this.audioTrackIndexToSetOnPlaying); } } - function onPlaying(e) { - if (!self._started) { - self._started = true; - this.removeAttribute('controls'); + /** + * @private + */ + onPlaying(e) { + if (!this._started) { + this._started = true; + this.onPlaying.removeAttribute('controls'); loading.hide(); - htmlMediaHelper.seekOnPlaybackStart(self, e.target, self._currentPlayOptions.playerStartPositionTicks, function () { - if (currentSubtitlesOctopus) { - currentSubtitlesOctopus.timeOffset = (self._currentPlayOptions.transcodingOffsetTicks || 0) / 10000000 + currentTrackOffset; - currentSubtitlesOctopus.resize(); - currentSubtitlesOctopus.resetRenderAheadCache(false); + htmlMediaHelper.seekOnPlaybackStart(this, e.target, this._currentPlayOptions.playerStartPositionTicks, function () { + if (this.currentSubtitlesOctopus) { + this.currentSubtitlesOctopus.timeOffset = (this._currentPlayOptions.transcodingOffsetTicks || 0) / 10000000 + currentTrackOffset; + this.currentSubtitlesOctopus.resize(); + this.currentSubtitlesOctopus.resetRenderAheadCache(false); } }); - if (self._currentPlayOptions.fullscreen) { + if (this._currentPlayOptions.fullscreen) { - appRouter.showVideoOsd().then(onNavigatedToOsd); + appRouter.showVideoOsd().then(this.onNavigatedToOsd.bind(this)); } else { appRouter.setTransparency('backdrop'); - videoDialog.classList.remove('videoPlayerContainer-onTop'); + this.videoDialog.classList.remove('videoPlayerContainer-onTop'); - onStartedAndNavigatedToOsd(); + this.onStartedAndNavigatedToOsd(); } } - events.trigger(self, 'playing'); + events.trigger(this, 'playing'); } - function onPlay(e) { - events.trigger(self, 'unpause'); + /** + * @private + */ + onPlay(e) { + events.trigger(this, 'unpause'); } - function ensureValidVideo(elem) { - if (elem !== self._mediaElement) { + /** + * @private + */ + ensureValidVideo(elem) { + if (elem !== this._mediaElement) { return; } if (elem.videoWidth === 0 && elem.videoHeight === 0) { - var mediaSource = (self._currentPlayOptions || {}).mediaSource; + const mediaSource = (this._currentPlayOptions || {}).mediaSource; // Only trigger this if there is media info // Avoid triggering in situations where it might not actually have a video stream (audio only live tv channel) if (!mediaSource || mediaSource.RunTimeTicks) { - htmlMediaHelper.onErrorInternal(self, 'mediadecodeerror'); - return; + htmlMediaHelper.onErrorInternal(this, 'mediadecodeerror'); } } } - function onClick() { - events.trigger(self, 'click'); + /** + * @private + */ + onClick() { + events.trigger(this, 'click'); } - function onDblClick() { - events.trigger(self, 'dblclick'); + /** + * @private + */ + onDblClick() { + events.trigger(this, 'dblclick'); } - function onPause() { - events.trigger(self, 'pause'); + /** + * @private + */ + onPause() { + events.trigger(this, 'pause'); } - function onWaiting() { - events.trigger(self, 'waiting'); + onWaiting() { + events.trigger(this, 'waiting'); } - function onError() { - var errorCode = this.error ? (this.error.code || 0) : 0; - var errorMessage = this.error ? (this.error.message || '') : ''; + /** + * @private + */ + onError() { + const errorCode = this.onError.error ? (this.onError.error.code || 0) : 0; + const errorMessage = this.onError.error ? (this.onError.error.message || "") : ""; console.error('media element error: ' + errorCode.toString() + ' ' + errorMessage); - var type; + let type; switch (errorCode) { case 1: @@ -959,30 +1022,33 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa return; } - htmlMediaHelper.onErrorInternal(self, type); + htmlMediaHelper.onErrorInternal(this, type); } - function destroyCustomTrack(videoElement) { - if (self._resizeObserver) { - self._resizeObserver.disconnect(); - self._resizeObserver = null; + /** + * @private + */ + destroyCustomTrack(videoElement) { + if (this._resizeObserver) { + this._resizeObserver.disconnect(); + this._resizeObserver = null; } - if (videoSubtitlesElem) { - var subtitlesContainer = videoSubtitlesElem.parentNode; + if (this.videoSubtitlesElem) { + const subtitlesContainer = this.videoSubtitlesElem.parentNode; if (subtitlesContainer) { tryRemoveElement(subtitlesContainer); } - videoSubtitlesElem = null; + this.videoSubtitlesElem = null; } - currentTrackEvents = null; + this.currentTrackEvents = null; if (videoElement) { - var allTracks = videoElement.textTracks || []; // get list of tracks - for (var i = 0; i < allTracks.length; i++) { + const allTracks = videoElement.textTracks || []; // get list of tracks + for (let i = 0; i < allTracks.length; i++) { - var currentTrack = allTracks[i]; + const currentTrack = allTracks[i]; if (currentTrack.label.indexOf('manualTrack') !== -1) { currentTrack.mode = 'disabled'; @@ -990,85 +1056,94 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa } } - customTrackIndex = -1; - currentClock = null; - self._currentAspectRatio = null; + this.customTrackIndex = -1; + this.currentClock = null; + this._currentAspectRatio = null; - var octopus = currentSubtitlesOctopus; + const octopus = this.currentSubtitlesOctopus; if (octopus) { octopus.dispose(); } - currentSubtitlesOctopus = null; + this.currentSubtitlesOctopus = null; - var renderer = currentAssRenderer; + const renderer = this.currentAssRenderer; if (renderer) { renderer.setEnabled(false); } - currentAssRenderer = null; + this.currentAssRenderer = null; } - self.destroyCustomTrack = destroyCustomTrack; - - function fetchSubtitlesUwp(track, item) { + /** + * @private + */ + fetchSubtitlesUwp(track, item) { return Windows.Storage.StorageFile.getFileFromPathAsync(track.Path).then(function (storageFile) { - return Windows.Storage.FileIO.readTextAsync(storageFile).then(function (text) { - return JSON.parse(text); - }); + return Windows.Storage.FileIO.readTextAsync(storageFile); + }).then(function (text) { + return JSON.parse(text); }); } - function fetchSubtitles(track, item) { + /** + * @private + */ + fetchSubtitles(track, item) { if (window.Windows && itemHelper.isLocalItem(item)) { - return fetchSubtitlesUwp(track, item); + return this.fetchSubtitlesUwp(track, item); } - incrementFetchQueue(); - return new Promise(function (resolve, reject) { - var xhr = new XMLHttpRequest(); + this.incrementFetchQueue(); + return new Promise((resolve, reject) => { + const xhr = new XMLHttpRequest(); - var url = getTextTrackUrl(track, item, '.js'); + const url = getTextTrackUrl(track, item, ".js"); xhr.open('GET', url, true); - xhr.onload = function (e) { + xhr.onload = (e) => { resolve(JSON.parse(this.response)); - decrementFetchQueue(); + this.decrementFetchQueue(); }; - xhr.onerror = function (e) { + xhr.onerror = (e) => { reject(e); - decrementFetchQueue(); + this.decrementFetchQueue(); }; xhr.send(); }); } - function setTrackForDisplay(videoElement, track) { - + /** + * @private + */ + setTrackForDisplay(videoElement, track) { if (!track) { - destroyCustomTrack(videoElement); + this.destroyCustomTrack(videoElement); return; } // skip if already playing this track - if (customTrackIndex === track.Index) { + if (this.customTrackIndex === track.Index) { return; } - self.resetSubtitleOffset(); - var item = self._currentPlayOptions.item; + this.resetSubtitleOffset(); + const item = self._currentPlayOptions.item; - destroyCustomTrack(videoElement); - customTrackIndex = track.Index; - renderTracksEvents(videoElement, track, item); - lastCustomTrackMs = 0; + this.destroyCustomTrack(videoElement); + this.customTrackIndex = track.Index; + this.renderTracksEvents(videoElement, track, item); + this.lastCustomTrackMs = 0; } - function renderSsaAss(videoElement, track, item) { - var attachments = self._currentPlayOptions.mediaSource.MediaAttachments || []; - var apiClient = connectionManager.getApiClient(item); - var options = { + /** + * @private + */ + renderSsaAss(videoElement, track, item) { + const attachments = self._currentPlayOptions.mediaSource.MediaAttachments || []; + const apiClient = connectionManager.getApiClient(item); + const options = { video: videoElement, subUrl: getTextTrackUrl(track, item), fonts: attachments.map(function (i) { @@ -1076,13 +1151,13 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa }), workerUrl: appRouter.baseUrl() + '/libraries/subtitles-octopus-worker.js', legacyWorkerUrl: appRouter.baseUrl() + '/libraries/subtitles-octopus-worker-legacy.js', - onError: function() { + onError() { htmlMediaHelper.onErrorInternal(self, 'mediadecodeerror'); }, - timeOffset: (self._currentPlayOptions.transcodingOffsetTicks || 0) / 10000000, + timeOffset: (this._currentPlayOptions.transcodingOffsetTicks || 0) / 10000000, // new octopus options; override all, even defaults - renderMode: 'blend', + renderMode: "blend", dropAllAnimations: false, libassMemoryLimit: 40, libassGlyphLimit: 40, @@ -1093,13 +1168,15 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa resizeVariation: 0.2, renderAhead: 90 }; - require(['JavascriptSubtitlesOctopus'], function(SubtitlesOctopus) { - currentSubtitlesOctopus = new SubtitlesOctopus(options); + import('JavascriptSubtitlesOctopus').then(SubtitlesOctopus => { + this.currentSubtitlesOctopus = new SubtitlesOctopus(options); }); } - function requiresCustomSubtitlesElement() { - + /** + * @private + */ + requiresCustomSubtitlesElement() { // after a system update, ps4 isn't showing anything when creating a track element dynamically // going to have to do it ourselves if (browser.ps4) { @@ -1116,7 +1193,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa } if (browser.iOS) { - var userAgent = navigator.userAgent.toLowerCase(); + const userAgent = navigator.userAgent.toLowerCase(); // works in the browser but not the native app if ((userAgent.indexOf('os 9') !== -1 || userAgent.indexOf('os 8') !== -1) && userAgent.indexOf('safari') === -1) { return true; @@ -1126,22 +1203,28 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa return false; } - function renderSubtitlesWithCustomElement(videoElement, track, item) { - fetchSubtitles(track, item).then(function (data) { - if (!videoSubtitlesElem) { - var subtitlesContainer = document.createElement('div'); + /** + * @private + */ + renderSubtitlesWithCustomElement(videoElement, track, item) { + this.fetchSubtitles(track, item).then((data) => { + if (!this.videoSubtitlesElem) { + const subtitlesContainer = document.createElement("div"); subtitlesContainer.classList.add('videoSubtitles'); subtitlesContainer.innerHTML = '
'; - videoSubtitlesElem = subtitlesContainer.querySelector('.videoSubtitlesInner'); - setSubtitleAppearance(subtitlesContainer, videoSubtitlesElem); + this.videoSubtitlesElem = subtitlesContainer.querySelector('.videoSubtitlesInner'); + this.setSubtitleAppearance(subtitlesContainer, this.videoSubtitlesElem); videoElement.parentNode.appendChild(subtitlesContainer); - currentTrackEvents = data.TrackEvents; + this.currentTrackEvents = data.TrackEvents; } }); } - function setSubtitleAppearance(elem, innerElem) { - require(['userSettings', 'subtitleAppearanceHelper'], function (userSettings, subtitleAppearanceHelper) { + /** + * @private + */ + setSubtitleAppearance(elem, innerElem) { + Promise.all([import('userSettings'), import('subtitleAppearanceHelper')]).then(([userSettings, subtitleAppearanceHelper]) => { subtitleAppearanceHelper.applyStyles({ text: innerElem, window: elem @@ -1149,9 +1232,12 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa }); } - function getCueCss(appearance, selector) { + /** + * @private + */ + getCueCss(appearance, selector) { - var html = selector + '::cue {'; + let html = selector + "::cue {"; html += appearance.text.map(function (s) { @@ -1164,13 +1250,16 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa return html; } - function setCueAppearance() { + /** + * @private + */ + setCueAppearance() { - require(['userSettings', 'subtitleAppearanceHelper'], function (userSettings, subtitleAppearanceHelper) { + Promise.all([import('userSettings'), import('subtitleAppearanceHelper')]).then(([userSettings, subtitleAppearanceHelper]) => { - var elementId = self.id + '-cuestyle'; + const elementId = self.id + "-cuestyle"; - var styleElem = document.querySelector('#' + elementId); + let styleElem = document.querySelector("#" + elementId); if (!styleElem) { styleElem = document.createElement('style'); styleElem.id = elementId; @@ -1178,26 +1267,28 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa document.getElementsByTagName('head')[0].appendChild(styleElem); } - styleElem.innerHTML = getCueCss(subtitleAppearanceHelper.getStyles(userSettings.getSubtitleAppearanceSettings(), true), '.htmlvideoplayer'); + styleElem.innerHTML = this.getCueCss(subtitleAppearanceHelper.getStyles(userSettings.getSubtitleAppearanceSettings(), true), '.htmlvideoplayer'); }); } - function renderTracksEvents(videoElement, track, item) { - + /** + * @private + */ + renderTracksEvents(videoElement, track, item) { if (!itemHelper.isLocalItem(item) || track.IsExternal) { - var format = (track.Codec || '').toLowerCase(); + const format = (track.Codec || "").toLowerCase(); if (format === 'ssa' || format === 'ass') { - renderSsaAss(videoElement, track, item); + this.renderSsaAss(videoElement, track, item); return; } - if (requiresCustomSubtitlesElement()) { - renderSubtitlesWithCustomElement(videoElement, track, item); + if (this.requiresCustomSubtitlesElement()) { + this.renderSubtitlesWithCustomElement(videoElement, track, item); return; } } - var trackElement = null; + let trackElement = null; if (videoElement.textTracks && videoElement.textTracks.length > 0) { trackElement = videoElement.textTracks[0]; @@ -1220,7 +1311,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa } // download the track json - fetchSubtitles(track, item).then(function (data) { + this.fetchSubtitles(track, item).then(function (data) { // show in ui console.debug('downloaded ' + data.TrackEvents.length + ' track events'); @@ -1228,8 +1319,8 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa // in safari, the cues need to be added before setting the track mode to showing data.TrackEvents.forEach(function (trackEvent) { - var trackCueObject = window.VTTCue || window.TextTrackCue; - var cue = new trackCueObject(trackEvent.StartPositionTicks / 10000000, trackEvent.EndPositionTicks / 10000000, normalizeTrackEventText(trackEvent.Text, false)); + const trackCueObject = window.VTTCue || window.TextTrackCue; + const cue = new trackCueObject(trackEvent.StartPositionTicks / 10000000, trackEvent.EndPositionTicks / 10000000, normalizeTrackEventText(trackEvent.Text, false)); trackElement.addCue(cue); }); @@ -1237,9 +1328,11 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa }); } - function updateSubtitleText(timeMs) { - - var clock = currentClock; + /** + * @private + */ + updateSubtitleText(timeMs) { + const clock = this.currentClock; if (clock) { try { clock.seek(timeMs / 1000); @@ -1249,15 +1342,15 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa return; } - var trackEvents = currentTrackEvents; - var subtitleTextElement = videoSubtitlesElem; + const trackEvents = this.currentTrackEvents; + const subtitleTextElement = this.videoSubtitlesElem; if (trackEvents && subtitleTextElement) { - var ticks = timeMs * 10000; - var selectedTrackEvent; - for (var i = 0; i < trackEvents.length; i++) { + const ticks = timeMs * 10000; + let selectedTrackEvent; + for (let i = 0; i < trackEvents.length; i++) { - var currentTrackEvent = trackEvents[i]; + const currentTrackEvent = trackEvents[i]; if (currentTrackEvent.StartPositionTicks <= ticks && currentTrackEvent.EndPositionTicks >= ticks) { selectedTrackEvent = currentTrackEvent; break; @@ -1274,20 +1367,23 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa } } - function setCurrentTrackElement(streamIndex) { + /** + * @private + */ + setCurrentTrackElement(streamIndex) { console.debug('setting new text track index to: ' + streamIndex); - var mediaStreamTextTracks = getMediaStreamTextTracks(self._currentPlayOptions.mediaSource); + const mediaStreamTextTracks = getMediaStreamTextTracks(this._currentPlayOptions.mediaSource); - var track = streamIndex === -1 ? null : mediaStreamTextTracks.filter(function (t) { + let track = streamIndex === -1 ? null : mediaStreamTextTracks.filter(function (t) { return t.Index === streamIndex; })[0]; - setTrackForDisplay(self._mediaElement, track); - if (enableNativeTrackSupport(self._currentSrc, track)) { + this.setTrackForDisplay(this._mediaElement, track); + if (enableNativeTrackSupport(this._currentSrc, track)) { if (streamIndex !== -1) { - setCueAppearance(); + this.setCueAppearance(); } } else { @@ -1297,19 +1393,17 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa } } - function createMediaElement(options) { - - return new Promise(function (resolve, reject) { - - var dlg = document.querySelector('.videoPlayerContainer'); + /** + * @private + */ + createMediaElement(options) { + const dlg = document.querySelector(".videoPlayerContainer"); if (!dlg) { - - require(['css!./style'], function () { - + return import('css!./style').then(() => { loading.show(); - var dlg = document.createElement('div'); + const dlg = document.createElement("div"); dlg.classList.add('videoPlayerContainer'); @@ -1317,8 +1411,8 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa dlg.classList.add('videoPlayerContainer-onTop'); } - var html = ''; - var cssClass = 'htmlvideoplayer'; + let html = ""; + let cssClass = "htmlvideoplayer"; if (!browser.chromecast) { cssClass += ' htmlvideoplayer-moveupsubtitles'; @@ -1335,29 +1429,29 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa html += ''; dlg.innerHTML = html; - var videoElement = dlg.querySelector('video'); + const videoElement = dlg.querySelector("video"); videoElement.volume = htmlMediaHelper.getSavedVolume(); - videoElement.addEventListener('timeupdate', onTimeUpdate); - videoElement.addEventListener('ended', onEnded); - videoElement.addEventListener('volumechange', onVolumeChange); - videoElement.addEventListener('pause', onPause); - videoElement.addEventListener('playing', onPlaying); - videoElement.addEventListener('play', onPlay); - videoElement.addEventListener('click', onClick); - videoElement.addEventListener('dblclick', onDblClick); - videoElement.addEventListener('waiting', onWaiting); + videoElement.addEventListener('timeupdate', this.onTimeUpdate); + videoElement.addEventListener('ended', this.onEnded); + videoElement.addEventListener('volumechange', this.onVolumeChange); + videoElement.addEventListener('pause', this.onPause); + videoElement.addEventListener('playing', this.onPlaying); + videoElement.addEventListener('play', this.onPlay); + videoElement.addEventListener('click', this.onClick); + videoElement.addEventListener('dblclick', this.onDblClick); + videoElement.addEventListener('waiting', this.onWaiting); if (options.backdropUrl) { videoElement.poster = options.backdropUrl; } document.body.insertBefore(dlg, document.body.firstChild); - videoDialog = dlg; - self._mediaElement = videoElement; + this.videoDialog = dlg; + this._mediaElement = videoElement; if (mediaManager) { if (!mediaManager.embyInit) { - initMediaManager(); + this.initMediaManager(); mediaManager.embyInit = true; } mediaManager.setMediaElement(videoElement); @@ -1366,41 +1460,50 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa // don't animate on smart tv's, too slow if (options.fullscreen && browser.supportsCssAnimation() && !browser.slow) { zoomIn(dlg).then(function () { - resolve(videoElement); + return videoElement; }); } else { hidePrePlaybackPage(); - resolve(videoElement); + return videoElement; } }); } else { - resolve(dlg.querySelector('video')); + return Promise.resolve(dlg.querySelector('video')); } - }); } + + /** + * @private + */ + canPlayMediaType(mediaType) { + return (mediaType || '').toLowerCase() === 'video'; } - HtmlVideoPlayer.prototype.canPlayMediaType = function (mediaType) { - return (mediaType || '').toLowerCase() === 'video'; - }; - - HtmlVideoPlayer.prototype.supportsPlayMethod = function (playMethod, item) { + /** + * @private + */ + supportsPlayMethod(playMethod, item) { if (appHost.supportsPlayMethod) { return appHost.supportsPlayMethod(playMethod, item); } return true; - }; + } - HtmlVideoPlayer.prototype.getDeviceProfile = function (item, options) { - var instance = this; - return getDeviceProfileInternal(item, options).then(function (profile) { - instance._lastProfile = profile; + /** + * @private + */ + getDeviceProfile(item, options) { + return HtmlVideoPlayer.getDeviceProfileInternal(item, options).then((profile) => { + this._lastProfile = profile; return profile; }); - }; + } - function getDeviceProfileInternal(item, options) { + /** + * @private + */ + static getDeviceProfileInternal(item, options) { if (appHost.getDeviceProfile) { return appHost.getDeviceProfile(item, options); } @@ -1408,14 +1511,14 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa return getDefaultProfile(); } - var supportedFeatures; + /** + * @private + */ + static getSupportedFeatures() { + const list = []; - function getSupportedFeatures() { - - var list = []; - - var video = document.createElement('video'); - if (video.webkitSupportsPresentationMode && typeof video.webkitSetPresentationMode === 'function' || document.pictureInPictureEnabled) { + const video = document.createElement("video"); + if (video.webkitSupportsPresentationMode && typeof video.webkitSetPresentationMode === "function" || document.pictureInPictureEnabled) { list.push('PictureInPicture'); } else if (window.Windows) { if (Windows.UI.ViewManagement.ApplicationView.getForCurrentView().isViewModeSupported(Windows.UI.ViewManagement.ApplicationViewMode.compactOverlay)) { @@ -1432,57 +1535,55 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa } list.push('SetBrightness'); - list.push('SetAspectRatio'); + list.push("SetAspectRatio"); return list; } - HtmlVideoPlayer.prototype.supports = function (feature) { - if (!supportedFeatures) { - supportedFeatures = getSupportedFeatures(); + supports(feature) { + if (!this.supportedFeatures) { + this.supportedFeatures = HtmlVideoPlayer.getSupportedFeatures(); } - return supportedFeatures.indexOf(feature) !== -1; - }; + return this.supportedFeatures.contains(feature); + } // Save this for when playback stops, because querying the time at that point might return 0 - HtmlVideoPlayer.prototype.currentTime = function (val) { - - var mediaElement = this._mediaElement; + currentTime(val) { + const mediaElement = this._mediaElement; if (mediaElement) { if (val != null) { mediaElement.currentTime = val / 1000; return; } - var currentTime = this._currentTime; + const currentTime = this._currentTime; if (currentTime) { return currentTime * 1000; } return (mediaElement.currentTime || 0) * 1000; } - }; + } - HtmlVideoPlayer.prototype.duration = function (val) { - - var mediaElement = this._mediaElement; + duration(val) { + const mediaElement = this._mediaElement; if (mediaElement) { - var duration = mediaElement.duration; + const duration = mediaElement.duration; if (htmlMediaHelper.isValidDuration(duration)) { return duration * 1000; } } return null; - }; + } - HtmlVideoPlayer.prototype.canSetAudioStreamIndex = function (index) { + canSetAudioStreamIndex(index) { if (browser.tizen || browser.orsay) { return true; } - var video = this._mediaElement; + const video = this._mediaElement; if (video) { if (video.audioTracks) { return true; @@ -1490,26 +1591,24 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa } return false; - }; + } - function onPictureInPictureError(err) { + static onPictureInPictureError(err) { console.error('Picture in picture error: ' + err.toString()); } - HtmlVideoPlayer.prototype.setPictureInPictureEnabled = function (isEnabled) { - - var video = this._mediaElement; + setPictureInPictureEnabled(isEnabled) { + const video = this._mediaElement; if (document.pictureInPictureEnabled) { if (video) { if (isEnabled) { - video.requestPictureInPicture().catch(onPictureInPictureError); + video.requestPictureInPicture().catch(HtmlVideoPlayer.onPictureInPictureError); } else { - document.exitPictureInPicture().catch(onPictureInPictureError); + document.exitPictureInPicture().catch(HtmlVideoPlayer.onPictureInPictureError); } } } else if (window.Windows) { - this.isPip = isEnabled; if (isEnabled) { Windows.UI.ViewManagement.ApplicationView.getForCurrentView().tryEnterViewModeAsync(Windows.UI.ViewManagement.ApplicationViewMode.compactOverlay); @@ -1517,93 +1616,90 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa Windows.UI.ViewManagement.ApplicationView.getForCurrentView().tryEnterViewModeAsync(Windows.UI.ViewManagement.ApplicationViewMode.default); } } else { - if (video && video.webkitSupportsPresentationMode && typeof video.webkitSetPresentationMode === 'function') { - video.webkitSetPresentationMode(isEnabled ? 'picture-in-picture' : 'inline'); + if (video && video.webkitSupportsPresentationMode && typeof video.webkitSetPresentationMode === "function") { + video.webkitSetPresentationMode(isEnabled ? "picture-in-picture" : "inline"); } } - }; - - HtmlVideoPlayer.prototype.isPictureInPictureEnabled = function () { + } + isPictureInPictureEnabled() { if (document.pictureInPictureEnabled) { return document.pictureInPictureElement ? true : false; } else if (window.Windows) { return this.isPip || false; } else { - var video = this._mediaElement; + const video = this._mediaElement; if (video) { - return video.webkitPresentationMode === 'picture-in-picture'; + return video.webkitPresentationMode === "picture-in-picture"; } } return false; - }; - - HtmlVideoPlayer.prototype.isAirPlayEnabled = function () { + } + static isAirPlayEnabled() { if (document.AirPlayEnabled) { return document.AirplayElement ? true : false; } return false; - }; + } - HtmlVideoPlayer.prototype.setAirPlayEnabled = function (isEnabled) { - var video = this._mediaElement; + setAirPlayEnabled(isEnabled) { + const video = this._mediaElement; if (document.AirPlayEnabled) { if (video) { if (isEnabled) { video.requestAirPlay().catch(function(err) { - console.error('Error requesting AirPlay', err); + console.error("Error requesting AirPlay", err); }); } else { document.exitAirPLay().catch(function(err) { - console.error('Error exiting AirPlay', err); + console.error("Error exiting AirPlay", err); }); } } } else { video.webkitShowPlaybackTargetPicker(); } - }; + } - HtmlVideoPlayer.prototype.setBrightness = function (val) { - - var elem = this._mediaElement; + setBrightness(val) { + const elem = this._mediaElement; if (elem) { val = Math.max(0, val); val = Math.min(100, val); - var rawValue = val; + let rawValue = val; rawValue = Math.max(20, rawValue); - var cssValue = rawValue >= 100 ? 'none' : (rawValue / 100); + const cssValue = rawValue >= 100 ? "none" : (rawValue / 100); elem.style['-webkit-filter'] = 'brightness(' + cssValue + ');'; elem.style.filter = 'brightness(' + cssValue + ')'; elem.brightnessValue = val; events.trigger(this, 'brightnesschange'); } - }; + } - HtmlVideoPlayer.prototype.getBrightness = function () { - var elem = this._mediaElement; + getBrightness() { + const elem = this._mediaElement; if (elem) { - var val = elem.brightnessValue; + const val = elem.brightnessValue; return val == null ? 100 : val; } - }; + } - HtmlVideoPlayer.prototype.seekable = function () { - var mediaElement = this._mediaElement; + seekable() { + const mediaElement = this._mediaElement; if (mediaElement) { - var seekable = mediaElement.seekable; + const seekable = mediaElement.seekable; if (seekable && seekable.length) { - var start = seekable.start(0); - var end = seekable.end(0); + let start = seekable.start(0); + let end = seekable.end(0); if (!htmlMediaHelper.isValidDuration(start)) { start = 0; @@ -1617,144 +1713,142 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa return false; } - }; + } - HtmlVideoPlayer.prototype.pause = function () { - var mediaElement = this._mediaElement; + pause() { + const mediaElement = this._mediaElement; if (mediaElement) { mediaElement.pause(); } - }; + } // This is a retry after error - HtmlVideoPlayer.prototype.resume = function () { - var mediaElement = this._mediaElement; + resume() { + const mediaElement = this._mediaElement; if (mediaElement) { mediaElement.play(); } - }; + } - HtmlVideoPlayer.prototype.unpause = function () { - var mediaElement = this._mediaElement; + unpause() { + const mediaElement = this._mediaElement; if (mediaElement) { mediaElement.play(); } - }; + } - HtmlVideoPlayer.prototype.paused = function () { - - var mediaElement = this._mediaElement; + paused() { + const mediaElement = this._mediaElement; if (mediaElement) { return mediaElement.paused; } return false; - }; + } - HtmlVideoPlayer.prototype.setPlaybackRate = function (value) { - var mediaElement = this._mediaElement; + setPlaybackRate(value) { + const mediaElement = this._mediaElement; if (mediaElement) { mediaElement.playbackRate = value; } }; - HtmlVideoPlayer.prototype.getPlaybackRate = function () { - var mediaElement = this._mediaElement; + getPlaybackRate() { + const mediaElement = this._mediaElement; if (mediaElement) { return mediaElement.playbackRate; } return null; }; - HtmlVideoPlayer.prototype.setVolume = function (val) { - var mediaElement = this._mediaElement; + setVolume(val) { + const mediaElement = this._mediaElement; if (mediaElement) { mediaElement.volume = val / 100; } - }; + } - HtmlVideoPlayer.prototype.getVolume = function () { - var mediaElement = this._mediaElement; + getVolume() { + const mediaElement = this._mediaElement; if (mediaElement) { return Math.min(Math.round(mediaElement.volume * 100), 100); } - }; + } - HtmlVideoPlayer.prototype.volumeUp = function () { + volumeUp() { this.setVolume(Math.min(this.getVolume() + 2, 100)); - }; + } - HtmlVideoPlayer.prototype.volumeDown = function () { + volumeDown() { this.setVolume(Math.max(this.getVolume() - 2, 0)); - }; + } - HtmlVideoPlayer.prototype.setMute = function (mute) { - var mediaElement = this._mediaElement; + setMute(mute) { + const mediaElement = this._mediaElement; if (mediaElement) { mediaElement.muted = mute; } - }; + } - HtmlVideoPlayer.prototype.isMuted = function () { - var mediaElement = this._mediaElement; + isMuted() { + const mediaElement = this._mediaElement; if (mediaElement) { return mediaElement.muted; } return false; - }; + } - HtmlVideoPlayer.prototype.setAspectRatio = function (val) { - var mediaElement = this._mediaElement; + setAspectRatio(val) { + const mediaElement = this._mediaElement; if (mediaElement) { - if ('auto' === val) { - mediaElement.style.removeProperty('object-fit'); + if ("auto" === val) { + mediaElement.style.removeProperty("object-fit"); } else { - mediaElement.style['object-fit'] = val; + mediaElement.style["object-fit"] = val; } } this._currentAspectRatio = val; - }; + } - HtmlVideoPlayer.prototype.getAspectRatio = function () { - return this._currentAspectRatio || 'auto'; - }; + getAspectRatio() { + return this._currentAspectRatio || "auto"; + } - HtmlVideoPlayer.prototype.getSupportedAspectRatios = function () { + getSupportedAspectRatios() { return [{ - name: 'Auto', - id: 'auto' + name: "Auto", + id: "auto" }, { - name: 'Cover', - id: 'cover' + name: "Cover", + id: "cover" }, { - name: 'Fill', - id: 'fill' + name: "Fill", + id: "fill" }]; - }; + } - HtmlVideoPlayer.prototype.togglePictureInPicture = function () { + togglePictureInPicture() { return this.setPictureInPictureEnabled(!this.isPictureInPictureEnabled()); - }; + } - HtmlVideoPlayer.prototype.toggleAirPlay = function () { + toggleAirPlay() { return this.setAirPlayEnabled(!this.isAirPlayEnabled()); - }; + } - HtmlVideoPlayer.prototype.getBufferedRanges = function () { - var mediaElement = this._mediaElement; + getBufferedRanges() { + const mediaElement = this._mediaElement; if (mediaElement) { return htmlMediaHelper.getBufferedRanges(this, mediaElement); } return []; - }; + } - HtmlVideoPlayer.prototype.getStats = function () { + getStats() { + const mediaElement = this._mediaElement; + const playOptions = this._currentPlayOptions || []; - var mediaElement = this._mediaElement; - var playOptions = this._currentPlayOptions || []; - - var categories = []; + const categories = []; if (!mediaElement) { return Promise.resolve({ @@ -1762,22 +1856,22 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa }); } - var mediaCategory = { + const mediaCategory = { stats: [], - type: 'media' + type: "media" }; categories.push(mediaCategory); if (playOptions.url) { // create an anchor element (note: no need to append this element to the document) - var link = document.createElement('a'); + let link = document.createElement("a"); // set href to any path link.setAttribute('href', playOptions.url); - var protocol = (link.protocol || '').replace(':', ''); + const protocol = (link.protocol || "").replace(":", ""); if (protocol) { mediaCategory.stats.push({ - label: globalize.translate('LabelProtocol'), + label: globalize.translate("LabelProtocol"), value: protocol }); } @@ -1787,30 +1881,30 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa if (this._hlsPlayer || this._shakaPlayer) { mediaCategory.stats.push({ - label: globalize.translate('LabelStreamType'), + label: globalize.translate("LabelStreamType"), value: 'HLS' }); } else { mediaCategory.stats.push({ - label: globalize.translate('LabelStreamType'), + label: globalize.translate("LabelStreamType"), value: 'Video' }); } - var videoCategory = { + const videoCategory = { stats: [], - type: 'video' + type: "video" }; categories.push(videoCategory); - var rect = mediaElement.getBoundingClientRect ? mediaElement.getBoundingClientRect() : {}; - var height = parseInt(rect.height); - var width = parseInt(rect.width); + const rect = mediaElement.getBoundingClientRect ? mediaElement.getBoundingClientRect() : {}; + let height = parseInt(rect.height); + let width = parseInt(rect.width); // Don't show player dimensions on smart TVs because the app UI could be lower resolution than the video and this causes users to think there is a problem if (width && height && !browser.tv) { videoCategory.stats.push({ - label: globalize.translate('LabelPlayerDimensions'), + label: globalize.translate("LabelPlayerDimensions"), value: width + 'x' + height }); } @@ -1820,34 +1914,34 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa if (width && height) { videoCategory.stats.push({ - label: globalize.translate('LabelVideoResolution'), + label: globalize.translate("LabelVideoResolution"), value: width + 'x' + height }); } if (mediaElement.getVideoPlaybackQuality) { - var playbackQuality = mediaElement.getVideoPlaybackQuality(); + const playbackQuality = mediaElement.getVideoPlaybackQuality(); - var droppedVideoFrames = playbackQuality.droppedVideoFrames || 0; + const droppedVideoFrames = playbackQuality.droppedVideoFrames || 0; videoCategory.stats.push({ - label: globalize.translate('LabelDroppedFrames'), + label: globalize.translate("LabelDroppedFrames"), value: droppedVideoFrames }); - var corruptedVideoFrames = playbackQuality.corruptedVideoFrames || 0; + const corruptedVideoFrames = playbackQuality.corruptedVideoFrames || 0; videoCategory.stats.push({ - label: globalize.translate('LabelCorruptedFrames'), + label: globalize.translate("LabelCorruptedFrames"), value: corruptedVideoFrames }); } - var audioCategory = { + const audioCategory = { stats: [], - type: 'audio' + type: "audio" }; categories.push(audioCategory); - var sinkId = mediaElement.sinkId; + const sinkId = mediaElement.sinkId; if (sinkId) { audioCategory.stats.push({ label: 'Sink Id:', @@ -1858,11 +1952,12 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa return Promise.resolve({ categories: categories }); - }; + } + } if (browser.chromecast) { mediaManager = new cast.receiver.MediaManager(document.createElement('video')); } +/* eslint-enable indent */ - return HtmlVideoPlayer; -}); +export default HtmlVideoPlayer; From eb14b7a1296bb54bc06ac97d6ddf6978a58e437b Mon Sep 17 00:00:00 2001 From: Cromefire_ Date: Sun, 19 Apr 2020 17:38:03 +0200 Subject: [PATCH 008/196] Fixed default export, fixed some occurrences of this and rewrote some for loops --- src/plugins/htmlVideoPlayer/plugin.js | 68 +++++++++++---------------- 1 file changed, 28 insertions(+), 40 deletions(-) diff --git a/src/plugins/htmlVideoPlayer/plugin.js b/src/plugins/htmlVideoPlayer/plugin.js index 2c9de26897..ecae533644 100644 --- a/src/plugins/htmlVideoPlayer/plugin.js +++ b/src/plugins/htmlVideoPlayer/plugin.js @@ -394,10 +394,10 @@ function supportsTextTracks() { // Listen for error events. player.addEventListener('error', this.onShakaError.bind(this)); - self._shakaPlayer = player; + this._shakaPlayer = player; // This is needed in setCurrentTrackElement - self._currentSrc = url; + this._currentSrc = url; // Try to load a manifest. // This is an asynchronous process. @@ -555,7 +555,7 @@ function supportsTextTracks() { setTracks(elem, tracks, options.item, options.mediaSource); - return setSrcWithShakaPlayer(self, elem, options, val); + return setSrcWithShakaPlayer(this, elem, options, val); } else*/ if (browser.chromecast && val.indexOf('.m3u8') !== -1 && options.mediaSource.RunTimeTicks) { @@ -722,9 +722,9 @@ function supportsTextTracks() { * @private */ getSupportedAudioStreams() { - const profile = self._lastProfile; + const profile = this._lastProfile; - return getMediaStreamAudioTracks(self._currentPlayOptions.mediaSource).filter((stream) => { + return getMediaStreamAudioTracks(this._currentPlayOptions.mediaSource).filter((stream) => { return this.isAudioStreamSupported(stream, profile); }); } @@ -739,12 +739,8 @@ function supportsTextTracks() { } let audioIndex = -1; - let i; - let length; - let stream; - for (i = 0, length = streams.length; i < length; i++) { - stream = streams[i]; + for (const stream of streams) { audioIndex++; @@ -757,7 +753,7 @@ function supportsTextTracks() { return; } - const elem = self._mediaElement; + const elem = this._mediaElement; if (!elem) { return; } @@ -767,16 +763,15 @@ function supportsTextTracks() { const elemAudioTracks = elem.audioTracks || []; console.debug('found ' + elemAudioTracks.length + ' audio tracks'); - for (i = 0, length = elemAudioTracks.length; i < length; i++) { - + elemAudioTracks.forEach((audioTrack, i) => { if (audioIndex === i) { - console.debug('setting audio track ' + i + ' to enabled'); - elemAudioTracks[i].enabled = true; + console.debug(`setting audio track ${i} to enabled`); + audioTrack.enabled = true; } else { - console.debug('setting audio track ' + i + ' to disabled'); - elemAudioTracks[i].enabled = false; + console.debug(`setting audio track ${i} to disabled`); + audioTrack.enabled = false; } - } + }); } stop(destroyPlayer) { @@ -896,8 +891,8 @@ function supportsTextTracks() { // If this causes a failure during navigation we end up in an awkward UI state this.setCurrentTrackElement(this.subtitleTrackIndexToSetOnPlaying); - if (this.audioTrackIndexToSetOnPlaying != null && self.canSetAudioStreamIndex()) { - self.setAudioStreamIndex(this.audioTrackIndexToSetOnPlaying); + if (this.audioTrackIndexToSetOnPlaying != null && this.canSetAudioStreamIndex()) { + this.setAudioStreamIndex(this.audioTrackIndexToSetOnPlaying); } } @@ -1005,8 +1000,8 @@ function supportsTextTracks() { break; case 3: // MEDIA_ERR_DECODE - if (self._hlsPlayer) { - htmlMediaHelper.handleHlsJsMediaError(self); + if (this._hlsPlayer) { + htmlMediaHelper.handleHlsJsMediaError(this); return; } else { type = 'mediadecodeerror'; @@ -1046,12 +1041,9 @@ function supportsTextTracks() { if (videoElement) { const allTracks = videoElement.textTracks || []; // get list of tracks - for (let i = 0; i < allTracks.length; i++) { - - const currentTrack = allTracks[i]; - - if (currentTrack.label.indexOf('manualTrack') !== -1) { - currentTrack.mode = 'disabled'; + for (const track of allTracks) { + if (track.label.includes('manualTrack')) { + track.mode = 'disabled'; } } } @@ -1129,7 +1121,7 @@ function supportsTextTracks() { } this.resetSubtitleOffset(); - const item = self._currentPlayOptions.item; + const item = this._currentPlayOptions.item; this.destroyCustomTrack(videoElement); this.customTrackIndex = track.Index; @@ -1141,7 +1133,7 @@ function supportsTextTracks() { * @private */ renderSsaAss(videoElement, track, item) { - const attachments = self._currentPlayOptions.mediaSource.MediaAttachments || []; + const attachments = this._currentPlayOptions.mediaSource.MediaAttachments || []; const apiClient = connectionManager.getApiClient(item); const options = { video: videoElement, @@ -1152,7 +1144,7 @@ function supportsTextTracks() { workerUrl: appRouter.baseUrl() + '/libraries/subtitles-octopus-worker.js', legacyWorkerUrl: appRouter.baseUrl() + '/libraries/subtitles-octopus-worker-legacy.js', onError() { - htmlMediaHelper.onErrorInternal(self, 'mediadecodeerror'); + htmlMediaHelper.onErrorInternal(this, 'mediadecodeerror'); }, timeOffset: (this._currentPlayOptions.transcodingOffsetTicks || 0) / 10000000, @@ -1254,10 +1246,8 @@ function supportsTextTracks() { * @private */ setCueAppearance() { - Promise.all([import('userSettings'), import('subtitleAppearanceHelper')]).then(([userSettings, subtitleAppearanceHelper]) => { - - const elementId = self.id + "-cuestyle"; + const elementId = this.id + "-cuestyle"; let styleElem = document.querySelector("#" + elementId); if (!styleElem) { @@ -1348,11 +1338,9 @@ function supportsTextTracks() { if (trackEvents && subtitleTextElement) { const ticks = timeMs * 10000; let selectedTrackEvent; - for (let i = 0; i < trackEvents.length; i++) { - - const currentTrackEvent = trackEvents[i]; - if (currentTrackEvent.StartPositionTicks <= ticks && currentTrackEvent.EndPositionTicks >= ticks) { - selectedTrackEvent = currentTrackEvent; + for (const trackEvent of trackEvents) { + if (trackEvent.StartPositionTicks <= ticks && trackEvent.EndPositionTicks >= ticks) { + selectedTrackEvent = trackEvent; break; } } @@ -1960,4 +1948,4 @@ function supportsTextTracks() { } /* eslint-enable indent */ -export default HtmlVideoPlayer; +export default () => new HtmlVideoPlayer(); From 06eb790abb5a0cdccfde24d95cb07546ef2b3787 Mon Sep 17 00:00:00 2001 From: Cromefire_ Date: Sun, 19 Apr 2020 23:23:46 +0200 Subject: [PATCH 009/196] Fixed fixed pluginManager es6 compat and switched to includes --- package.json | 1 + src/plugins/htmlVideoPlayer/plugin.js | 34 +++++++++++++-------------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/package.json b/package.json index 47f5c63b42..105398b815 100644 --- a/package.json +++ b/package.json @@ -110,6 +110,7 @@ "src/components/playmenu.js", "src/components/sanatizefilename.js", "src/components/scrollManager.js", + "src/components/htmlvideoplayer/plugin.js", "src/components/syncPlay/groupSelectionMenu.js", "src/components/syncPlay/playbackPermissionManager.js", "src/components/syncPlay/syncPlayManager.js", diff --git a/src/plugins/htmlVideoPlayer/plugin.js b/src/plugins/htmlVideoPlayer/plugin.js index ecae533644..f7edf444d1 100644 --- a/src/plugins/htmlVideoPlayer/plugin.js +++ b/src/plugins/htmlVideoPlayer/plugin.js @@ -59,14 +59,14 @@ function supportsTextTracks() { } if (browser.firefox) { - if ((currentSrc || '').toLowerCase().indexOf('.m3u8') !== -1) { + if ((currentSrc || '').toLowerCase().includes('.m3u8')) { return false; } } // subs getting blocked due to CORS if (browser.chromecast) { - if ((currentSrc || '').toLowerCase().indexOf('.m3u8') !== -1) { + if ((currentSrc || '').toLowerCase().includes('.m3u8')) { return false; } } @@ -252,7 +252,7 @@ function supportsTextTracks() { * @private */ updateVideoUrl(streamInfo) { - const isHls = streamInfo.url.toLowerCase().indexOf(".m3u8") !== -1; + const isHls = streamInfo.url.toLowerCase().includes(".m3u8"); const mediaSource = streamInfo.mediaSource; const item = streamInfo.item; @@ -335,7 +335,7 @@ function supportsTextTracks() { */ setSrcWithHlsJs(instance, elem, options, url) { - return new Promise(function (resolve, reject) { + return new Promise((resolve, reject) => { requireHlsPlayer(() => { const hls = new Hls({ @@ -472,7 +472,7 @@ function supportsTextTracks() { } else if (ext === 'mpd' || contentType === 'application/dash+xml') { protocol = cast.player.api.CreateDashStreamingProtocol(host); - } else if (url.indexOf('.ism') > -1 || + } else if (url.includes('.ism') || contentType === 'application/vnd.ms-sstr+xml') { protocol = cast.player.api.CreateSmoothStreamingProtocol(host); } @@ -551,17 +551,17 @@ function supportsTextTracks() { elem.crossOrigin = crossOrigin; } - /*if (htmlMediaHelper.enableHlsShakaPlayer(options.item, options.mediaSource, 'Video') && val.indexOf('.m3u8') !== -1) { + /*if (htmlMediaHelper.enableHlsShakaPlayer(options.item, options.mediaSource, 'Video') && val.includes('.m3u8')) { setTracks(elem, tracks, options.item, options.mediaSource); return setSrcWithShakaPlayer(this, elem, options, val); } else*/ - if (browser.chromecast && val.indexOf('.m3u8') !== -1 && options.mediaSource.RunTimeTicks) { + if (browser.chromecast && val.includes('.m3u8') && options.mediaSource.RunTimeTicks) { return this.setCurrentSrcChromecast(this, elem, options, val); - } else if (htmlMediaHelper.enableHlsJsPlayer(options.mediaSource.RunTimeTicks, 'Video') && val.indexOf('.m3u8') !== -1) { + } else if (htmlMediaHelper.enableHlsJsPlayer(options.mediaSource.RunTimeTicks, 'Video') && val.includes('.m3u8')) { return this.setSrcWithHlsJs(this, elem, options, val); } else if (options.playMethod !== 'Transcode' && options.mediaSource.Container === 'flv') { return this.setSrcWithFlvJs(this, elem, options, val); @@ -710,7 +710,7 @@ function supportsTextTracks() { return true; } - return p.AudioCodec.toLowerCase().indexOf(codec) !== -1; + return p.AudioCodec.toLowerCase().includes(codec); } return false; @@ -902,7 +902,7 @@ function supportsTextTracks() { onPlaying(e) { if (!this._started) { this._started = true; - this.onPlaying.removeAttribute('controls'); + this._mediaElement.removeAttribute('controls'); loading.hide(); @@ -1135,6 +1135,7 @@ function supportsTextTracks() { renderSsaAss(videoElement, track, item) { const attachments = this._currentPlayOptions.mediaSource.MediaAttachments || []; const apiClient = connectionManager.getApiClient(item); + const htmlVideoPlayer = this; const options = { video: videoElement, subUrl: getTextTrackUrl(track, item), @@ -1144,7 +1145,7 @@ function supportsTextTracks() { workerUrl: appRouter.baseUrl() + '/libraries/subtitles-octopus-worker.js', legacyWorkerUrl: appRouter.baseUrl() + '/libraries/subtitles-octopus-worker-legacy.js', onError() { - htmlMediaHelper.onErrorInternal(this, 'mediadecodeerror'); + htmlMediaHelper.onErrorInternal(htmlVideoPlayer, 'mediadecodeerror'); }, timeOffset: (this._currentPlayOptions.transcodingOffsetTicks || 0) / 10000000, @@ -1187,7 +1188,7 @@ function supportsTextTracks() { if (browser.iOS) { const userAgent = navigator.userAgent.toLowerCase(); // works in the browser but not the native app - if ((userAgent.indexOf('os 9') !== -1 || userAgent.indexOf('os 8') !== -1) && userAgent.indexOf('safari') === -1) { + if ((userAgent.includes('os 9') || userAgent.includes('os 8')) && !userAgent.includes('safari')) { return true; } } @@ -1307,13 +1308,12 @@ function supportsTextTracks() { console.debug('downloaded ' + data.TrackEvents.length + ' track events'); // add some cues to show the text // in safari, the cues need to be added before setting the track mode to showing - data.TrackEvents.forEach(function (trackEvent) { - + for (const trackEvent of data.TrackEvents) { const trackCueObject = window.VTTCue || window.TextTrackCue; const cue = new trackCueObject(trackEvent.StartPositionTicks / 10000000, trackEvent.EndPositionTicks / 10000000, normalizeTrackEventText(trackEvent.Text, false)); trackElement.addCue(cue); - }); + } trackElement.mode = 'showing'; }); } @@ -1533,7 +1533,7 @@ function supportsTextTracks() { this.supportedFeatures = HtmlVideoPlayer.getSupportedFeatures(); } - return this.supportedFeatures.contains(feature); + return this.supportedFeatures.includes(feature); } // Save this for when playback stops, because querying the time at that point might return 0 @@ -1948,4 +1948,4 @@ function supportsTextTracks() { } /* eslint-enable indent */ -export default () => new HtmlVideoPlayer(); +export default HtmlVideoPlayer; From a1b2ed2c4a9b7936ab84744946de8126c846a854 Mon Sep 17 00:00:00 2001 From: Cromefire_ Date: Wed, 27 May 2020 00:38:01 +0200 Subject: [PATCH 010/196] Fixed event handling --- src/plugins/htmlVideoPlayer/plugin.js | 99 +++++++++++++++++---------- 1 file changed, 61 insertions(+), 38 deletions(-) diff --git a/src/plugins/htmlVideoPlayer/plugin.js b/src/plugins/htmlVideoPlayer/plugin.js index f7edf444d1..69dc4d9a96 100644 --- a/src/plugins/htmlVideoPlayer/plugin.js +++ b/src/plugins/htmlVideoPlayer/plugin.js @@ -349,7 +349,7 @@ function supportsTextTracks() { hls.loadSource(url); hls.attachMedia(elem); - htmlMediaHelper.bindEventsToHlsPlayer(this, hls, elem, this.onError.bind(this), resolve, reject); + htmlMediaHelper.bindEventsToHlsPlayer(this, hls, elem, this.onError, resolve, reject); this._hlsPlayer = hls; @@ -362,8 +362,7 @@ function supportsTextTracks() { /** * @private */ - onShakaError(event) { - + onShakaError = (event) => { const error = event.detail; console.error('Error code', error.code, 'object', error); } @@ -392,7 +391,7 @@ function supportsTextTracks() { //shaka.log.setLevel(6); // Listen for error events. - player.addEventListener('error', this.onShakaError.bind(this)); + player.addEventListener('error', this.onShakaError); this._shakaPlayer = player; @@ -441,8 +440,7 @@ function supportsTextTracks() { * Adapted from : https://github.com/googlecast/CastReferencePlayer/blob/master/player.js * @private */ - onMediaManagerLoadMedia(event) { - + onMediaManagerLoadMedia = (event) => { if (this._castPlayer) { this._castPlayer.unload(); // Must unload before starting again. } @@ -498,7 +496,7 @@ function supportsTextTracks() { */ initMediaManager() { mediaManager.defaultOnLoad = mediaManager.onLoad.bind(mediaManager); - mediaManager.onLoad = this.onMediaManagerLoadMedia.bind(this); + mediaManager.onLoad = this.onMediaManagerLoadMedia; //mediaManager.defaultOnPlay = mediaManager.onPlay.bind(mediaManager); //mediaManager.onPlay = function (event) { @@ -517,7 +515,7 @@ function supportsTextTracks() { * @private */ setCurrentSrc(elem, options) { - elem.removeEventListener('error', this.onError.bind(this)); + elem.removeEventListener('error', this.onError); let val = options.url; console.debug('playing url: ' + val); @@ -574,7 +572,7 @@ function supportsTextTracks() { return htmlMediaHelper.applySrc(elem, val, options).then(() => { this._currentSrc = val; - return htmlMediaHelper.playWithPromise(elem, this.onError.bind(this)); + return htmlMediaHelper.playWithPromise(elem, this.onError); }); } } @@ -783,7 +781,7 @@ function supportsTextTracks() { elem.pause(); } - htmlMediaHelper.onEndedInternal(this, elem, this.onError.bind(this)); + htmlMediaHelper.onEndedInternal(this, elem, this.onError); if (destroyPlayer) { this.destroy(); @@ -807,15 +805,15 @@ function supportsTextTracks() { this._mediaElement = null; this.destroyCustomTrack(videoElement); - videoElement.removeEventListener('timeupdate', this.onTimeUpdate.bind(this)); - videoElement.removeEventListener('ended', this.onEnded.bind(this)); - videoElement.removeEventListener('volumechange', this.onVolumeChange.bind(this)); - videoElement.removeEventListener('pause', this.onPause.bind(this)); - videoElement.removeEventListener('playing', this.onPlaying.bind(this)); - videoElement.removeEventListener('play', this.onPlay.bind(this)); - videoElement.removeEventListener('click', this.onClick.bind(this)); - videoElement.removeEventListener('dblclick', this.onDblClick.bind(this)); - videoElement.removeEventListener('waiting', this.onWaiting.bind(this)); + videoElement.removeEventListener('timeupdate', this.onTimeUpdate); + videoElement.removeEventListener('ended', this.onEnded); + videoElement.removeEventListener('volumechange', this.onVolumeChange); + videoElement.removeEventListener('pause', this.onPause); + videoElement.removeEventListener('playing', this.onPlaying); + videoElement.removeEventListener('play', this.onPlay); + videoElement.removeEventListener('click', this.onClick); + videoElement.removeEventListener('dblclick', this.onDblClick); + videoElement.removeEventListener('waiting', this.onWaiting); videoElement.parentNode.removeChild(videoElement); } @@ -833,22 +831,32 @@ function supportsTextTracks() { /** * @private + * @param e {Event} The event received from the `