1
0
mirror of https://github.com/mifi/lossless-cut.git synced 2024-11-25 11:43:17 +01:00

Allow turning off keyframe display #259

This commit is contained in:
Mikael Finstad 2020-02-27 23:26:08 +08:00
parent 9e7a4e317f
commit 8d08fc5237
4 changed files with 24 additions and 11 deletions

View File

@ -174,7 +174,7 @@ const Timeline = memo(({
/>
))}
{mainVideoStream && shouldShowKeyframes && neighbouringFrames.filter(f => f.keyframe).map((f) => (
{shouldShowKeyframes && neighbouringFrames.filter(f => f.keyframe).map((f) => (
<div key={f.time} style={{ position: 'absolute', top: 0, bottom: 0, left: `${(f.time / duration) * 100}%`, marginLeft: -1, width: 1, background: 'rgba(0,0,0,1)', pointerEvents: 'none' }} />
))}
</div>

View File

@ -1,10 +1,10 @@
import React, { memo } from 'react';
import { FaHandPointLeft, FaHandPointRight, FaStepBackward, FaStepForward, FaCaretLeft, FaCaretRight, FaPause, FaPlay, FaImages } from 'react-icons/fa';
import { FaHandPointLeft, FaHandPointRight, FaStepBackward, FaStepForward, FaCaretLeft, FaCaretRight, FaPause, FaPlay, FaImages, FaKey } from 'react-icons/fa';
import { GiSoundWaves } from 'react-icons/gi';
// import useTraceUpdate from 'use-trace-update';
import { getSegColors, parseDuration, formatDuration } from './util';
import { primaryColor } from './colors';
import { primaryTextColor } from './colors';
const TimelineControls = memo(({
@ -12,6 +12,7 @@ const TimelineControls = memo(({
setCurrentSegIndex, cutStartTimeManual, setCutStartTimeManual, cutEndTimeManual, setCutEndTimeManual,
duration, jumpCutEnd, jumpCutStart, startTimeOffset, setCutTime, currentApparentCutSeg,
playing, shortStep, playCommand, setTimelineMode, hasAudio, hasVideo, timelineMode,
keyframesEnabled, setKeyframesEnabled,
}) => {
const {
segActiveBgColor: currentSegActiveBgColor,
@ -118,7 +119,7 @@ const TimelineControls = memo(({
{hasAudio && (
<GiSoundWaves
size={24}
style={{ padding: '0 5px', color: timelineMode === 'waveform' ? primaryColor : undefined }}
style={{ padding: '0 5px', color: timelineMode === 'waveform' ? primaryTextColor : undefined }}
role="button"
title="Show waveform"
onClick={() => setTimelineMode('waveform')}
@ -127,12 +128,20 @@ const TimelineControls = memo(({
{hasVideo && (
<FaImages
size={20}
style={{ padding: '0 5px', color: timelineMode === 'thumbnails' ? primaryColor : undefined }}
style={{ padding: '0 5px', color: timelineMode === 'thumbnails' ? primaryTextColor : undefined }}
role="button"
title="Show thumbnails"
onClick={() => setTimelineMode('thumbnails')}
/>
)}
<FaKey
size={16}
style={{ padding: '0 5px', color: keyframesEnabled ? primaryTextColor : undefined }}
role="button"
title="Show keyframes"
onClick={() => setKeyframesEnabled(v => !v)}
/>
</div>
<div style={{ flexGrow: 1 }} />

View File

@ -1,5 +1,6 @@
export const saveColor = 'hsl(158, 100%, 43%)';
export const primaryColor = 'hsl(194, 78%, 47%)';
export const primaryTextColor = 'hsla(194, 100%, 66%, 1)';
export const waveformColor = '#ffffff'; // Must be hex because used by ffmpeg
export const controlsBackground = '#6b6b6b';
export const timelineBackground = '#444';

View File

@ -147,10 +147,11 @@ const App = memo(() => {
const [shortestFlag, setShortestFlag] = useState(false);
const [debouncedWaveformData, setDebouncedWaveformData] = useState();
const [debouncedReadKeyframesData, setDebouncedReadKeyframesData] = useState();
const [waveformEnabled, setWaveformEnabled] = useState(false);
const [thumbnailsEnabled, setThumbnailsEnabled] = useState(false);
const [zoomWindowStartTime, setZoomWindowStartTime] = useState(0);
const [keyframesEnabled, setKeyframesEnabled] = useState(false);
const [waveformEnabled, setWaveformEnabled] = useState(false);
const [thumbnailsEnabled, setThumbnailsEnabled] = useState(false);
const [showSideBar, setShowSideBar] = useState(true);
// Segment related state
@ -176,8 +177,8 @@ const App = memo(() => {
}, 500, [filePath, commandedTime, duration, zoom, waveformEnabled, mainAudioStream]);
const [, cancelReadKeyframeDataDebounce] = useDebounce(() => {
setDebouncedReadKeyframesData({ filePath, commandedTime, duration, zoom, mainVideoStream });
}, 500, [filePath, commandedTime, duration, zoom, mainVideoStream]);
setDebouncedReadKeyframesData({ keyframesEnabled, filePath, commandedTime, duration, zoom, mainVideoStream });
}, 500, [keyframesEnabled, filePath, commandedTime, duration, zoom, mainVideoStream]);
// Preferences
const [captureFormat, setCaptureFormat] = useState(configStore.get('captureFormat'));
@ -681,7 +682,7 @@ const App = memo(() => {
setCutSegments(cutSegmentsNew);
}, [currentSegIndexSafe, cutSegments, setCutSegments]);
const shouldShowKeyframes = calcShouldShowKeyframes(duration, zoom);
const shouldShowKeyframes = keyframesEnabled && !!mainVideoStream && calcShouldShowKeyframes(duration, zoom);
const thumnailsRef = useRef([]);
const thumnailsRenderingPromiseRef = useRef();
@ -722,7 +723,7 @@ const App = memo(() => {
useEffect(() => {
async function run() {
const d = debouncedReadKeyframesData;
if (!d || !d.filePath || !d.mainVideoStream || d.commandedTime == null || !calcShouldShowKeyframes(d.duration, d.zoom) || readingKeyframesPromise.current) return;
if (!d || !d.keyframesEnabled || !d.filePath || !d.mainVideoStream || d.commandedTime == null || !calcShouldShowKeyframes(d.duration, d.zoom) || readingKeyframesPromise.current) return;
try {
const promise = ffmpeg.readFrames({ filePath: d.filePath, aroundTime: d.commandedTime, stream: d.mainVideoStream.index, window: ffmpegExtractWindow });
@ -1650,6 +1651,8 @@ const App = memo(() => {
timelineMode={timelineMode}
hasAudio={hasAudio}
hasVideo={hasVideo}
keyframesEnabled={keyframesEnabled}
setKeyframesEnabled={setKeyframesEnabled}
/>
<div style={{ display: 'flex', justifyContent: 'space-between' }}>