diff --git a/package.json b/package.json index fbf1163d34..76d01b1841 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ "shaka-player": "^2.5.5", "sortablejs": "^1.9.0", "swiper": "^3.4.2", + "libass-wasm": "^2.1.1", "webcomponents.js": "^0.7.24", "whatwg-fetch": "^1.1.1" }, diff --git a/src/bundle.js b/src/bundle.js index 4748c6d281..54623fab74 100644 --- a/src/bundle.js +++ b/src/bundle.js @@ -90,3 +90,9 @@ require("libjass/libjass.css"); _define("libjass", function() { return libjass; }); + +// libass-wasm +var libass_wasm = require("libass-wasm"); +_define("JavascriptSubtitlesOctopus", function() { + return libass_wasm; +}); diff --git a/src/components/htmlvideoplayer/plugin.js b/src/components/htmlvideoplayer/plugin.js index ac4e8cf6a5..adc76f67b1 100644 --- a/src/components/htmlvideoplayer/plugin.js +++ b/src/components/htmlvideoplayer/plugin.js @@ -27,6 +27,14 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa return _supportsTextTracks; } + function supportsCanvas() { + return !!document.createElement('canvas').getContext; + } + + function supportsWebWorkers() { + return !!window.Worker; + } + function enableNativeTrackSupport(currentSrc, track) { if (track) { @@ -185,6 +193,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa var lastCustomTrackMs = 0; var currentClock; + var currentSubtitlesOctopus; var currentAssRenderer; var customTrackIndex = -1; @@ -962,6 +971,12 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa currentClock = null; self._currentAspectRatio = null; + var octopus = currentSubtitlesOctopus; + if (octopus) { + octopus.dispose(); + } + currentSubtitlesOctopus = null; + var renderer = currentAssRenderer; if (renderer) { renderer.setEnabled(false); @@ -1026,6 +1041,22 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa lastCustomTrackMs = 0; } + function renderWithSubtitlesOctopus(videoElement, track, item) { + var attachments = self._currentPlayOptions.mediaSource.MediaAttachments || []; + var options = { + video: videoElement, + subUrl: getTextTrackUrl(track, item), + fonts: attachments.map(i => i.DeliveryUrl), + workerUrl: appRouter.baseUrl() + "/libraries/subtitles-octopus-worker.js", + onError: function() { + htmlMediaHelper.onErrorInternal(self, 'mediadecodeerror') + } + }; + require(['JavascriptSubtitlesOctopus'], function(SubtitlesOctopus) { + currentSubtitlesOctopus = new SubtitlesOctopus(options); + }); + } + function renderWithLibjass(videoElement, track, item) { var rendererSettings = {}; @@ -1072,6 +1103,15 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa }); } + function renderSsaAss(videoElement, track, item) { + if (supportsCanvas() && supportsWebWorkers()) { + renderWithSubtitlesOctopus(videoElement, track, item); + } else { + console.log('rendering subtitles with libjass'); + renderWithLibjass(videoElement, track, item); + } + } + function onVideoResize() { if (browser.iOS) { // the new sizes will be delayed for about 500ms with wkwebview @@ -1182,7 +1222,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa var format = (track.Codec || '').toLowerCase(); if (format === 'ssa' || format === 'ass') { // libjass is needed here - renderWithLibjass(videoElement, track, item); + renderSsaAss(videoElement, track, item); return; } diff --git a/src/components/htmlvideoplayer/style.css b/src/components/htmlvideoplayer/style.css index ed7b6d126e..e1875ff332 100644 --- a/src/components/htmlvideoplayer/style.css +++ b/src/components/htmlvideoplayer/style.css @@ -24,6 +24,10 @@ z-index: 1000; } +.videoPlayerContainer .libassjs-canvas-parent { + order: -1; +} + video::-webkit-media-controls { display: none !important; } diff --git a/webpack.common.js b/webpack.common.js index 969c7d6e08..5e0f885267 100644 --- a/webpack.common.js +++ b/webpack.common.js @@ -5,7 +5,10 @@ const CopyPlugin = require("copy-webpack-plugin"); const Assets = [ "alameda/alameda.js", - "requirejs/require.js" + "requirejs/require.js", + "libass-wasm/dist/subtitles-octopus-worker.js", + "libass-wasm/dist/subtitles-octopus-worker.data", + "libass-wasm/dist/subtitles-octopus-worker.wasm" ]; module.exports = { diff --git a/yarn.lock b/yarn.lock index 34c6ad9164..705eac6a19 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2943,6 +2943,11 @@ levn@^0.3.0, levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" +libass-wasm@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/libass-wasm/-/libass-wasm-2.1.1.tgz#f12f4fdb9579dd422dcbc348bc3bd61097f4d07d" + integrity sha512-d45bHQ7tFVsLW3QstQDrDog2m+0D6Cja4GTrkGi70R9A5+aeLunPSUz3G4CVB+sKffNgiWjK4QI5NZLHQKZ9oQ== + libjass@^0.11.0: version "0.11.0" resolved "https://registry.yarnpkg.com/libjass/-/libjass-0.11.0.tgz#bff1f464a2428c3bddfb68e4503b2d52afe3d6e6"