diff --git a/.travis.yml b/.travis.yml index f6f80df4..8185793f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,3 @@ -# https://github.com/develar/onshape-desktop-shell/blob/master/.travis.yml - branches: only: - master @@ -7,55 +5,12 @@ branches: - /^v.*$/ os: osx -osx_image: xcode9.3 +osx_image: xcode11.2 language: node_js node_js: - - "8" - -# https://discourse.brew.sh/t/wine-first-time-configuration-gets-stuck-forever-on-macos/1612 -env: - global: - - ELECTRON_CACHE=$HOME/.cache/electron - - ELECTRON_BUILDER_CACHE=$HOME/.cache/electron-builder - - WINEARCH=win32 - -cache: - yarn: true - directories: - - $HOME/.cache/electron - - $HOME/.cache/electron-builder - - ffmpeg-tmp/archives - -before_cache: - - rm -rf $HOME/.cache/electron-builder/wine - -before_install: - - HOMEBREW_NO_AUTO_UPDATE=1 brew install wine - - HOMEBREW_NO_AUTO_UPDATE=1 brew install p7zip + - 12 script: - | - npm run lint && - npm run download-ffmpeg && - ls ffmpeg-tmp/archives && - npm run extract-ffmpeg && - npm run build && npm run icon-gen && - npm run package - -deploy: - provider: releases - overwrite: true - api_key: - secure: "ncttMNBIvaY1R5iDUzB3vFkLXMNDtNiNNBZsvxvD0FxtuYVMLA3NYVcqbYxO94LgE1idR6GePlyhGmrxtjD3cahLf0+2DhoVZqykZF6Y/EGaC8aLP5di6UQKR2gubDiP+GWvqHTA9Y9oZp8vOh2zGz20tT92U6F9hLxiD0k6wHachLAWDKTOU+TjpZjpmnT7Cchmn9s0pmGzn3557kCh4v4X+D+GPk/kGzvN0wuEf75kHPJ2wCj0NgO2TfH3pK7w4mI7NDtnAooNr9UJc4fWxo+Pelob7XY6A/pfkCfywx0lZjBg0A6AsL3pon/p9ERuHN1s4Sqj4njpkeqfk3y4s0wOh4uF71PPN5TCJbb6mwdbmbAKMnx4VaQZC9G55+xjSeh5Kr0Due5TMlaEWF14Ft4klEBsoRF7QmCxkAoitzYmPlz78oeEpnhU/kZcdvptXnREiv/093MD+MIfg7a6+xZEkJjDGvDB9GrWnVcnq5MOo/fknWhE/az8AW8h7A/zCykmJeUwS67CD/lhBouzjblIBhuGzWZMMUEqbNFJy1qXOgFO2YrXfMMUms6U0NpK4fDVMgghQqLf+95vv/8e/CnpWxLmPgFN+BPFPQPBVLqOVyZtw/brLzebAaaInudVKsmjhw6hXF11hX4U+fBdbc+JeLxMcLaVO/zP25ZeUak=" - file: - - package/LosslessCut-darwin-x64.zip - - package/LosslessCut-win32-ia32.zip - - package/LosslessCut-win32-x64.zip - - package/LosslessCut-linux-ia32.zip - - package/LosslessCut-linux-x64.zip - skip_cleanup: true - draft: true -# tag_name: $TRAVIS_TAG - on: - tags: true + yarn release diff --git a/package.json b/package.json index a9971083..2e298ec2 100644 --- a/package.json +++ b/package.json @@ -1,28 +1,26 @@ { "name": "lossless-cut", + "productName": "LosslessCut", + "description": "Lossless video editor", + "copyright": "Copyright © 2019 ${author}", "version": "2.4.0", - "description": "", - "main": "index.js", + "main": "build/index.js", "scripts": { - "start": "electron dist", - "watch": "npm run build && babel src -d dist --copy-files -w", - "build": "rm -rf dist && babel src -d dist --copy-files && ln -s ../node_modules dist/ && ln -s ../package.json ./dist/", - "download-ffmpeg": "bash ./scripts/ffmpeg-dl/dl.sh", - "extract-ffmpeg": "bash ./scripts/ffmpeg-dl/extract.sh", - "copy-ffmpeg": "rm -rf dist/ffmpeg && mkdir dist/ffmpeg && cp ffmpeg-tmp/binaries/${PLATFORM}_${ARCH}/* dist/ffmpeg", - "package-single": "npm run copy-ffmpeg && electron-packager dist LosslessCut --out=package --asar.unpackDir=ffmpeg --overwrite --platform=${PLATFORM} --arch=${ARCH} --icon=icon-dist/${ICON} --app-copyright='Copyright (c) 2017 Mikael Finstad' --win32metadata.CompanyName=mifi --win32metadata.FileDescription=LosslessCut --win32metadata.OriginalFilename=LosslessCut.exe --win32metadata.ProductName=LosslessCut --win32metadata.InternalName=LosslessCut", - "package:darwin_x64": "PLATFORM=darwin ARCH=x64 ICON=app.icns npm run package-single", - "package:win32_ia32": "PLATFORM=win32 ARCH=ia32 ICON=app.ico npm run package-single", - "package:win32_x64": "PLATFORM=win32 ARCH=x64 ICON=app.ico npm run package-single", - "package:linux_x64": "PLATFORM=linux ARCH=x64 ICON=app.ico npm run package-single", - "zip": "(cd package && rm -f LosslessCut-*.zip && for f in LosslessCut-*; do zip -r --symlinks \"$f\".zip \"$f\"; done)", - "icon-gen": "icon-gen -i src/icon.svg -o ./icon-dist -r", - "package": "npm run package:darwin_x64 && npm run package:win32_ia32 && npm run package:win32_x64 && npm run package:linux_x64 && npm run zip", - "release": "gh-release -a package/LosslessCut-darwin-x64.zip,package/LosslessCut-win32-ia32.zip,package/LosslessCut-win32-x64.zip,package/LosslessCut-linux-ia32.zip,package/LosslessCut-linux-x64.zip", + "start": "electron watch-build", + "watch": "babel src -d watch-build --copy-files -w", + "icon-gen": "svg2png src/icon.svg -o ./icon-build/app-512.png -w 512 -h 512", + "build-js": "rm -rf build && babel src -d build --copy-files", + "postinstall": "electron-builder install-app-deps", + "pack-mac": "electron-builder --mac", + "prepack-mac": "yarn build-js", + "pack-win": "electron-builder --win", + "prepack-win": "yarn build-js", + "pack-linux": "electron-builder --linux", + "prepack-linux": "yarn build-js", + "prerelease": "yarn build-js", + "release": "build", "gifify": "gifify -p 405:299 -r 5@3 Untitled.mov-00.00.00.971-00.00.19.780.mp4", - "lint": "eslint --ext .jsx --ext .js .", - "clean": "rm -rf dist ffmpeg-tmp/extracted ffmpeg-tmp/binaries package", - "clean-ffmpeg": "rm -rf ffmpeg-tmp/archives" + "lint": "eslint --ext .jsx --ext .js ." }, "author": { "name": "Mikael Finstad", @@ -41,23 +39,24 @@ "babel-plugin-transform-object-rest-spread": "^6.26.0", "babel-preset-env": "^1.6.1", "babel-preset-react": "^6.16.0", - "electron-packager": "^8.1.0", + "electron": "^7.0.1", + "electron-builder": "21", "eslint": "^5.6.1", "eslint-config-airbnb": "^17.1.0", "eslint-plugin-import": "^2.14.0", "eslint-plugin-jsx-a11y": "^6.1.1", "eslint-plugin-react": "^7.11.1", - "gh-release": "^2.2.1", - "icon-gen": "^1.2.0" + "svg2png": "^4.1.1" }, "dependencies": { "bluebird": "^3.4.6", "classnames": "^2.2.5", "color": "^3.1.0", - "electron": "^2.0.18", "electron-default-menu": "^1.0.0", "electron-is-dev": "^0.1.2", "execa": "^0.5.0", + "ffmpeg-static": "^2.7.0", + "ffprobe-static": "^3.0.0", "file-type": "^11.0.0", "github-api": "^3.2.2", "hammerjs": "^2.0.8", @@ -80,5 +79,47 @@ "trash": "^4.3.0", "uuid": "^3.3.2", "which": "^1.2.11" + }, + "browserslist": { + "production": [ + "electron 7.0" + ], + "development": [ + "electron 7.0" + ] + }, + "build": { + "appId": "no.mifi.losslesscut", + "files": [ + "build/**/*", + "!node_modules/ffmpeg-static/bin/**/*", + "!node_modules/ffprobe-static/bin/**/*" + ], + "asar": { + "smartUnpack": false + }, + "mac": { + "target": "dmg", + "extraResources": [ + "node_modules/ffmpeg-static/bin/darwin/**", + "node_modules/ffprobe-static/bin/darwin/**" + ], + "icon": "icon-build/app-512.png" + }, + "win": { + "target": "portable", + "extraResources": [ + "node_modules/ffmpeg-static/bin/win32/x64/**", + "node_modules/ffprobe-static/bin/win32/x64/**" + ], + "icon": "icon-build/app-512.png" + }, + "linux": { + "extraResources": [ + "node_modules/ffmpeg-static/bin/linux/x64/**", + "node_modules/ffprobe-static/bin/linux/x64/**" + ], + "icon": "icon-build/app-512.png" + } } } diff --git a/scripts/ffmpeg-dl/dl.sh b/scripts/ffmpeg-dl/dl.sh deleted file mode 100755 index 89cda493..00000000 --- a/scripts/ffmpeg-dl/dl.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env bash -ffmpeg_version=4.2 - -ffmpeg_linux_x64=https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz -ffmpeg_darwin_x64=https://evermeet.cx/ffmpeg/ffmpeg-"${ffmpeg_version}".7z -ffmpeg_win32_ia32=https://ffmpeg.zeranoe.com/builds/win32/static/ffmpeg-"${ffmpeg_version}"-win32-static.zip -ffmpeg_win32_x64=https://ffmpeg.zeranoe.com/builds/win64/static/ffmpeg-"${ffmpeg_version}"-win64-static.zip -ffprobe_darwin_x64=http://evermeet.cx/ffmpeg/ffprobe-"${ffmpeg_version}".7z - -OUT_DIR=ffmpeg-tmp/archives - -if test "$(ls -A "$OUT_DIR" 2>/dev/null)"; then - echo "$OUT_DIR exists, skipping download." - exit -fi - -mkdir -p "$OUT_DIR" && -(cd "$OUT_DIR" && -wget -O ffmpeg_linux_x64.tar.xz "${ffmpeg_linux_x64}" && -wget -O ffmpeg_darwin_x64.7z "${ffmpeg_darwin_x64}" && -wget -O ffmpeg_win32_ia32.zip "${ffmpeg_win32_ia32}" && -wget -O ffmpeg_win32_x64.zip "${ffmpeg_win32_x64}" && -wget -O ffprobe_darwin_x64.7z "${ffprobe_darwin_x64}") diff --git a/scripts/ffmpeg-dl/extract.sh b/scripts/ffmpeg-dl/extract.sh deleted file mode 100755 index 394eeabf..00000000 --- a/scripts/ffmpeg-dl/extract.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env bash -ffmpeg_version=4.2 - -( - mkdir -p ffmpeg-tmp/extracted && - cd ffmpeg-tmp/extracted && - (mkdir -p linux_x64 && cd linux_x64 && - 7z x ../../archives/ffmpeg_linux_x64.tar.xz && tar xvfp ffmpeg_linux_x64.tar) && - (mkdir -p win32_ia32 && cd win32_ia32 && - unzip ../../archives/ffmpeg_win32_ia32.zip) && - (mkdir -p win32_x64 && cd win32_x64 && - unzip ../../archives/ffmpeg_win32_x64.zip) && - (mkdir -p darwin_x64 && cd darwin_x64 && - 7z x ../../archives/ffmpeg_darwin_x64.7z && - 7z x ../../archives/ffprobe_darwin_x64.7z) -) && -cd ffmpeg-tmp && -mkdir -p binaries/linux_x64 && -mkdir -p binaries/win32_ia32 && -mkdir -p binaries/win32_x64 && -mkdir -p binaries/darwin_x64 && -ls -R extracted && -mv extracted/linux_x64/ffmpeg-"${ffmpeg_version}"-amd64-static/ffmpeg binaries/linux_x64 && -mv extracted/linux_x64/ffmpeg-"${ffmpeg_version}"-amd64-static/ffprobe binaries/linux_x64 && -mv extracted/win32_ia32/ffmpeg-"${ffmpeg_version}"-win32-static/bin/ffmpeg.exe binaries/win32_ia32 && -mv extracted/win32_ia32/ffmpeg-"${ffmpeg_version}"-win32-static/bin/ffprobe.exe binaries/win32_ia32 && -mv extracted/win32_x64/ffmpeg-"${ffmpeg_version}"-win64-static/bin/ffmpeg.exe binaries/win32_x64 && -mv extracted/win32_x64/ffmpeg-"${ffmpeg_version}"-win64-static/bin/ffprobe.exe binaries/win32_x64 && -mv extracted/darwin_x64/ffmpeg binaries/darwin_x64 && -mv extracted/darwin_x64/ffprobe binaries/darwin_x64 && -echo Done diff --git a/src/ffmpeg.js b/src/ffmpeg.js index 070cc1d2..e701281d 100644 --- a/src/ffmpeg.js +++ b/src/ffmpeg.js @@ -1,6 +1,5 @@ const execa = require('execa'); const bluebird = require('bluebird'); -const which = bluebird.promisify(require('which')); const path = require('path'); const fileType = require('file-type'); const readChunk = require('read-chunk'); @@ -10,35 +9,36 @@ const readline = require('readline'); const moment = require('moment'); const stringToStream = require('string-to-stream'); const trash = require('trash'); +const isDev = require('electron-is-dev'); +const os = require('os'); const { formatDuration, getOutPath, transferTimestamps } = require('./util'); -function getWithExt(name) { - return process.platform === 'win32' ? `${name}.exe` : name; -} +function getPath(type) { + const platform = os.platform(); -function canExecuteFfmpeg(ffmpegPath) { - return execa(ffmpegPath, ['-version']); -} + const map = { + darwin: `darwin/x64/${type}`, + win32: `win32/x64/${type}.exe`, + linux: `linux/x64/${type}`, + }; -function getFfmpegPath() { - const internalFfmpeg = path.join(__dirname, '..', 'app.asar.unpacked', 'ffmpeg', getWithExt('ffmpeg')); - return canExecuteFfmpeg(internalFfmpeg) - .then(() => internalFfmpeg) - .catch(() => { - console.log('Internal ffmpeg unavail'); - return which('ffmpeg'); - }); + const subPath = map[platform]; + + if (!subPath) throw new Error(`Unsupported platform ${platform}`); + + return isDev + ? `node_modules/${type}-static/bin/${subPath}` + : path.join(window.process.resourcesPath, `node_modules/${type}-static/bin/${subPath}`); } async function runFfprobe(args) { - const ffmpegPath = await getFfmpegPath(); - const ffprobePath = path.join(path.dirname(ffmpegPath), getWithExt('ffprobe')); + const ffprobePath = await getPath('ffprobe'); return execa(ffprobePath, args); } async function runFfmpeg(args) { - const ffmpegPath = await getFfmpegPath(); + const ffmpegPath = await getPath('ffmpeg'); return execa(ffmpegPath, args); } @@ -109,7 +109,7 @@ async function cut({ onProgress(0); - const ffmpegPath = await getFfmpegPath(); + const ffmpegPath = await getPath('ffmpeg'); const process = execa(ffmpegPath, ffmpegArgs); handleProgress(process, cutDuration, onProgress); const result = await process; @@ -232,7 +232,7 @@ async function mergeFiles(paths, outPath) { console.log(concatTxt); - const ffmpegPath = await getFfmpegPath(); + const ffmpegPath = await getPath('ffmpeg'); const process = execa(ffmpegPath, ffmpegArgs); stringToStream(concatTxt).pipe(process.stdin); @@ -382,7 +382,7 @@ async function renderFrame(timestamp, filePath, rotation) { ]; // console.time('ffmpeg'); - const ffmpegPath = await getFfmpegPath(); + const ffmpegPath = await getPath('ffmpeg'); // console.timeEnd('ffmpeg'); console.log('ffmpeg', args); const { stdout } = await execa(ffmpegPath, args, { encoding: null }); diff --git a/src/index.html b/src/index.html index 8f6859ff..15bdd534 100644 --- a/src/index.html +++ b/src/index.html @@ -10,8 +10,6 @@
- +