From d4e6c8427941d5f2fb1ca140bead837eb2498817 Mon Sep 17 00:00:00 2001 From: DC Date: Mon, 16 May 2016 08:03:21 -0700 Subject: [PATCH] Automatically add subtitle tracks Currently, add all .SRT and .VTT subtitle files in the same torrent as a video file --- renderer/index.js | 41 +++++++++++++++++++++++++++++++++------- renderer/state.js | 15 +++++++++++++-- renderer/views/player.js | 13 ++++--------- renderer/webtorrent.js | 4 +--- 4 files changed, 52 insertions(+), 21 deletions(-) diff --git a/renderer/index.js b/renderer/index.js index 64bf6e89..69c7d983 100644 --- a/renderer/index.js +++ b/renderer/index.js @@ -423,7 +423,7 @@ function openSubtitles () { properties: [ 'openFile' ] }, function (filenames) { if (!Array.isArray(filenames)) return - addSubtitle({path: filenames[0]}) + addSubtitle({path: filenames[0]}, true) }) } @@ -543,7 +543,7 @@ function onOpen (files) { // In the player, the only drag-drop function is adding subtitles var isInPlayer = state.location.current().url === 'player' if (isInPlayer) { - return files.filter(isSubtitle).forEach(addSubtitle) + return files.filter(isSubtitle).forEach((file) => addSubtitle(file, true)) } // Otherwise, you can only drag-drop onto the home screen @@ -592,12 +592,20 @@ function addTorrent (torrentId) { ipcRenderer.send('wt-start-torrenting', torrentKey, torrentId, path) } -function addSubtitle (file) { +function addSubtitle (file, autoSelect) { var srtToVtt = require('srt-to-vtt') var LanguageDetect = require('languagedetect') + // Subtitles are only supported while playing video if (state.playing.type !== 'video') return - fs.createReadStream(file.path || file).pipe(srtToVtt()).pipe(concat(function (buf) { + + // No dupes allowed + var subs = state.playing.subtitles + var filePath = file.path || file + if (subs.tracks.some((track) => track.filePath === filePath)) return + + // Read the .SRT or .VTT file, parse it, add subtitle track + fs.createReadStream(filePath).pipe(srtToVtt()).pipe(concat(function (buf) { // 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. @@ -609,11 +617,11 @@ function addSubtitle (file) { var track = { buffer: 'data:text/vtt;base64,' + subtitles.toString('base64'), language: langDetected, - label: langDetected + label: langDetected, + filePath: filePath } - var subs = state.playing.subtitles subs.tracks.push(track) - selectNewlyAddedSubtitle() + if (autoSelect) selectNewlyAddedSubtitle() relabelSubtitles() })) } @@ -653,6 +661,20 @@ function relabelSubtitles () { }) } +function checkForSubtitles () { + if (state.playing.type !== 'video') return + var torrentSummary = state.getPlayingTorrentSummary() + if (!torrentSummary || !torrentSummary.progress) return + + torrentSummary.progress.files.forEach(function (fp, ix) { + if (fp.numPieces !== fp.numPiecesPresent) return // ignore incomplete files + var file = torrentSummary.files[ix] + if (!isSubtitle(file.name)) return + var filePath = path.join(torrentSummary.path, file.path) + addSubtitle(filePath) + }) +} + function toggleSubtitlesMenu () { state.playing.subtitles.showMenu = !state.playing.subtitles.showMenu } @@ -835,6 +857,8 @@ function torrentProgress (progressInfo) { torrentSummary.progress = p }) + checkForSubtitles() + update() } @@ -934,6 +958,9 @@ function openPlayerFromActiveTorrent (torrentSummary, index, timeout, cb) { ipcRenderer.send('wt-get-audio-metadata', torrentSummary.infoHash, index) } + // if it's video, check for subtitles files that are done downloading + checkForSubtitles() + ipcRenderer.send('wt-start-server', torrentSummary.infoHash, index) ipcRenderer.once('wt-server-' + torrentSummary.infoHash, function (e, info) { clearTimeout(timeout) diff --git a/renderer/state.js b/renderer/state.js index 11c8dab9..45ab6940 100644 --- a/renderer/state.js +++ b/renderer/state.js @@ -9,7 +9,8 @@ var LocationHistory = require('./lib/location-history') module.exports = { getInitialState, getDefaultPlayState, - getDefaultSavedState + getDefaultSavedState, + getPlayingTorrentSummary } function getInitialState () { @@ -57,7 +58,12 @@ function getInitialState () { * * Also accessible via `require('application-config')('WebTorrent').filePath` */ - saved: {} + saved: {}, + + /* + * Getters, for convenience + */ + getPlayingTorrentSummary } } @@ -264,3 +270,8 @@ function getDefaultSavedState () { : remote.app.getPath('downloads') } } + +function getPlayingTorrentSummary () { + var infoHash = this.playing.infoHash + return this.saved.torrents.find((x) => x.infoHash === infoHash) +} diff --git a/renderer/views/player.js b/renderer/views/player.js index 0db8767f..5fee9449 100644 --- a/renderer/views/player.js +++ b/renderer/views/player.js @@ -161,7 +161,7 @@ function renderOverlay (state) { } function renderAudioMetadata (state) { - var torrentSummary = getPlayingTorrentSummary(state) + var torrentSummary = state.getPlayingTorrentSummary() var fileSummary = torrentSummary.files[state.playing.fileIndex] if (!fileSummary.audioInfo) return var info = fileSummary.audioInfo @@ -200,7 +200,7 @@ function renderLoadingSpinner (state) { (new Date().getTime() - state.playing.lastTimeUpdate > 2000) if (!isProbablyStalled) return - var prog = getPlayingTorrentSummary(state).progress || {} + var prog = state.getPlayingTorrentSummary().progress || {} var fileProgress = 0 if (prog.files) { var file = prog.files[state.playing.fileIndex] @@ -493,7 +493,7 @@ var volumeChanging = false // Renders the loading bar. Shows which parts of the torrent are loaded, which // can be "spongey" / non-contiguous function renderLoadingBar (state) { - var torrentSummary = getPlayingTorrentSummary(state) + var torrentSummary = state.getPlayingTorrentSummary() if (!torrentSummary.progress) { return [] } @@ -530,7 +530,7 @@ function renderLoadingBar (state) { // Returns the CSS background-image string for a poster image + dark vignette function cssBackgroundImagePoster (state) { - var torrentSummary = getPlayingTorrentSummary(state) + var torrentSummary = state.getPlayingTorrentSummary() var posterPath = TorrentSummary.getPosterPath(torrentSummary) if (!posterPath) return '' return cssBackgroundImageDarkGradient() + `, url(${posterPath})` @@ -540,8 +540,3 @@ function cssBackgroundImageDarkGradient () { return 'radial-gradient(circle at center, ' + 'rgba(0,0,0,0.4) 0%, rgba(0,0,0,1) 100%)' } - -function getPlayingTorrentSummary (state) { - var infoHash = state.playing.infoHash - return state.saved.torrents.find((x) => x.infoHash === infoHash) -} diff --git a/renderer/webtorrent.js b/renderer/webtorrent.js index c3f95a3b..c9d24723 100644 --- a/renderer/webtorrent.js +++ b/renderer/webtorrent.js @@ -157,9 +157,7 @@ function getTorrentFileInfo (file) { return { name: file.name, length: file.length, - path: file.path, - numPiecesPresent: 0, - numPieces: null + path: file.path } }