simplify html5ify

fix html5ify progress on batch
pull/982/head
Mikael Finstad 5 years ago
parent c7bfcd63d4
commit 8795532430
No known key found for this signature in database
GPG Key ID: 25AB36E3E81CBC26

@ -59,7 +59,7 @@ import {
checkDirWriteAccess, dirExists, openDirToast, isMasBuild, isStoreBuild, dragPreventer, doesPlayerSupportFile,
isDurationValid, isWindows, filenamify, getOutFileExtension, generateSegFileName, defaultOutSegTemplate,
hasDuplicates, havePermissionToReadFile, isMac, resolvePathIfNeeded, pathExists, html5ifiedPrefix, html5dummySuffix, findExistingHtml5FriendlyFile,
deleteFiles, getHtml5ifiedPath, isStreamThumbnail, getAudioStreams, getVideoStreams, isOutOfSpaceError, shuffleArray,
deleteFiles, isStreamThumbnail, getAudioStreams, getVideoStreams, isOutOfSpaceError, shuffleArray,
} from './util';
import { formatDuration } from './util/duration';
import { adjustRate } from './util/rate-calculator';
@ -198,7 +198,7 @@ const App = memo(() => {
} = useUserPreferences();
const {
mergeFiles: ffmpegMergeFiles, html5ifyDummy, cutMultiple, autoMergeSegments, html5ify: ffmpegHtml5ify, fixInvalidDuration,
mergeFiles: ffmpegMergeFiles, html5ifyDummy, cutMultiple, autoMergeSegments, html5ify, fixInvalidDuration,
} = useFfmpegOperations({ filePath, enableTransferTimestamps });
const outSegTemplateOrDefault = outSegTemplate || defaultOutSegTemplate;
@ -887,31 +887,6 @@ const App = memo(() => {
if (!hideAllNotifications) toast.fire({ icon: 'info', text: i18n.t('Loaded existing preview file: {{ fileName }}', { fileName }) });
}, [hideAllNotifications]);
const html5ify = useCallback(async ({ customOutDir: cod, filePath: fp, speed, hasAudio: ha, hasVideo: hv }) => {
const path = getHtml5ifiedPath(cod, fp, speed);
let audio;
if (ha) {
if (speed === 'slowest') audio = 'hq';
else if (['slow-audio', 'fast-audio', 'fastest-audio'].includes(speed)) audio = 'lq';
else if (['fast-audio-remux', 'fastest-audio-remux'].includes(speed)) audio = 'copy';
}
let video;
if (hv) {
if (speed === 'slowest') video = 'hq';
else if (['slow-audio', 'slow'].includes(speed)) video = 'lq';
else video = 'copy';
}
try {
await ffmpegHtml5ify({ filePath: fp, outPath: path, video, audio, onProgress: setCutProgress });
} finally {
setCutProgress();
}
return path;
}, [ffmpegHtml5ify]);
const html5ifyAndLoad = useCallback(async (cod, fp, speed, hv, ha) => {
const usesDummyVideo = ['fastest-audio', 'fastest-audio-remux', 'fastest'].includes(speed);
console.log('html5ifyAndLoad', { speed, hasVideo: hv, hasAudio: ha, usesDummyVideo });
@ -929,9 +904,12 @@ const App = memo(() => {
return path;
}
const shouldIncludeVideo = !usesDummyVideo && hv;
const path = await html5ify({ customOutDir: cod, filePath: fp, speed, hasAudio: ha, hasVideo: shouldIncludeVideo });
return path;
try {
const shouldIncludeVideo = !usesDummyVideo && hv;
return await html5ify({ customOutDir: cod, filePath: fp, speed, hasAudio: ha, hasVideo: shouldIncludeVideo, onProgress: setCutProgress });
} finally {
setCutProgress();
}
}
const path = await doHtml5ify();
@ -1069,7 +1047,7 @@ const App = memo(() => {
const nameSanitized = filenamifyOrNot(name);
const generated = generateSegFileName({ template, segSuffix, inputFileNameWithoutExt: fileNameWithoutExt, ext, segNum, segLabel: nameSanitized, cutFrom: cutFromStr, cutTo: cutToStr, tags: tagsSanitized });
return safeOutputFileName ? generated.substr(0, 200) : generated; // If sanitation is enabled, make sure filename is not too long
return safeOutputFileName ? generated.substring(0, 200) : generated; // If sanitation is enabled, make sure filename is not too long
})
), [segmentsToExport, filenamifyOrNot, isCustomFormatSelected, fileFormat, filePath, safeOutputFileName]);
@ -1928,6 +1906,7 @@ const App = memo(() => {
const failedFiles = [];
let i = 0;
const setTotalProgress = (fileProgress = 0) => setCutProgress((i + fileProgress) / filePaths.length);
const { selectedOption: speed } = await askForHtml5ifySpeed({ allowedOptions: ['fastest-audio', 'fastest-audio-remux', 'fast-audio-remux', 'fast-audio', 'fast', 'slow', 'slow-audio', 'slowest'] });
if (!speed) return;
@ -1948,14 +1927,14 @@ const App = memo(() => {
}
// eslint-disable-next-line no-await-in-loop
await html5ify({ customOutDir: newCustomOutDir, filePath: path, speed, hasAudio: true, hasVideo: true });
await html5ify({ customOutDir: newCustomOutDir, filePath: path, speed, hasAudio: true, hasVideo: true, onProgress: setTotalProgress });
} catch (err2) {
console.error('Failed to html5ify', path, err2);
failedFiles.push(path);
}
i += 1;
setCutProgress(i / filePaths.length);
setTotalProgress();
}
if (failedFiles.length > 0) toast.fire({ title: `${i18n.t('Failed to convert files:')} ${failedFiles.join(' ')}`, timer: null, showConfirmButton: true });
@ -2050,7 +2029,7 @@ const App = memo(() => {
electron.ipcRenderer.removeListener('fixInvalidDuration', fixInvalidDuration2);
electron.ipcRenderer.removeListener('reorderSegsByStartTime', reorderSegsByStartTime);
};
}, [outputDir, filePath, customOutDir, startTimeOffset, userHtml5ifyCurrentFile, batchLoadPaths, extractAllStreams, userOpenFiles, openSendReportDialogWithState, setWorking, loadEdlFile, cutSegments, apparentCutSegments, edlFilePath, toggleHelp, toggleSettings, ensureOutDirAccessible, html5ifyAndLoad, html5ify, loadCutSegments, duration, checkFileOpened, loadMedia, fileFormat, reorderSegsByStartTime, closeFileWithConfirm, closeBatch, clearSegments, clearSegCounter, fixInvalidDuration, invertAllCutSegments, getFrameCount, getTimeFromFrameNum, shuffleSegments]);
}, [outputDir, filePath, customOutDir, startTimeOffset, userHtml5ifyCurrentFile, batchLoadPaths, extractAllStreams, userOpenFiles, openSendReportDialogWithState, setWorking, loadEdlFile, cutSegments, apparentCutSegments, edlFilePath, toggleHelp, toggleSettings, ensureOutDirAccessible, html5ifyAndLoad, loadCutSegments, duration, checkFileOpened, loadMedia, fileFormat, reorderSegsByStartTime, closeFileWithConfirm, closeBatch, clearSegments, clearSegCounter, fixInvalidDuration, invertAllCutSegments, getFrameCount, getTimeFromFrameNum, shuffleSegments, html5ify]);
const showAddStreamSourceDialog = useCallback(async () => {
try {

@ -53,6 +53,7 @@ export function runFfmpeg(args) {
export function handleProgress(process, cutDuration, onProgress) {
if (!onProgress) return;
onProgress(0);
const rl = readline.createInterface({ input: process.stderr });

@ -4,7 +4,7 @@ import flatMapDeep from 'lodash/flatMapDeep';
import sum from 'lodash/sum';
import pMap from 'p-map';
import { getOutPath, transferTimestamps, getOutFileExtension, getOutDir, isMac, deleteDispositionValue } from '../util';
import { getOutPath, transferTimestamps, getOutFileExtension, getOutDir, isMac, deleteDispositionValue, getHtml5ifiedPath } from '../util';
import { isCuttingStart, isCuttingEnd, handleProgress, getFfCommandLine, getFfmpegPath, getDuration, runFfmpeg, createChaptersFromSegments } from '../ffmpeg';
const execa = window.require('execa');
@ -354,8 +354,24 @@ function useFfmpegOperations({ filePath, enableTransferTimestamps }) {
if (autoDeleteMergedSegments) await pMap(segmentPaths, path => fs.unlink(path), { concurrency: 5 });
}, [filePath, mergeFiles]);
const html5ify = useCallback(async ({ filePath: specificFilePath, outPath, video, audio, onProgress }) => {
console.log('Making HTML5 friendly version', { specificFilePath, outPath, video, audio });
const html5ify = useCallback(async ({ customOutDir, filePath: filePathArg, speed, hasAudio, hasVideo, onProgress }) => {
const outPath = getHtml5ifiedPath(customOutDir, filePathArg, speed);
let audio;
if (hasAudio) {
if (speed === 'slowest') audio = 'hq';
else if (['slow-audio', 'fast-audio', 'fastest-audio'].includes(speed)) audio = 'lq';
else if (['fast-audio-remux', 'fastest-audio-remux'].includes(speed)) audio = 'copy';
}
let video;
if (hasVideo) {
if (speed === 'slowest') video = 'hq';
else if (['slow-audio', 'slow'].includes(speed)) video = 'lq';
else video = 'copy';
}
console.log('Making HTML5 friendly version', { filePathArg, outPath, video, audio });
let videoArgs;
let audioArgs;
@ -428,29 +444,31 @@ function useFfmpegOperations({ filePath, enableTransferTimestamps }) {
const ffmpegArgs = [
'-hide_banner',
'-i', specificFilePath,
'-i', filePathArg,
...videoArgs,
...audioArgs,
'-sn',
'-y', outPath,
];
const duration = await getDuration(specificFilePath);
const duration = await getDuration(filePathArg);
const process = runFfmpeg(ffmpegArgs);
if (duration) handleProgress(process, duration, onProgress);
const { stdout } = await process;
console.log(stdout);
await optionalTransferTimestamps(specificFilePath, outPath);
await optionalTransferTimestamps(filePathArg, outPath);
return outPath;
}, [optionalTransferTimestamps]);
// This is just used to load something into the player with correct length,
// so user can seek and then we render frames using ffmpeg
const html5ifyDummy = useCallback(async ({ filePath: specificFilePath, outPath, onProgress }) => {
console.log('Making HTML5 friendly dummy', { specificFilePath, outPath });
const html5ifyDummy = useCallback(async ({ filePath: filePathArg, outPath, onProgress }) => {
console.log('Making HTML5 friendly dummy', { filePathArg, outPath });
const duration = await getDuration(specificFilePath);
const duration = await getDuration(filePathArg);
const ffmpegArgs = [
'-hide_banner',
@ -468,7 +486,7 @@ function useFfmpegOperations({ filePath, enableTransferTimestamps }) {
const { stdout } = await process;
console.log(stdout);
await optionalTransferTimestamps(specificFilePath, outPath);
await optionalTransferTimestamps(filePathArg, outPath);
}, [optionalTransferTimestamps]);
// https://stackoverflow.com/questions/34118013/how-to-determine-webm-duration-using-ffprobe

Loading…
Cancel
Save