From 9731d85ca3b651b2b9856f69af947bf2db12e316 Mon Sep 17 00:00:00 2001 From: DC Date: Sun, 15 May 2016 23:59:56 -0700 Subject: [PATCH] Simplify subtitles code --- package.json | 1 + renderer/index.js | 74 +++++++++++++++++---------- renderer/state.js | 5 +- renderer/views/create-torrent-page.js | 1 + renderer/views/player.js | 36 ++++++------- 5 files changed, 69 insertions(+), 48 deletions(-) diff --git a/package.json b/package.json index c86184e2..df31d763 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "electron-prebuilt": "1.0.2", "fs-extra": "^0.27.0", "hyperx": "^2.0.2", + "iso-639-1": "^1.2.1", "languagedetect": "^1.1.1", "main-loop": "^3.2.0", "musicmetadata": "^2.0.2", diff --git a/renderer/index.js b/renderer/index.js index 06372b7d..64bf6e89 100644 --- a/renderer/index.js +++ b/renderer/index.js @@ -17,6 +17,7 @@ var appConfig = require('application-config')('WebTorrent') var concat = require('concat-stream') var dragDrop = require('drag-drop') var fs = require('fs-extra') +var iso639 = require('iso-639-1') var mainLoop = require('main-loop') var path = require('path') @@ -295,10 +296,10 @@ function dispatch (action, ...args) { openSubtitles() } if (action === 'selectSubtitle') { - selectSubtitle(args[0] /* label */) + selectSubtitle(args[0] /* index */) } - if (action === 'showSubtitles') { - showSubtitles() + if (action === 'toggleSubtitlesMenu') { + toggleSubtitlesMenu() } if (action === 'mediaStalled') { state.playing.isStalled = true @@ -600,41 +601,60 @@ function addSubtitle (file) { // Set the cue text position so it appears above the player controls. // The only way to change cue text position is by modifying the VTT. It is not // possible via CSS. - var langDetected = (new LanguageDetect()).detect(buf.toString().replace(/(.*-->.*)/g, ''), 2) + var vttContents = buf.toString().replace(/(.*-->.*)/g, '') + var langDetected = (new LanguageDetect()).detect(vttContents, 2) langDetected = langDetected.length ? langDetected[0][0] : 'subtitle' langDetected = langDetected.slice(0, 1).toUpperCase() + langDetected.slice(1) var subtitles = Buffer(buf.toString().replace(/(-->.*)/g, '$1 line:88%')) var track = { buffer: 'data:text/vtt;base64,' + subtitles.toString('base64'), - label: langDetected, - selected: true + language: langDetected, + label: langDetected } - state.playing.subtitles.tracks.forEach(function (trackItem) { - trackItem.selected = false - if (trackItem.label === track.label) { - var labelParts = /([^\d]+)(\d+)$/.exec(track.label) - track.label = labelParts - ? labelParts[1] + (parseInt(labelParts[2]) + 1) - : track.label + ' 2' - } - }) - state.playing.subtitles.change = track.label - state.playing.subtitles.tracks.push(track) - state.playing.subtitles.enabled = true + var subs = state.playing.subtitles + subs.tracks.push(track) + selectNewlyAddedSubtitle() + relabelSubtitles() })) } -function selectSubtitle (label) { - state.playing.subtitles.tracks.forEach(function (track) { - track.selected = (track.label === label) - }) - state.playing.subtitles.enabled = !!label - state.playing.subtitles.change = label - state.playing.subtitles.show = false +function selectSubtitle (ix) { + state.playing.subtitles.selectedIndex = ix } -function showSubtitles () { - state.playing.subtitles.show = !state.playing.subtitles.show +// Automatically choose the subtitle in the user's language, if possible +function selectNewlyAddedSubtitle () { + var oldIx = state.playing.subtitles.selectedIndex + if (oldIx === -1) oldIx = undefined + var newIx = state.playing.subtitles.tracks.length - 1 + + // Find which subtitle track fits the current locale + var langIx + var osLangISO = window.navigator.language.split('-')[0] // eg "en" + var trackLang = state.playing.subtitles.tracks[newIx].language // eg "German" + var trackLangISO = iso639.getCode(trackLang) // eg "de" + if (trackLangISO === osLangISO) { + selectSubtitle(newIx) // newly added track is in the user's language + } else { + selectSubtitle(oldIx || newIx) // otherwise, if we've already selected a track, keep it + } + + console.log('SELECTING', langIx, oldIx, newIx) +} + +// Make sure we don't have two subtitle tracks with the same label +// Labels each track by language, eg "German", "English", "English 2", ... +function relabelSubtitles () { + var counts = {} + state.playing.subtitles.tracks.forEach(function (track) { + var lang = track.language + counts[lang] = (counts[lang] || 0) + 1 + track.label = counts[lang] > 1 ? (lang + ' ' + counts[lang]) : lang + }) +} + +function toggleSubtitlesMenu () { + state.playing.subtitles.showMenu = !state.playing.subtitles.showMenu } // Starts downloading and/or seeding a given torrentSummary. Returns WebTorrent object diff --git a/renderer/state.js b/renderer/state.js index 0f1a3867..11c8dab9 100644 --- a/renderer/state.js +++ b/renderer/state.js @@ -75,8 +75,9 @@ function getDefaultPlayState () { lastTimeUpdate: 0, /* Unix time in ms */ mouseStationarySince: 0, /* Unix time in ms */ subtitles: { - tracks: [], /* subtitles file (Buffer) */ - enabled: false + tracks: [], /* subtitle tracks, each {label, language, ...} */ + selectedIndex: -1, /* current subtitle track */ + showMenu: false /* popover menu, above the video */ }, aspectRatio: 0 /* aspect ratio of the video */ } diff --git a/renderer/views/create-torrent-page.js b/renderer/views/create-torrent-page.js index d1213d38..efbc0666 100644 --- a/renderer/views/create-torrent-page.js +++ b/renderer/views/create-torrent-page.js @@ -30,6 +30,7 @@ function CreateTorrentPage (state) { pathPrefix = files[0] } } + console.log('WTF', pathPrefix, files) // Sanity check: show the number of files and total size var numFiles = files.length diff --git a/renderer/views/player.js b/renderer/views/player.js index fe4812e5..0db8767f 100644 --- a/renderer/views/player.js +++ b/renderer/views/player.js @@ -54,14 +54,10 @@ function renderMedia (state) { state.playing.setVolume = null } - // fix textTrack cues not been removed rerender - if (state.playing.subtitles.change) { - var tracks = mediaElement.textTracks - for (var j = 0; j < tracks.length; j++) { - // mode is not an attribute, only available on DOM - tracks[j].mode = (tracks[j].label === state.playing.subtitles.change) ? 'showing' : 'hidden' - } - state.playing.subtitles.change = null + // Switch to the newly added subtitle track, if available + var tracks = mediaElement.textTracks + for (var j = 0; j < tracks.length; j++) { + tracks[j].mode = (j === state.playing.subtitles.selectedIndex) ? 'showing' : 'hidden' } state.playing.currentTime = mediaElement.currentTime @@ -71,13 +67,13 @@ function renderMedia (state) { // Add subtitles to the