mirror of
https://github.com/jely2002/youtube-dl-gui.git
synced 2021-11-01 22:46:21 +03:00
Update to testing version 1.3.2 (check release for changelog)
This commit is contained in:
13
custom.css
13
custom.css
@@ -36,7 +36,14 @@ body {
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.title, .channel, .duration {
|
||||
.thumbnail-settings {
|
||||
border-radius: 3px;
|
||||
width: 100%;
|
||||
height: 18vw;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.title, .channel, .duration, .size, #directoryInputLabel {
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
@@ -82,6 +89,10 @@ body {
|
||||
background-color: #424242;
|
||||
}
|
||||
|
||||
#directoryInput {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
/* CUSTOM CHECKMARK SPINNER */
|
||||
.circle-loader {
|
||||
margin-bottom: 3.5em;
|
||||
|
||||
112
downloader.js
112
downloader.js
@@ -4,13 +4,16 @@ const {remote} = require('electron')
|
||||
|
||||
let selectedURL
|
||||
let availableFormats = []
|
||||
let availableFormatCodes = []
|
||||
let formatSizes = []
|
||||
let audioSize;
|
||||
let ffmpegLoc
|
||||
let timings
|
||||
|
||||
if(process.platform === "darwin") {
|
||||
let appPath = remote.app.getAppPath().slice(0, -8)
|
||||
youtubedl.setYtdlBinary(appPath + "youtube-dl")
|
||||
ffmpegLoc = appPath + "ffmpeg"
|
||||
youtubedl.setYtdlBinary(appPath + "youtube-dl-darwin")
|
||||
ffmpegLoc = appPath + "ffmpeg-darwin"
|
||||
} else {
|
||||
youtubedl.setYtdlBinary("resources/youtube-dl.exe")
|
||||
ffmpegLoc = "resources/ffmpeg.exe"
|
||||
@@ -26,6 +29,9 @@ function url_entered() {
|
||||
let url = $("#url").val()
|
||||
if(validate(url)) {
|
||||
availableFormats = []
|
||||
formatSizes = []
|
||||
availableFormatCodes = []
|
||||
audioSize = []
|
||||
showInfo(url)
|
||||
$('#url').addClass("is-valid").removeClass("is-invalid")
|
||||
} else {
|
||||
@@ -44,6 +50,7 @@ function showInfo(url) {
|
||||
youtubedl.getInfo(url, function(err, info) {
|
||||
if (err) showError(err)
|
||||
$(".thumbnail").attr("src", info.thumbnail)
|
||||
$(".thumbnail-settings").attr("src", info.thumbnail)
|
||||
$(".title").html("<strong>Title:</strong> " + info.title)
|
||||
$(".channel").html("<strong>Channel:</strong> " + info.uploader)
|
||||
$(".duration").html("<strong>Duration:</strong> " + info.duration)
|
||||
@@ -55,27 +62,37 @@ function showInfo(url) {
|
||||
if (err) showError(err)
|
||||
output.splice(0,3)
|
||||
console.log(output)
|
||||
let audio
|
||||
output.forEach(function(entry) {
|
||||
if(entry.includes("audio only") && entry.includes("m4a")) audio = entry
|
||||
if(!(entry.includes('mp4') || entry.includes('webm'))) return
|
||||
if(entry.includes('4320p')) addFormat("4320p", entry)
|
||||
if(entry.includes('2160p')) addFormat("2160p", entry)
|
||||
if(entry.includes('1440p')) addFormat("1440p", entry)
|
||||
if(entry.includes('1080p')) addFormat("1080p", entry)
|
||||
if(entry.includes('720p')) addFormat("720p", entry)
|
||||
if(entry.includes('480p')) addFormat("480p", entry)
|
||||
if(entry.includes('360p')) addFormat("360p", entry)
|
||||
if(entry.includes('240p')) addFormat("240p", entry)
|
||||
if(entry.includes('144p')) addFormat("144p", entry)
|
||||
if(entry.includes('4320p')) addFormat("4320p", entry, audio)
|
||||
if(entry.includes('2160p')) addFormat("2160p", entry, audio)
|
||||
if(entry.includes('1440p')) addFormat("1440p", entry, audio)
|
||||
if(entry.includes('1080p')) addFormat("1080p", entry, audio)
|
||||
if(entry.includes('720p')) addFormat("720p", entry, audio)
|
||||
if(entry.includes('480p')) addFormat("480p", entry, audio)
|
||||
if(entry.includes('360p')) addFormat("360p", entry, audio)
|
||||
if(entry.includes('240p')) addFormat("240p", entry, audio)
|
||||
if(entry.includes('144p')) addFormat("144p", entry, audio)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function downloadAudio(quality) {
|
||||
console.log(quality)
|
||||
let realQuality = 0
|
||||
if(quality === "worst") {
|
||||
realQuality = '9'
|
||||
}
|
||||
const options = [
|
||||
'-f', quality + 'audio[ext=m4a]',
|
||||
'--extract-audio', '--audio-quality', realQuality,
|
||||
'--audio-format', 'mp3',
|
||||
'--ffmpeg-location', ffmpegLoc, '--hls-prefer-ffmpeg',
|
||||
'-o', remote.app.getPath('music').replace(/\\/g, "/") + '/' + '%(title)s.%(ext)s'
|
||||
'--embed-thumbnail',
|
||||
'-o', downloadPath.replace(/\\/g, "/") + '/' + '%(title)s.%(ext)s'
|
||||
]
|
||||
console.log(options)
|
||||
youtubedl.exec(selectedURL, options, {}, function(err, output) {
|
||||
if (err) showError(err)
|
||||
downloadFinished()
|
||||
@@ -85,21 +102,12 @@ function downloadAudio(quality) {
|
||||
|
||||
function downloadVideo(quality) {
|
||||
let downloadSubs = $('#subtitles').prop('checked')
|
||||
let fps = quality.substr(-2)
|
||||
let qualityOption
|
||||
let height
|
||||
if(fps === "60" || fps === "50") {
|
||||
height = quality.slice(0,-3);
|
||||
qualityOption = 'bestvideo[height<='+ height + '][fps=' + fps + ']+bestaudio[ext=m4a]/best[height<=' + height + '][fps=' + fps + ']'
|
||||
} else {
|
||||
height = quality.slice(0,-1);
|
||||
qualityOption = 'bestvideo[height<='+ height + '][fps<50]+bestaudio[ext=m4a]/best[height<=' + height + '][fps<50]'
|
||||
}
|
||||
let qualityOption = quality + "+bestaudio[ext=m4a]/best"
|
||||
const options = [
|
||||
'-f', qualityOption,
|
||||
'--ffmpeg-location', ffmpegLoc, '--hls-prefer-ffmpeg',
|
||||
'--merge-output-format', 'mp4',
|
||||
'-o', remote.app.getPath('videos').replace(/\\/g, "/") + '/' + '%(title)s.%(ext)s'
|
||||
'-o', downloadPath.replace(/\\/g, "/") + '/' + '%(title)s-(%(height)sp%(fps)s).%(ext)s'
|
||||
]
|
||||
if(downloadSubs) {
|
||||
options.push("--all-subs")
|
||||
@@ -117,7 +125,7 @@ function downloadVideo(quality) {
|
||||
|
||||
function download() {
|
||||
let quality = $('#quality').val()
|
||||
timings = setTimeout(showWarning, 60000)
|
||||
timings = setTimeout(showWarning, 90000)
|
||||
stepper.next()
|
||||
if($('input[name=type-select]:checked').val() === "video") {
|
||||
downloadVideo(quality)
|
||||
@@ -133,24 +141,61 @@ function downloadFinished() {
|
||||
$('#reset-btn').html("Download another video").prop("disabled", false)
|
||||
}
|
||||
|
||||
function addFormat(quality, entry) {
|
||||
if(entry.includes(quality + "60")) {
|
||||
if(!availableFormats.includes(quality + "60")) availableFormats.push(quality + "60")
|
||||
} else if(entry.includes(quality + "50")) {
|
||||
if(!availableFormats.includes(quality + "50")) availableFormats.push(quality + "50")
|
||||
} else {
|
||||
if(!availableFormats.includes(quality)) availableFormats.push(quality)
|
||||
function addSize(entry, audio) {
|
||||
let vidSizeUnformat = entry.split(' ').pop()
|
||||
let vidUnit = vidSizeUnformat.slice(-3)
|
||||
let vidSize = parseFloat(vidSizeUnformat.slice(0, -3))
|
||||
let audSizeUnformat = audio.split(' ').pop()
|
||||
let audUnit = audSizeUnformat.slice(-3)
|
||||
let audSize = parseFloat(audSizeUnformat.slice(0, -3))
|
||||
if(vidUnit === audUnit) {
|
||||
let mib = audSize + vidSize
|
||||
formatSizes.push(mib.toFixed(1) + "MB")
|
||||
} else if(audUnit === "MiB") {
|
||||
let mib = audSize + (vidSize/1024)
|
||||
formatSizes.push(mib.toFixed(1) + "MB")
|
||||
} else if(audUnit === "KiB") {
|
||||
let mib = (audSize/1024 + vidSize)
|
||||
formatSizes.push(mib.toFixed(1) + "MB")
|
||||
}
|
||||
audioSize = "~" + audSize.toFixed(1) + "MB"
|
||||
}
|
||||
|
||||
function addFormat(quality, entry, audio) {
|
||||
if(entry.includes(quality + "60")) {
|
||||
if(!availableFormats.includes(quality + "60")) {
|
||||
availableFormats.push(quality + "60")
|
||||
availableFormatCodes.push(entry.slice(0,3))
|
||||
addSize(entry, audio)
|
||||
}
|
||||
} else if(entry.includes(quality + "50")) {
|
||||
if(!availableFormats.includes(quality + "50")) {
|
||||
availableFormats.push(quality + "50")
|
||||
availableFormatCodes.push(entry.slice(0,3))
|
||||
addSize(entry, audio)
|
||||
}
|
||||
} else {
|
||||
if(!availableFormats.includes(quality)) {
|
||||
availableFormats.push(quality)
|
||||
availableFormatCodes.push(entry.slice(0,3))
|
||||
addSize(entry, audio)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function resetSteps() {
|
||||
selectedURL = ""
|
||||
availableFormats = []
|
||||
formatSizes = []
|
||||
availableFormatCodes = []
|
||||
audioSize = []
|
||||
$('#url').removeClass("is-valid").removeClass("is-invalid")
|
||||
$(".thumbnail").attr("src", "https://via.placeholder.com/640x360?text=%20")
|
||||
$(".title").html("<strong>Title:</strong> --")
|
||||
$(".channel").html("<strong>Channel:</strong> --")
|
||||
$(".duration").html("<strong>Duration:</strong> --")
|
||||
$(".size").html("<strong>Download size:</strong> --")
|
||||
$('.main-input').trigger('reset')
|
||||
$('.circle-loader').toggleClass('load-complete')
|
||||
$('.checkmark').toggle()
|
||||
@@ -159,6 +204,7 @@ function resetSteps() {
|
||||
$('#subtitles').prop("disabled", true).prop("checked", false)
|
||||
$('#quality').empty().append(new Option("Select quality", "quality")).prop("disabled", true).val("quality")
|
||||
$("#download-btn").prop("disabled", true)
|
||||
$("#directoryInput").prop("disabled", true)
|
||||
stepper.reset()
|
||||
}
|
||||
|
||||
@@ -169,6 +215,8 @@ function resetBack() {
|
||||
$('#subtitles').prop("disabled", true).prop("checked", false)
|
||||
$('#quality').empty().append(new Option("Select quality", "quality")).prop("disabled", true).val("quality")
|
||||
$("#download-btn").prop("disabled", true)
|
||||
$("#directoryInput").prop("disabled", true)
|
||||
$(".size").html("<strong>Download size:</strong> --")
|
||||
}
|
||||
|
||||
function showWarning() {
|
||||
|
||||
31
index.html
31
index.html
@@ -49,7 +49,7 @@
|
||||
<div class="spinner-border text-dark" role="status">
|
||||
<span class="sr-only">Loading...</span>
|
||||
</div>
|
||||
<img src="img/waiting-for-link.png" class="img-fluid thumbnail" alt="Thumbnail of the specified video">
|
||||
<img src="web-resources/waiting-for-link.png" class="img-fluid thumbnail" alt="Thumbnail of the specified video">
|
||||
</div>
|
||||
<div class="col-md-6 text-left">
|
||||
<p class="title"><strong>Title:</strong> --</p>
|
||||
@@ -67,10 +67,12 @@
|
||||
<div id="settings-part" class="content fade" role="tabpanel" aria-labelledby="settings-part-trigger">
|
||||
<form class="main-input">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<img src="img/waiting-for-link.png" class="img-fluid thumbnail" alt="Thumbnail of the specified video">
|
||||
<div class="col-md-5 text-left">
|
||||
<img src="web-resources/waiting-for-link.png" class="img-fluid thumbnail-settings" alt="Thumbnail of the specified video">
|
||||
<p class="size mt-3"><strong>Download size:</strong> --</p>
|
||||
<p class="duration mb-0"><strong>Duration:</strong> --</p>
|
||||
</div>
|
||||
<div class="col-md-6 text-left">
|
||||
<div class="col-md-7 text-left">
|
||||
<div class="form-group">
|
||||
<form id="settings">
|
||||
<div class="custom-control custom-radio custom-control-inline">
|
||||
@@ -93,6 +95,12 @@
|
||||
<label class="custom-control-label" for="subtitles">Add subtitles (if available)</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="custom-file">
|
||||
<input type="text" onclick="setDirectory()" class="custom-file-input" id="directoryInput" disabled>
|
||||
<label class="custom-file-label" id="directoryInputLabel" for="directoryInput">Choose download directory</label>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<button type="button" onclick="resetBack()" class="btn btn-dark">Back</button>
|
||||
@@ -130,6 +138,15 @@
|
||||
An error has occured, please report this to the author.
|
||||
</div>
|
||||
</div>
|
||||
<div class="toast" id="connection" role="alert" aria-live="assertive" aria-atomic="true">
|
||||
<div class="toast-header bg-danger">
|
||||
<i class="fas mr-3 fa-wifi"></i>
|
||||
<strong class="mr-auto">No internet connection found!</strong>
|
||||
</div>
|
||||
<div class="toast-body">
|
||||
Please connect to the internet and restart the app. This app will not work without an internet connection.
|
||||
</div>
|
||||
</div>
|
||||
<div class="toast warning-toast" id="warning" role="alert" aria-live="assertive" aria-atomic="true">
|
||||
<div class="toast-header bg-warning">
|
||||
<i class="fas mr-3 fa-exclamation-triangle"></i>
|
||||
@@ -139,12 +156,14 @@
|
||||
</button>
|
||||
</div>
|
||||
<div class="toast-body">
|
||||
The download is taking longer than usual, this might be because you are downloading a large file. Otherwise please restart the program.
|
||||
The download is taking longer than usual, this might be because you're downloading a large file, have a slow connection, or are downloading subtitles. Otherwise please restart the program.
|
||||
</div>
|
||||
</div>
|
||||
<script src="downloader.js"></script>
|
||||
<script src="plugins.js"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bs-stepper@1.7.0/dist/js/bs-stepper.min.js" integrity="sha256-INfYp5owpb0btFquNHGlhSxgGYrFlGYRU2oN/3jWGeM=" crossorigin="anonymous"></script>
|
||||
<script src="downloader.js"></script>
|
||||
<script src="metrics.js"></script>
|
||||
<script src="updater.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
8
main.js
8
main.js
@@ -12,7 +12,7 @@ function createWindow () {
|
||||
resizable: false,
|
||||
maximizable: false,
|
||||
titleBarStyle: "hidden",
|
||||
icon: "img/icon-light.png",
|
||||
icon: "web-resources/icon-light.png",
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
@@ -25,7 +25,7 @@ function createWindow () {
|
||||
resizable: false,
|
||||
maximizable: false,
|
||||
frame: false,
|
||||
icon: "img/icon-light.png",
|
||||
icon: "web-resources/icon-light.png",
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
}
|
||||
@@ -33,7 +33,9 @@ function createWindow () {
|
||||
}
|
||||
|
||||
win.removeMenu()
|
||||
//win.webContents.openDevTools()
|
||||
if(process.argv[2] === '--dev') {
|
||||
win.webContents.openDevTools()
|
||||
}
|
||||
win.loadFile('index.html')
|
||||
win.on('closed', () => {
|
||||
win = null
|
||||
|
||||
63
metrics.js
Normal file
63
metrics.js
Normal file
@@ -0,0 +1,63 @@
|
||||
const os = require('os')
|
||||
const fs = require('fs')
|
||||
|
||||
let Platform = process.platform
|
||||
let Version = remote.app.getVersion()
|
||||
let ram = (process.getSystemMemoryInfo().total / 1.074e+6).toFixed(0)
|
||||
let cpuModel = os.cpus()[0].model
|
||||
let cpuCores = os.cpus().length
|
||||
let country = remote.app.getLocaleCountryCode()
|
||||
|
||||
let metricsID;
|
||||
let appTrimPath
|
||||
|
||||
startMetrics()
|
||||
|
||||
function startMetrics() {
|
||||
if(process.platform === "darwin") {
|
||||
appTrimPath = remote.app.getAppPath().slice(0, -8)
|
||||
} else {
|
||||
appTrimPath = "resources/"
|
||||
}
|
||||
fs.access(appTrimPath + "metricsID.txt", fs.F_OK, function(err) {
|
||||
if (err) {
|
||||
metricsID = generateUUID();
|
||||
fs.writeFile(appTrimPath + "metricsID.txt", metricsID, 'utf-8', function(err) {
|
||||
if(err) console.log(err)
|
||||
sendInitialMetrics()
|
||||
})
|
||||
} else {
|
||||
fs.readFile(appTrimPath + "metricsID.txt", 'utf-8', function (err, data) {
|
||||
if (err) console.log(err)
|
||||
metricsID = data
|
||||
sendInitialMetrics()
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function sendInitialMetrics() {
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: 'http://backend.jelleglebbeek.com/youtubedl/metrics.php',
|
||||
dataType: 'json',
|
||||
data: {
|
||||
uuid: metricsID,
|
||||
version: Version,
|
||||
platform: Platform,
|
||||
memory: ram,
|
||||
cpumodel: cpuModel,
|
||||
cpucores: cpuCores,
|
||||
countrycode: country
|
||||
},
|
||||
success: function() {
|
||||
console.log("Metrics send.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function generateUUID() {
|
||||
return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>
|
||||
(c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
|
||||
);
|
||||
}
|
||||
30
package-lock.json
generated
30
package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "youtube-dl-gui",
|
||||
"version": "1.1.3",
|
||||
"version": "1.2.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@@ -817,6 +817,15 @@
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.5.5",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
|
||||
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"minimist": "^1.2.5"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
@@ -1384,12 +1393,9 @@
|
||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.5.4",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.4.tgz",
|
||||
"integrity": "sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw==",
|
||||
"requires": {
|
||||
"minimist": "^1.2.5"
|
||||
}
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
|
||||
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
@@ -2348,6 +2354,16 @@
|
||||
"request": "~2.88.0",
|
||||
"streamify": "~0.2.9",
|
||||
"universalify": "~0.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"mkdirp": {
|
||||
"version": "0.5.5",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
|
||||
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
|
||||
"requires": {
|
||||
"minimist": "^1.2.5"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"zero-fill": {
|
||||
|
||||
19
package.json
19
package.json
@@ -4,7 +4,7 @@
|
||||
"description": "A GUI for the YouTube-dl library",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
"start": "electron .",
|
||||
"start": "electron . --dev",
|
||||
"dist": "electron-builder"
|
||||
},
|
||||
"keywords": [],
|
||||
@@ -12,7 +12,8 @@
|
||||
"license": "GPL-3.0-only",
|
||||
"devDependencies": {
|
||||
"electron": "^8.2.0",
|
||||
"electron-builder": "^22.4.1"
|
||||
"electron-builder": "^22.4.1",
|
||||
"request": "^2.88.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-free": "^5.13.0",
|
||||
@@ -20,6 +21,7 @@
|
||||
"custom-electron-titlebar": "^3.2.2-hotfix62",
|
||||
"fs": "0.0.1-security",
|
||||
"jquery": "^3.4.1",
|
||||
"mkdirp": "^1.0.4",
|
||||
"popper.js": "^1.16.1",
|
||||
"youtube-dl": "^3.0.2"
|
||||
},
|
||||
@@ -41,7 +43,10 @@
|
||||
{
|
||||
"from": "resources",
|
||||
"to": "./",
|
||||
"filter": ["ffmpeg.exe", "youtube-dl.exe"]
|
||||
"filter": [
|
||||
"ffmpeg.exe",
|
||||
"youtube-dl.exe"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -53,12 +58,12 @@
|
||||
{
|
||||
"from": "resources",
|
||||
"to": "./",
|
||||
"filter": ["ffmpeg", "youtube-dl"]
|
||||
"filter": [
|
||||
"ffmpeg",
|
||||
"youtube-dl"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"linux": {
|
||||
"target": "AppImage"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
44
plugins.js
44
plugins.js
@@ -3,15 +3,17 @@ window.$ = window.jQuery = require('jquery')
|
||||
const customTitlebar = require('custom-electron-titlebar')
|
||||
|
||||
let stepper
|
||||
let downloadPath = remote.app.getPath('downloads');
|
||||
let downloadMode
|
||||
|
||||
if(process.platform === "darwin") {
|
||||
new customTitlebar.Titlebar({
|
||||
backgroundColor: customTitlebar.Color.fromHex('#000000'),
|
||||
backgroundColor: customTitlebar.Color.fromHex('#212121'),
|
||||
maximizable: false,
|
||||
shadow: true,
|
||||
shadow: false,
|
||||
titleHorizontalAlignment: "center",
|
||||
enableMnemonics: false,
|
||||
icon: "img/icon-light.png"
|
||||
icon: "web-resources/icon-light.png"
|
||||
})
|
||||
} else {
|
||||
new customTitlebar.Titlebar({
|
||||
@@ -20,7 +22,7 @@ if(process.platform === "darwin") {
|
||||
shadow: true,
|
||||
titleHorizontalAlignment: "left",
|
||||
enableMnemonics: false,
|
||||
icon: "img/icon-light.png"
|
||||
icon: "web-resources/icon-light.png"
|
||||
})
|
||||
}
|
||||
|
||||
@@ -37,18 +39,48 @@ $(document).ready(function () {
|
||||
autohide: false,
|
||||
animation: true
|
||||
})
|
||||
$('#connection').toast({
|
||||
autohide: false,
|
||||
animation: true
|
||||
})
|
||||
$("#directoryInputLabel").html(remote.app.getPath('downloads'))
|
||||
$("#quality").on('change', function() {
|
||||
if(downloadMode === "audio") return
|
||||
let index = availableFormats.indexOf(document.getElementById("quality").options[document.getElementById("quality").selectedIndex].text)
|
||||
$('.size').html('<b>Download size: </b>' + formatSizes[index])
|
||||
})
|
||||
})
|
||||
|
||||
function setDirectory() {
|
||||
$('#directoryInput').blur();
|
||||
let path = remote.dialog.showOpenDialog(remote.getCurrentWindow(), {
|
||||
defaultPath: downloadPath,
|
||||
properties: [
|
||||
'openDirectory',
|
||||
'createDirectory'
|
||||
]
|
||||
}).then(result => {
|
||||
$('#directoryInputLabel').html(result.filePaths[0])
|
||||
downloadPath = result.filePaths[0]
|
||||
})
|
||||
}
|
||||
|
||||
function setType(type) {
|
||||
$("#download-btn").prop("disabled", false)
|
||||
$("#directoryInput").prop("disabled", false)
|
||||
if(type === "audio") {
|
||||
downloadMode = "audio"
|
||||
$('#quality').empty().append(new Option("Best", "best")).append(new Option("Worst", "worst")).prop("disabled", false).val("best")
|
||||
$('.size').html('<b>Download size: </b>' + audioSize)
|
||||
} else if(type === "video") {
|
||||
downloadMode = "video"
|
||||
$('#quality').empty()
|
||||
availableFormats.forEach(function(quality) {
|
||||
$('#quality').append(new Option(quality, quality)).prop("disabled", false)
|
||||
$('#quality').append(new Option(quality, availableFormatCodes[availableFormats.indexOf(quality)])).prop("disabled", false)
|
||||
$('#subtitles').prop("disabled", false)
|
||||
})
|
||||
$('#quality').val(availableFormats[availableFormats.length-1])
|
||||
$('#quality').val(availableFormatCodes[availableFormatCodes.length-1])
|
||||
let index = availableFormats.indexOf(document.getElementById("quality").options[document.getElementById("quality").selectedIndex].text)
|
||||
$('.size').html('<b>Download size: </b>' + formatSizes[index])
|
||||
}
|
||||
}
|
||||
|
||||
1
resources/details
Normal file
1
resources/details
Normal file
@@ -0,0 +1 @@
|
||||
{"version":"2020.03.24","path":"resources/youtube-dl.exe"}
|
||||
0
resources/ffmpeg → resources/ffmpeg-darwin
Executable file → Normal file
0
resources/ffmpeg → resources/ffmpeg-darwin
Executable file → Normal file
0
resources/youtube-dl → resources/youtube-dl-darwin
Executable file → Normal file
0
resources/youtube-dl → resources/youtube-dl-darwin
Executable file → Normal file
73
updater.js
Normal file
73
updater.js
Normal file
@@ -0,0 +1,73 @@
|
||||
'use strict'
|
||||
const request = require('request')
|
||||
|
||||
let defaultBin;
|
||||
let defaultPath;
|
||||
let filePath
|
||||
let url = 'https://yt-dl.org/downloads/latest/youtube-dl'
|
||||
|
||||
if(process.platform === "darwin") {
|
||||
defaultBin = remote.app.getAppPath().slice(0, -8)
|
||||
defaultPath = defaultBin + 'details'
|
||||
filePath = defaultBin + "youtube-dl-darwin"
|
||||
} else {
|
||||
defaultPath = "resources/details"
|
||||
filePath = "resources/youtube-dl.exe"
|
||||
url = "https://yt-dl.org/downloads/latest/youtube-dl.exe"
|
||||
}
|
||||
|
||||
update()
|
||||
|
||||
function update() {
|
||||
request.get(url, { followRedirect: false }, function (err, res) {
|
||||
if (err) {
|
||||
console.log(err)
|
||||
if(err.toString().includes('ENOTFOUND')) {
|
||||
$('#connection').toast('show')
|
||||
$('#url').prop("disabled", true).attr("placeholder", "Please connect to the internet and restart this app")
|
||||
}
|
||||
return
|
||||
}
|
||||
if (res.statusCode !== 302) {
|
||||
return console.log('Did not get redirect for the latest version link. Status: ' + res.statusCode)
|
||||
}
|
||||
const newUrl = res.headers.location
|
||||
const newVersion = /yt-dl\.org\/downloads\/(\d{4}\.\d\d\.\d\d(\.\d)?)\/youtube-dl/.exec(newUrl)[1]
|
||||
console.log("Latest release: " + newVersion)
|
||||
if(newVersion === getCurrentVersion()) {
|
||||
console.log("Binaries were already up-to-date!")
|
||||
} else {
|
||||
console.log("New version found! Updating...")
|
||||
const downloadFile = request.get(newUrl)
|
||||
downloadFile.on('response', function response(res) {
|
||||
if (res.statusCode !== 200) {
|
||||
console.log('Response Error: ' + res.statusCode)
|
||||
return
|
||||
}
|
||||
downloadFile.pipe(fs.createWriteStream(filePath, {mode: 493}))
|
||||
})
|
||||
downloadFile.on('error', function error(err) {
|
||||
console.log(err)
|
||||
})
|
||||
downloadFile.on('end', function end() {
|
||||
console.log("New youtube-dl version downloaded: " + newVersion)
|
||||
console.log("Writing version data...")
|
||||
fs.writeFileSync(
|
||||
defaultPath,
|
||||
JSON.stringify({
|
||||
version: newVersion,
|
||||
path: filePath
|
||||
}),
|
||||
'utf8'
|
||||
)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function getCurrentVersion() {
|
||||
let details = JSON.parse(fs.readFileSync(defaultPath, 'utf-8'))
|
||||
console.log("Current version: " + details.version)
|
||||
return details.version;
|
||||
|
||||
}
|
||||
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 9.6 KiB After Width: | Height: | Size: 9.6 KiB |
|
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 8.1 KiB |
Reference in New Issue
Block a user