diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index d183cee9..27381237 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,2 +1 @@ github: feross -custom: https://paypal.me/borewit diff --git a/README.md b/README.md index 51557b66..78099b83 100644 --- a/README.md +++ b/README.md @@ -142,11 +142,12 @@ The Windows app can be packaged from **any** platform. Note: Windows code signing only works from **Windows**, for now. Note: To package the Windows app from non-Windows platforms, -[Wine](https://www.winehq.org/) needs to be installed. For example on Mac, first -install [XQuartz](http://www.xquartz.org/), then run: +[Wine](https://www.winehq.org/) and [Mono](https://www.mono-project.com/) need +to be installed. For example on Mac, first install +[XQuartz](http://www.xquartz.org/), then run: ``` -brew install wine +brew install wine mono ``` (Requires the [Homebrew](http://brew.sh/) package manager.) @@ -164,7 +165,6 @@ If packaging from Mac, install system dependencies with Homebrew by running: ``` npm run install-system-deps ``` - #### Recommended readings to start working in the app Electron (Framework to make native apps for Windows, OSX and Linux in Javascript): diff --git a/package-lock.json b/package-lock.json index 0b964f44..f543c149 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5645,9 +5645,9 @@ } }, "music-metadata": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/music-metadata/-/music-metadata-4.5.3.tgz", - "integrity": "sha512-VXIr9hGJyxcdyqOlUmn+c4wM8f1FAyLyxV12L1pYC5Zb/MKElrh2JmGTLBSy23DN27uBA4QbqhfOOtkvd9H6Mw==", + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/music-metadata/-/music-metadata-4.8.0.tgz", + "integrity": "sha512-eQp9mDTwg8WEqVRIEj1lUuqZ4qiQvXa71ipotkPFKch4ekTAtGTzU/TXAi7DhCeHsZB8WLfGUBTFN1NGBE1iOQ==", "requires": { "content-type": "^1.0.4", "debug": "^4.1.0", diff --git a/package.json b/package.json index 6db88aa2..d628b32e 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "location-history": "^1.1.1", "material-ui": "^0.20.2", "mkdirp": "^0.5.1", - "music-metadata": "^4.5.3", + "music-metadata": "^4.8.0", "network-address": "^1.1.2", "parse-torrent": "^7.0.1", "prettier-bytes": "^1.0.4", @@ -103,7 +103,7 @@ "install-system-deps": "brew install fakeroot dpkg rpm", "open-config": "node ./bin/open-config.js", "package": "node ./bin/package.js", - "start": "npm run build && electron .", + "start": "npm run build && electron --no-sandbox .", "test": "standard && depcheck --ignores=standard,babel-eslint --ignore-dirs=build,dist && node ./bin/extra-lint.js", "test-integration": "npm run build && node ./test", "update-authors": "./bin/update-authors.sh", diff --git a/src/main/windows/about.js b/src/main/windows/about.js index fc16d517..1e6d6dc5 100644 --- a/src/main/windows/about.js +++ b/src/main/windows/about.js @@ -25,7 +25,8 @@ function init () { title: 'About ' + config.APP_WINDOW_TITLE, useContentSize: true, webPreferences: { - nodeIntegration: true + nodeIntegration: true, + enableBlinkFeatures: 'AudioVideoTracks' }, width: 300 }) diff --git a/src/main/windows/main.js b/src/main/windows/main.js index 404c82b9..11aad3d0 100644 --- a/src/main/windows/main.js +++ b/src/main/windows/main.js @@ -45,7 +45,7 @@ function init (state, options) { width: initialBounds.width, webPreferences: { nodeIntegration: true, - experimentalFeatures: true + enableBlinkFeatures: 'AudioVideoTracks' }, x: initialBounds.x, y: initialBounds.y diff --git a/src/main/windows/webtorrent.js b/src/main/windows/webtorrent.js index 8c58043b..cd08e225 100644 --- a/src/main/windows/webtorrent.js +++ b/src/main/windows/webtorrent.js @@ -26,7 +26,8 @@ function init () { title: 'webtorrent-hidden-window', useContentSize: true, webPreferences: { - nodeIntegration: true + nodeIntegration: true, + enableBlinkFeatures: 'AudioVideoTracks' }, width: 150 }) diff --git a/src/renderer/pages/player-page.js b/src/renderer/pages/player-page.js index ea3fb243..8a2fe034 100644 --- a/src/renderer/pages/player-page.js +++ b/src/renderer/pages/player-page.js @@ -1,5 +1,3 @@ -/* global HTMLMediaElement */ - const React = require('react') const Bitfield = require('bitfield') const prettyBytes = require('prettier-bytes') @@ -137,7 +135,6 @@ function renderMedia (state) { onError={dispatcher('mediaError')} onTimeUpdate={dispatcher('mediaTimeUpdate')} onEncrypted={dispatcher('mediaEncrypted')} - onCanPlay={onCanPlay} > {trackTags} @@ -155,29 +152,50 @@ function renderMedia (state) { ) - // As soon as we know the video dimensions, resize the window function onLoadedMetadata (e) { - if (state.playing.type !== 'video') return - const video = e.target - const dimensions = { - width: video.videoWidth, - height: video.videoHeight - } - dispatch('setDimensions', dimensions) + const mediaElement = e.target + + // check if we can decode video and audio track + if (state.playing.type === 'video') { + if (mediaElement.videoTracks.length === 0) { + dispatch('mediaError', 'Video codec unsupported') + } + + if (mediaElement.audioTracks.length === 0) { + dispatch('mediaError', 'Audio codec unsupported') + } + + dispatch('mediaSuccess') + + const dimensions = { + width: mediaElement.videoWidth, + height: mediaElement.videoHeight + } + + // As soon as we know the video dimensions, resize the window + dispatch('setDimensions', dimensions) - if (video.audioTracks) { // set audioTracks const tracks = [] - for (let i = 0; i < video.audioTracks.length; i++) { + for (let i = 0; i < mediaElement.audioTracks.length; i++) { tracks.push({ - label: video.audioTracks[i].label || `Track ${i + 1}`, - language: video.audioTracks[i].language + label: mediaElement.audioTracks[i].label || `Track ${i + 1}`, + language: mediaElement.audioTracks[i].language }) } state.playing.audioTracks.tracks = tracks state.playing.audioTracks.selectedIndex = 0 } + + // check if we can decode audio track + if (state.playing.type === 'audio') { + if (mediaElement.audioTracks.length === 0) { + dispatch('mediaError', 'Audio codec unsupported') + } + + dispatch('mediaSuccess') + } } function onEnded (e) { @@ -189,20 +207,6 @@ function renderMedia (state) { if (state.window.isFullScreen) dispatch('toggleFullScreen') } } - - function onCanPlay (e) { - const elem = e.target - if (elem.readyState < HTMLMediaElement.HAVE_FUTURE_DATA) return - if (state.playing.type === 'video' && - elem.webkitVideoDecodedByteCount === 0) { - dispatch('mediaError', 'Video codec unsupported') - } else if (elem.webkitAudioDecodedByteCount === 0) { - dispatch('mediaError', 'Audio codec unsupported') - } else { - dispatch('mediaSuccess') - elem.play() - } - } } function renderOverlay (state) { diff --git a/src/renderer/pages/torrent-list-page.js b/src/renderer/pages/torrent-list-page.js index 5c4123ca..286e9acf 100644 --- a/src/renderer/pages/torrent-list-page.js +++ b/src/renderer/pages/torrent-list-page.js @@ -212,7 +212,9 @@ module.exports = class TorrentList extends React.Component { else if (torrentSummary.progress.progress === 1) status = 'Not seeding' else status = 'Paused' } else if (torrentSummary.status === 'downloading') { - status = 'Downloading' + if (!torrentSummary.progress) status = '' + else if (!torrentSummary.progress.ready) status = 'Verifying' + else status = 'Downloading' } else if (torrentSummary.status === 'seeding') { status = 'Seeding' } else { // torrentSummary.status is 'new' or something unexpected @@ -316,7 +318,7 @@ module.exports = class TorrentList extends React.Component { torrentSummary.progress.files[index]) { const fileProg = torrentSummary.progress.files[index] isDone = fileProg.numPiecesPresent === fileProg.numPieces - progress = Math.round(100 * fileProg.numPiecesPresent / fileProg.numPieces) + '%' + progress = Math.floor(100 * fileProg.numPiecesPresent / fileProg.numPieces) + '%' } // Second, for media files where we saved our position, show how far we got diff --git a/static/linux/webtorrent-desktop.ejs b/static/linux/webtorrent-desktop.ejs index af143b6e..e88789cc 100644 --- a/static/linux/webtorrent-desktop.ejs +++ b/static/linux/webtorrent-desktop.ejs @@ -5,7 +5,7 @@ Name=<%= productName %> <% if (genericName) { %>GenericName=<%= genericName %><% } %> <% if (description) { %>Comment=<%= description %><% } %> Icon=<%= name %> -<% if (name) { %>Exec=<%= name %> %U<% } %> +<% if (name) { %>Exec=<%= name %> --no-sandbox %U<% } %><%/*HACK: --no-sandbox fixes an Electron 6 bug. See: #1703*/%> Terminal=false Actions=CreateNewTorrent;OpenTorrentFile;OpenTorrentAddress; <% if (mimeType && mimeType.length) { %>MimeType=<%= mimeType.join(';') %>;<% } %> @@ -15,12 +15,12 @@ StartupNotify=true [Desktop Action CreateNewTorrent] Name=Create New Torrent... -<% if (name) { %>Exec=<%= name %> -n <% } %> +<% if (name) { %>Exec=<%= name %> --no-sandbox -n <% } %><%/*HACK: --no-sandbox fixes an Electron 6 bug. See: #1703*/%> [Desktop Action OpenTorrentFile] Name=Open Torrent File... -<% if (name) { %>Exec=<%= name %> -o <% } %> +<% if (name) { %>Exec=<%= name %> --no-sandbox -o <% } %><%/*HACK: --no-sandbox fixes an Electron 6 bug. See: #1703*/%> [Desktop Action OpenTorrentAddress] Name=Open Torrent Address... -<% if (name) { %>Exec=<%= name %> -u <% } %> +<% if (name) { %>Exec=<%= name %> --no-sandbox -u <% } %><%/*HACK: --no-sandbox fixes an Electron 6 bug. See: #1703*/%>