diff --git a/package.json b/package.json
index 8a1e587351f..bb34bc6add8 100644
--- a/package.json
+++ b/package.json
@@ -82,6 +82,7 @@
     "react-sortablejs": "^6.1.4",
     "react-syntax-highlighter": "^15.4.3",
     "react-use": "^17.4.0",
+    "screenfull": "^6.0.2",
     "scroll-into-view-if-needed": "^2.2.28",
     "sharp": "^0.32.6",
     "smpte-timecode": "^1.2.3",
diff --git a/public/configStore.js b/public/configStore.js
index 8a621da8cc0..48f9056543e 100644
--- a/public/configStore.js
+++ b/public/configStore.js
@@ -65,6 +65,8 @@ const defaultKeyBindings = [
   { keys: 'ctrl+c', action: 'copySegmentsToClipboard' },
   { keys: 'command+c', action: 'copySegmentsToClipboard' },
 
+  { key: 'f', action: 'toggleFullscreenVideo' },
+
   { keys: 'enter', action: 'labelCurrentSegment' },
 
   { keys: 'e', action: 'export' },
diff --git a/src/App.jsx b/src/App.jsx
index 79ade467ef3..4a538966985 100644
--- a/src/App.jsx
+++ b/src/App.jsx
@@ -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>
diff --git a/src/components/KeyboardShortcuts.jsx b/src/components/KeyboardShortcuts.jsx
index d3854d351fa..8da13d273b7 100644
--- a/src/components/KeyboardShortcuts.jsx
+++ b/src/components/KeyboardShortcuts.jsx
@@ -540,6 +540,10 @@ const KeyboardShortcuts = memo(({
           name: t('Show keyframes'),
           category: otherCategory,
         },
+        toggleFullscreenVideo: {
+          name: 'Toggle full screen video',
+          category: otherCategory,
+        },
         toggleSettings: {
           name: t('Settings'),
           category: otherCategory,
diff --git a/src/main.css b/src/main.css
index f71d01b1523..056f40199dd 100644
--- a/src/main.css
+++ b/src/main.css
@@ -83,3 +83,8 @@ code.highlighted {
 .button-unstyled:focus {
   outline: revert;
 }
+
+/* https://stackoverflow.com/questions/18270894/html5-video-does-not-hide-controls-in-fullscreen-mode-in-chrome */
+video.main-player::-webkit-media-controls {
+  display:none !important;
+}
diff --git a/yarn.lock b/yarn.lock
index d60f8d46a2c..5b76412fcf4 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -6622,6 +6622,7 @@ __metadata:
     react-sortablejs: "npm:^6.1.4"
     react-syntax-highlighter: "npm:^15.4.3"
     react-use: "npm:^17.4.0"
+    screenfull: "npm:^6.0.2"
     scroll-into-view-if-needed: "npm:^2.2.28"
     semver: "npm:^7.5.2"
     sharp: "npm:^0.32.6"
@@ -8705,6 +8706,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"screenfull@npm:^6.0.2":
+  version: 6.0.2
+  resolution: "screenfull@npm:6.0.2"
+  checksum: 13ad07683538a94a0dac99533ddf54755c9c10890850f726872a9dace69ad09457451b2e467efcbb270f19f201bbb9b6911ab7b12618222648a093f369be6fd2
+  languageName: node
+  linkType: hard
+
 "scroll-into-view-if-needed@npm:^2.2.28":
   version: 2.2.28
   resolution: "scroll-into-view-if-needed@npm:2.2.28"