Skip to content

Commit

Permalink
fix: binaries
Browse files Browse the repository at this point in the history
  • Loading branch information
Markkop committed Apr 25, 2020
1 parent 3400074 commit f8cee96
Show file tree
Hide file tree
Showing 9 changed files with 131 additions and 267 deletions.
Binary file removed bin/ffmpeg.exe
Binary file not shown.
Binary file removed bin/youtube-dl.exe
Binary file not shown.
7 changes: 3 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
"repository": "github:markkop/yt-dlandcut",
"main": "build/electron/main.js",
"scripts": {
"test": "babel-node src/download.js",
"postinstall": "electron-builder install-app-deps",
"start": "electron .",
"start": "yarn transpile && electron .",
"transpile": "babel src --out-dir build",
"pack": "electron-builder --dir",
"build": "yarn transpile && electron-builder",
Expand All @@ -24,7 +25,7 @@
"@babel/cli": "^7.8.4",
"@babel/plugin-transform-runtime": "^7.9.0",
"@babel/runtime": "^7.9.2",
"ffmpeg-static": "^4.1.1",
"axios": "^0.19.2",
"fluent-ffmpeg": "^2.1.2",
"youtube-dl": "^3.0.2"
},
Expand All @@ -40,9 +41,7 @@
"asar": false,
"files": [
"build/**/*",
"bin/*",
"public/*",
"node_modules/youtube-dl/bin/youtube-dl",
"package.json"
],
"linux": {
Expand Down
20 changes: 3 additions & 17 deletions src/convert.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,7 @@
import { remote } from 'electron'
import path from 'path'
import ffmpeg from 'fluent-ffmpeg'
import { checkAndCreateFolder, updateStatus } from './helpers'
import pathToFfmpeg from 'ffmpeg-static'
let ffmpegPath = pathToFfmpeg

/**
* Change ffmpeg binary to its exe version.
* TO DO: refactor this
*/
export function useWindowsBinaryFfmpeg() {
if (process.platform === 'win32') {
ffmpegPath = path.resolve(remote.app.getAppPath(), 'bin/ffmpeg.exe')
const message = `Windows detected: using ffmpeg.exe at ${ffmpegPath}`
updateStatus(message)
}
}
import { ffmpegFilePath } from './settings'

/**
* Cut videos by it's start time and duration in seconds
Expand All @@ -35,7 +21,7 @@ export function cutVideo(inputPath, outputPath, fileName, startTime, duration) {
conv
.setStartTime(startTime)
.setDuration(duration)
.setFfmpegPath(ffmpegPath)
.setFfmpegPath(ffmpegFilePath)
.on('start', function (commandLine) {
const message = `Starting ffmpeg with command:\n${commandLine}`
updateStatus(message)
Expand Down Expand Up @@ -70,7 +56,7 @@ export function convertToMp3(inputPath, outputPath, fileName) {
const conv = new ffmpeg({ source: inputPath })
conv
.toFormat('mp3')
.setFfmpegPath(ffmpegPath)
.setFfmpegPath(ffmpegFilePath)
.on('start', function (commandLine) {
const message = `Starting ffmpeg with command:\n${commandLine}`
updateStatus(message)
Expand Down
95 changes: 81 additions & 14 deletions src/download.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,9 @@
import { remote } from 'electron'
import fs from 'fs'
import path from 'path'
import youtubedl from 'youtube-dl'
import { checkAndCreateFolder, updateStatus } from './helpers'

/**
* Change youtube-dl binary to its exe version.
* TO DO: Refactor this to merge it with the similar function at convert.js
*/
export function useWindowsBinaryYoutubeDl() {
if (process.platform === 'win32') {
const customBinaryPath = path.resolve(remote.app.getAppPath(), 'bin/youtube-dl.exe')
youtubedl.setYtdlBinary(customBinaryPath)
const message = `Windows detected: using youtube-dl.exe at ${youtubedl.getYtdlBinary()}`
updateStatus(message)
}
}
import axios from 'axios'
import { binariesPath, youtubeDlFilePath, ffmpegFilePath } from './settings'

/**
* Get Youtube's video title
Expand Down Expand Up @@ -46,6 +34,7 @@ export function getVideoTitle(url = '') {
export function downloadFromYoutube(youtubeUrl, downloadPath, fileName, overwriteFile) {
return new Promise((resolve, reject) => {
try {
youtubedl.setYtdlBinary(youtubeDlFilePath)
checkAndCreateFolder(downloadPath)
const filePath = path.join(downloadPath, `${fileName}.mp4`)

Expand Down Expand Up @@ -74,3 +63,81 @@ export function downloadFromYoutube(youtubeUrl, downloadPath, fileName, overwrit
}
})
}

/**
* Check and download required binaries according to os
* @param { String } basePath
* @returns { Promise<Bollean> } success
*/
export function checkAndDownloadBinaries() {
return new Promise(async (resolve, reject) => {
let success = true
const isWin = process.platform === 'win32'
const ffmpegFileName = isWin ? 'ffmpeg.exe' : 'ffmpeg'
const youtubeDlFileName = isWin ? 'youtube-dl.exe' : 'youtube-dl'

const hasYoutubeDl = fs.existsSync(youtubeDlFilePath)
const hasFfmpeg = fs.existsSync(ffmpegFilePath)

if (!hasYoutubeDl && !hasFfmpeg) {
updateStatus(
"It looks like this is your first time running this app, I'll download the required files it needs to work. ;)"
)
}
if (!hasYoutubeDl) {
updateStatus(`File ${youtubeDlFilePath} not found, downloading...`)
const youtubeDlUrl = `https://github.com/ytdl-org/youtube-dl/releases/latest/download/${youtubeDlFileName}`
success = await downloadFile(youtubeDlUrl, binariesPath, youtubeDlFileName)
}

if (!hasFfmpeg) {
updateStatus(`File ${ffmpegFilePath} not found, downloading...`)
updateStatus('This one is kinda big, it may take a while :o')
const ffmpegDownloadName = `${process.platform}-${process.arch}`
const ffmpegUrl = `https://github.com/eugeneware/ffmpeg-static/releases/latest/download/${ffmpegDownloadName}`
success = await downloadFile(ffmpegUrl, binariesPath, ffmpegFileName)
}

if (success) {
return resolve(true)
} else {
return reject(false)
}
})
}

/**
* Downloads a file
* @param { String } url
* @param { String } downloadPath
* @param { String } fileName
* @returns { Promise<String|false> } downloaded file path or false
*/
async function downloadFile(url, downloadPath, fileName) {
axios.defaults.adapter = require('axios/lib/adapters/http')

checkAndCreateFolder(downloadPath)
updateStatus(`Downloading ${url} to ${downloadPath}`)

const downloadFilePath = path.join(downloadPath, fileName)
const writer = fs.createWriteStream(downloadFilePath)
const response = await axios(url, {
method: 'GET',
responseType: 'stream',
})
response.data.pipe(writer)

return new Promise((resolve, reject) => {
writer.on('finish', () => {
updateStatus(`Download finished`)
if (process.platform === 'linux') {
fs.chmodSync(downloadFilePath, 0o755)
}
resolve(path)
})
writer.on('error', (err) => {
updateStatus(`Error on download: ${err}`)
reject(false)
})
})
}
4 changes: 2 additions & 2 deletions src/helpers.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { shell } from 'electron'
import fs from 'fs'
import { shell } from 'electron'

/**
* Get the time duration betweet two dates
Expand Down Expand Up @@ -44,7 +44,7 @@ export function updateStatus(message) {
const today = new Date()
const time = today.getHours() + ':' + today.getMinutes() + ':' + today.getSeconds()
console.log(message)
if (!document) {
if (typeof document === 'undefined') {
return
}

Expand Down
19 changes: 11 additions & 8 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import path from 'path'
import { getDuration, openItem, slugify, updateStatus } from './helpers'
import { downloadFromYoutube, getVideoTitle, useWindowsBinaryYoutubeDl } from './download'
import { cutVideo, convertToMp3, useWindowsBinaryFfmpeg } from './convert'
import { basePath } from './settings'
import { downloadFromYoutube, getVideoTitle, checkAndDownloadBinaries } from './download'
import { cutVideo, convertToMp3 } from './convert'
import { basePath, binariesPath } from './settings'

/**
* Runs this package
Expand All @@ -14,9 +14,7 @@ export async function downloadAndCut(youtubeUrl, startTime, endTime, options) {
}
updateStatus('Starting...')

// TO DO: refactor windows binaries usage
useWindowsBinaryYoutubeDl()
useWindowsBinaryFfmpeg()
await checkAndDownloadBinaries(binariesPath)

const { customFileName, openAtFinish, toMp3, overwriteDownload } = options

Expand Down Expand Up @@ -45,7 +43,12 @@ export async function downloadAndCut(youtubeUrl, startTime, endTime, options) {

updateStatus('Finished! Check your files in your home folder.')
} catch (error) {
// TO DO: better error handling on all files
console.error(error)
updateStatus(`Something bad happened :c. Here's what you can try:
- Clean your ${binariesPath} folder and try again
- Check the youtube url and times
- Lay down and cry :'(
- Ask me for help on Twitter: @HeyMarkKop
- Check the error below, it might have something useful`)
updateStatus(error)
}
}
9 changes: 7 additions & 2 deletions src/settings.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { remote } from 'electron'
import path from 'path'

const isWin = process.platform === 'win32'

const homePath = remote.app.getPath('home')
const basePath = path.resolve(`${homePath}/yt-dlandcut`)
const basePath = path.resolve(homePath, 'yt-dlandcut')
const binariesPath = path.resolve(basePath, 'binaries')
const youtubeDlFilePath = path.resolve(binariesPath, isWin ? 'youtube-dl.exe' : 'youtube-dl')
const ffmpegFilePath = path.resolve(binariesPath, isWin ? 'ffmpeg.exe' : 'ffmpeg')

export { homePath, basePath }
export { homePath, basePath, binariesPath, youtubeDlFilePath, ffmpegFilePath }
Loading

0 comments on commit f8cee96

Please sign in to comment.