use license free codecs for html5ify

pull/713/head
Mikael Finstad 5 years ago
parent 0d5ef77b5d
commit bdb764fc13
No known key found for this signature in database
GPG Key ID: 25AB36E3E81CBC26

@ -52,7 +52,7 @@ import {
getOutPath, toast, errorToast, showFfmpegFail, setFileNameTitle, getOutDir, withBlur, getOutPath, toast, errorToast, showFfmpegFail, setFileNameTitle, getOutDir, withBlur,
checkDirWriteAccess, dirExists, openDirToast, isMasBuild, isStoreBuild, dragPreventer, doesPlayerSupportFile, checkDirWriteAccess, dirExists, openDirToast, isMasBuild, isStoreBuild, dragPreventer, doesPlayerSupportFile,
isDurationValid, isWindows, filenamify, getOutFileExtension, generateSegFileName, defaultOutSegTemplate, isDurationValid, isWindows, filenamify, getOutFileExtension, generateSegFileName, defaultOutSegTemplate,
hasDuplicates, havePermissionToReadFile, hasDuplicates, havePermissionToReadFile, isMac,
} from './util'; } from './util';
import { formatDuration } from './util/duration'; import { formatDuration } from './util/duration';
import { askForOutDir, askForImportChapters, createNumSegments, createFixedDurationSegments, promptTimeOffset, askForHtml5ifySpeed, askForYouTubeInput, askForFileOpenAction, confirmExtractAllStreamsDialog, cleanupFilesDialog, showDiskFull, showCutFailedDialog, labelSegmentDialog, openYouTubeChaptersDialog, showMergeDialog, showOpenAndMergeDialog, openAbout } from './dialogs'; import { askForOutDir, askForImportChapters, createNumSegments, createFixedDurationSegments, promptTimeOffset, askForHtml5ifySpeed, askForYouTubeInput, askForFileOpenAction, confirmExtractAllStreamsDialog, cleanupFilesDialog, showDiskFull, showCutFailedDialog, labelSegmentDialog, openYouTubeChaptersDialog, showMergeDialog, showOpenAndMergeDialog, openAbout } from './dialogs';
@ -1126,7 +1126,8 @@ const App = memo(() => {
}, [playing, canvasPlayerEnabled]); }, [playing, canvasPlayerEnabled]);
const getHtml5ifiedPath = useCallback((cod, fp, type) => { const getHtml5ifiedPath = useCallback((cod, fp, type) => {
const ext = type === 'fastest-audio' ? 'mkv' : 'mp4'; // See also inside ffmpegHtml5ify
const ext = (isMac && ['slowest', 'slow', 'slow-audio'].includes(type)) ? 'mp4' : 'mkv';
return getOutPath(cod, fp, `html5ified-${type}.${ext}`); return getOutPath(cod, fp, `html5ified-${type}.${ext}`);
}, []); }, []);
@ -1569,9 +1570,9 @@ const App = memo(() => {
let audio; let audio;
if (ha) { if (ha) {
if (speed === 'slowest') audio = 'hq'; if (speed === 'slowest') audio = 'hq';
else if (speed === 'slow-audio') audio = 'lq-aac'; else if (speed === 'slow-audio') audio = 'lq';
else if (speed === 'fast-audio') audio = 'copy'; else if (speed === 'fast-audio') audio = 'copy';
else if (speed === 'fastest-audio') audio = 'lq-flac'; else if (speed === 'fastest-audio') audio = 'silent-audio';
} }
let video; let video;
@ -1961,6 +1962,7 @@ const App = memo(() => {
// if (isDev) load({ filePath: '/Users/mifi/Downloads/inp.MOV', customOutDir }); // if (isDev) load({ filePath: '/Users/mifi/Downloads/inp.MOV', customOutDir });
}, []); }, []);
// TODO fastest-audio shows muted
const VolumeIcon = muted || dummyVideoPath ? FaVolumeMute : FaVolumeUp; const VolumeIcon = muted || dummyVideoPath ? FaVolumeMute : FaVolumeUp;
useEffect(() => { useEffect(() => {

@ -5,7 +5,7 @@ import moment from 'moment';
import i18n from 'i18next'; import i18n from 'i18next';
import Timecode from 'smpte-timecode'; import Timecode from 'smpte-timecode';
import { getOutPath, isDurationValid, getExtensionForFormat } from './util'; import { getOutPath, isDurationValid, getExtensionForFormat, isMac, isWindows } from './util';
const execa = window.require('execa'); const execa = window.require('execa');
const { join } = window.require('path'); const { join } = window.require('path');
@ -13,7 +13,6 @@ const fileType = window.require('file-type');
const readChunk = window.require('read-chunk'); const readChunk = window.require('read-chunk');
const readline = window.require('readline'); const readline = window.require('readline');
const isDev = window.require('electron-is-dev'); const isDev = window.require('electron-is-dev');
const os = window.require('os');
export function getFfCommandLine(cmd, args) { export function getFfCommandLine(cmd, args) {
@ -22,13 +21,14 @@ export function getFfCommandLine(cmd, args) {
} }
function getFfPath(cmd) { function getFfPath(cmd) {
const platform = os.platform(); // Testing non-mac setup on mac:
// return `node_modules/ffmpeg-ffprobe-static/${cmd}`;
if (platform === 'darwin') { if (isMac) {
return isDev ? `ffmpeg-mac/${cmd}` : join(window.process.resourcesPath, cmd); return isDev ? `ffmpeg-mac/${cmd}` : join(window.process.resourcesPath, cmd);
} }
const exeName = platform === 'win32' ? `${cmd}.exe` : cmd; const exeName = isWindows ? `${cmd}.exe` : cmd;
return isDev return isDev
? `node_modules/ffmpeg-ffprobe-static/${exeName}` ? `node_modules/ffmpeg-ffprobe-static/${exeName}`
: join(window.process.resourcesPath, `node_modules/ffmpeg-ffprobe-static/${exeName}`); : join(window.process.resourcesPath, `node_modules/ffmpeg-ffprobe-static/${exeName}`);

@ -4,11 +4,10 @@ import flatMapDeep from 'lodash/flatMapDeep';
import sum from 'lodash/sum'; import sum from 'lodash/sum';
import pMap from 'p-map'; import pMap from 'p-map';
import { getOutPath, transferTimestamps, getOutFileExtension, getOutDir } from '../util'; import { getOutPath, transferTimestamps, getOutFileExtension, getOutDir, isMac } from '../util';
import { isCuttingStart, isCuttingEnd, handleProgress, getFfCommandLine, getFfmpegPath, getDuration, runFfmpeg, createChaptersFromSegments } from '../ffmpeg'; import { isCuttingStart, isCuttingEnd, handleProgress, getFfCommandLine, getFfmpegPath, getDuration, runFfmpeg, createChaptersFromSegments } from '../ffmpeg';
const execa = window.require('execa'); const execa = window.require('execa');
const os = window.require('os');
const { join } = window.require('path'); const { join } = window.require('path');
const fs = window.require('fs-extra'); const fs = window.require('fs-extra');
const stringToStream = window.require('string-to-stream'); const stringToStream = window.require('string-to-stream');
@ -268,14 +267,19 @@ function useFfmpegOperations({ filePath, enableTransferTimestamps }) {
let videoArgs; let videoArgs;
let audioArgs; let audioArgs;
const isMac = os.platform() === 'darwin'; // h264/aac_at: No licensing when using HW encoder (Video/Audio Toolbox on Mac)
// https://github.com/mifi/lossless-cut/issues/372#issuecomment-810766512
switch (video) { switch (video) {
case 'hq': { case 'hq': {
if (isMac) { if (isMac) {
videoArgs = ['-vf', 'format=yuv420p', '-allow_sw', '1', '-vcodec', 'h264', '-b:v', '15M']; videoArgs = ['-vf', 'format=yuv420p', '-allow_sw', '1', '-vcodec', 'h264', '-b:v', '15M'];
} else { } else {
videoArgs = ['-vf', 'format=yuv420p', '-vcodec', 'libx264', '-profile:v', 'high', '-preset:v', 'slow', '-crf', '17']; // AV1 is very slow
// videoArgs = ['-vf', 'scale=-2:400,format=yuv420p', '-sws_flags', 'neighbor', '-vcodec', 'libaom-av1', '-crf', '30', '-cpu-used', '8'];
// Theora is a bit faster but not that much
// videoArgs = ['-vf', '-c:v', 'libtheora', '-qscale:v', '1'];
videoArgs = ['-vf', 'format=yuv420p', '-c:v', 'libvpx-vp9', '-crf', '30', '-b:v', '0', '-row-mt', '1'];
} }
break; break;
} }
@ -283,7 +287,7 @@ function useFfmpegOperations({ filePath, enableTransferTimestamps }) {
if (isMac) { if (isMac) {
videoArgs = ['-vf', 'scale=-2:400,format=yuv420p', '-allow_sw', '1', '-sws_flags', 'lanczos', '-vcodec', 'h264', '-b:v', '1500k']; videoArgs = ['-vf', 'scale=-2:400,format=yuv420p', '-allow_sw', '1', '-sws_flags', 'lanczos', '-vcodec', 'h264', '-b:v', '1500k'];
} else { } else {
videoArgs = ['-vf', 'scale=-2:400,format=yuv420p', '-sws_flags', 'neighbor', '-vcodec', 'libx264', '-profile:v', 'baseline', '-x264opts', 'level=3.0', '-preset:v', 'ultrafast', '-crf', '28']; videoArgs = ['-vf', 'scale=-2:400,format=yuv420p', '-sws_flags', 'neighbor', '-c:v', 'libtheora', '-qscale:v', '1'];
} }
break; break;
} }
@ -298,15 +302,23 @@ function useFfmpegOperations({ filePath, enableTransferTimestamps }) {
switch (audio) { switch (audio) {
case 'hq': { case 'hq': {
audioArgs = ['-acodec', 'aac', '-b:a', '192k']; if (isMac) {
audioArgs = ['-acodec', 'aac_at', '-b:a', '192k'];
} else {
audioArgs = ['-acodec', 'flac'];
}
break; break;
} }
case 'lq-flac': { case 'silent-audio': {
audioArgs = ['-acodec', 'flac', '-ar', '11025', '-ac', '2']; audioArgs = ['-acodec', 'flac', '-ar', '11025', '-ac', '2'];
break; break;
} }
case 'lq-aac': { case 'lq': {
audioArgs = ['-acodec', 'aac', '-ar', '44100', '-ac', '2', '-b:a', '96k']; if (isMac) {
audioArgs = ['-acodec', 'aac_at', '-ar', '44100', '-ac', '2', '-b:a', '96k'];
} else {
audioArgs = ['-acodec', 'flac', '-ar', '11025', '-ac', '2'];
}
break; break;
} }
case 'copy': { case 'copy': {

@ -120,6 +120,7 @@ export const isDurationValid = (duration) => Number.isFinite(duration) && durati
const platform = os.platform(); const platform = os.platform();
export const isWindows = platform === 'win32'; export const isWindows = platform === 'win32';
export const isMac = platform === 'darwin';
export function getExtensionForFormat(format) { export function getExtensionForFormat(format) {
const ext = { const ext = {

Loading…
Cancel
Save