|
|
|
|
@ -8,6 +8,7 @@ import { useDebounce } from 'use-debounce';
|
|
|
|
|
import i18n from 'i18next';
|
|
|
|
|
import { useTranslation } from 'react-i18next';
|
|
|
|
|
import { produce } from 'immer';
|
|
|
|
|
import screenfull from 'screenfull';
|
|
|
|
|
|
|
|
|
|
import fromPairs from 'lodash/fromPairs';
|
|
|
|
|
import sortBy from 'lodash/sortBy';
|
|
|
|
|
@ -1909,6 +1910,21 @@ const App = memo(() => {
|
|
|
|
|
}
|
|
|
|
|
}, [addStreamSourceFile]);
|
|
|
|
|
|
|
|
|
|
const toggleFullscreenVideo = useCallback(async () => {
|
|
|
|
|
if (!screenfull.isEnabled) {
|
|
|
|
|
console.warn('Fullscreen not allowed');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
try {
|
|
|
|
|
if (videoRef.current == null) {
|
|
|
|
|
console.warn('No video tag to full screen');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
await screenfull.toggle(videoRef.current, { navigationUI: 'hide' });
|
|
|
|
|
} catch (err) {
|
|
|
|
|
console.error('Failed to toggle fullscreen', err);
|
|
|
|
|
}
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
const mainActions = useMemo(() => {
|
|
|
|
|
async function exportYouTube() {
|
|
|
|
|
@ -2039,8 +2055,9 @@ const App = memo(() => {
|
|
|
|
|
toggleShowThumbnails,
|
|
|
|
|
toggleShowKeyframes,
|
|
|
|
|
showIncludeExternalStreamsDialog,
|
|
|
|
|
toggleFullscreenVideo,
|
|
|
|
|
};
|
|
|
|
|
}, [addSegment, alignSegmentTimesToKeyframes, apparentCutSegments, askStartTimeOffset, batchFileJump, batchOpenSelectedFile, captureSnapshot, captureSnapshotAsCoverArt, changePlaybackRate, checkFileOpened, cleanupFilesDialog, clearSegments, closeBatch, closeFileWithConfirm, combineOverlappingSegments, combineSelectedSegments, concatBatch, convertFormatBatch, copySegmentsToClipboard, createFixedDurationSegments, createNumSegments, createRandomSegments, createSegmentsFromKeyframes, currentSegIndexSafe, cutSegmentsHistory, deselectAllSegments, detectBlackScenes, detectSceneChanges, detectSilentScenes, duplicateCurrentSegment, extractAllStreams, extractCurrentSegmentFramesAsImages, extractSelectedSegmentsFramesAsImages, fillSegmentsGaps, goToTimecode, handleShowStreamsSelectorClick, increaseRotation, invertAllSegments, invertSelectedSegments, jumpCutEnd, jumpCutStart, jumpSeg, jumpTimelineEnd, jumpTimelineStart, keyboardNormalSeekSpeed, keyboardSeekAccFactor, onExportPress, onLabelSegment, openFilesDialog, openSendReportDialogWithState, pause, play, removeCutSegment, removeSelectedSegments, reorderSegsByStartTime, seekClosestKeyframe, seekRel, seekRelPercent, selectAllSegments, selectOnlyCurrentSegment, setCutEnd, setCutStart, setPlaybackVolume, shiftAllSegmentTimes, shortStep, showIncludeExternalStreamsDialog, shuffleSegments, splitCurrentSegment, timelineToggleComfortZoom, toggleCaptureFormat, toggleCurrentSegmentSelected, toggleKeyboardShortcuts, toggleKeyframeCut, toggleLastCommands, toggleLoopSelectedSegments, togglePlay, toggleSegmentsList, toggleSettings, toggleShowKeyframes, toggleShowThumbnails, toggleStreamsSelector, toggleStripAudio, toggleWaveformMode, tryFixInvalidDuration, userHtml5ifyCurrentFile, zoomRel]);
|
|
|
|
|
}, [addSegment, alignSegmentTimesToKeyframes, apparentCutSegments, askStartTimeOffset, batchFileJump, batchOpenSelectedFile, captureSnapshot, captureSnapshotAsCoverArt, changePlaybackRate, checkFileOpened, cleanupFilesDialog, clearSegments, closeBatch, closeFileWithConfirm, combineOverlappingSegments, combineSelectedSegments, concatBatch, convertFormatBatch, copySegmentsToClipboard, createFixedDurationSegments, createNumSegments, createRandomSegments, createSegmentsFromKeyframes, currentSegIndexSafe, cutSegmentsHistory, deselectAllSegments, detectBlackScenes, detectSceneChanges, detectSilentScenes, duplicateCurrentSegment, extractAllStreams, extractCurrentSegmentFramesAsImages, extractSelectedSegmentsFramesAsImages, fillSegmentsGaps, goToTimecode, handleShowStreamsSelectorClick, increaseRotation, invertAllSegments, invertSelectedSegments, jumpCutEnd, jumpCutStart, jumpSeg, jumpTimelineEnd, jumpTimelineStart, keyboardNormalSeekSpeed, keyboardSeekAccFactor, onExportPress, onLabelSegment, openFilesDialog, openSendReportDialogWithState, pause, play, removeCutSegment, removeSelectedSegments, reorderSegsByStartTime, seekClosestKeyframe, seekRel, seekRelPercent, selectAllSegments, selectOnlyCurrentSegment, setCutEnd, setCutStart, setPlaybackVolume, shiftAllSegmentTimes, shortStep, showIncludeExternalStreamsDialog, shuffleSegments, splitCurrentSegment, timelineToggleComfortZoom, toggleCaptureFormat, toggleCurrentSegmentSelected, toggleFullscreenVideo, toggleKeyboardShortcuts, toggleKeyframeCut, toggleLastCommands, toggleLoopSelectedSegments, togglePlay, toggleSegmentsList, toggleSettings, toggleShowKeyframes, toggleShowThumbnails, toggleStreamsSelector, toggleStripAudio, toggleWaveformMode, tryFixInvalidDuration, userHtml5ifyCurrentFile, zoomRel]);
|
|
|
|
|
|
|
|
|
|
const getKeyboardAction = useCallback((action) => mainActions[action], [mainActions]);
|
|
|
|
|
|
|
|
|
|
@ -2342,6 +2359,7 @@ const App = memo(() => {
|
|
|
|
|
<div className="no-user-select" style={{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, visibility: !isFileOpened || !hasVideo || bigWaveformEnabled ? 'hidden' : undefined }} onWheel={onTimelineWheel}>
|
|
|
|
|
{/* eslint-disable-next-line jsx-a11y/media-has-caption */}
|
|
|
|
|
<video
|
|
|
|
|
className="main-player"
|
|
|
|
|
muted={playbackVolume === 0}
|
|
|
|
|
ref={videoRef}
|
|
|
|
|
style={videoStyle}
|
|
|
|
|
@ -2352,6 +2370,7 @@ const App = memo(() => {
|
|
|
|
|
onDurationChange={onDurationChange}
|
|
|
|
|
onTimeUpdate={onTimeUpdate}
|
|
|
|
|
onError={onVideoError}
|
|
|
|
|
onDoubleClick={toggleFullscreenVideo}
|
|
|
|
|
>
|
|
|
|
|
{renderSubtitles()}
|
|
|
|
|
</video>
|
|
|
|
|
|