Achieve truly lossless video cuts without losing a single frame!
Have you ever tried to cut a video "losslessly" using popular tools like mkvmerge or stream-copying with FFmpeg, only to find that your cuts aren't exactly where you placed them? You might notice:
- Lost Frames at the Start: Your video segment begins after your intended start point, skipping valuable frames.
- Inaccurate End Points: While less common, the end point might also shift, slightly altering your desired duration.
- Keyframe Limitations: Traditional "lossless" methods are forced to cut only at keyframes (I-frames). If your desired cut point falls between keyframes, the tool must jump to the next available keyframe to avoid corrupting the video stream. This is why you lose frames!
- Complex Proxy Workflows: If you edit with proxy videos for performance, manually aligning cuts for your high-resolution source can be a nightmare.
- Open GOP Codec Challenges: Modern codecs like x265 (HEVC) use "Open GOP" structures, which can lead to visual corruption at cut-in points if not handled perfectly, often requiring you to cut even further back.
This leads to frustrating workarounds, re-editing, or compromising on precision – a major headache for anyone serious about video editing.
ExactCut Video Tools offers a groundbreaking solution that bypasses these limitations. By intelligently combining the power of VirtualDub2, Python scripting, FFmpeg, and LosslessCut, this suite of tools allows you to:
- Define Cuts Exactly Where You Want Them: Place your cut points precisely in VirtualDub2, even on proxy videos.
- Automate Keyframe Alignment: Our Python script (
vdscript_range_adjuster.py
) analyzes detailed frame data from FFmpeg to automatically adjust your cut ranges to "legal frame boundaries" (I-frames and P-frames). - Ensure No Frames Are Lost: The script meticulously ensures that your output segments retain every single desired frame, providing truly lossless cuts at both the start and end of each segment.
- Streamlined Proxy Workflow: Cut effortlessly on low-resolution proxies, and the script handles the precise alignment for your high-resolution source footage automatically.
- Handle Complex Codecs: Specifically designed to manage issues with "Open GOP" codecs (like x265) by offering intelligent adjustment options that prevent corruption in your chosen parts. NOTE: The cut-in points will be corrupted, but your chosen parts will not. To achieve this, you must set "i_frame_offset" to "2" in
vdscript_range_adjuster.py
.
With ExactCut Video Tools, the tedious and error-prone process of manual keyframe alignment is a thing of the past. You gain full control and peace of mind that your video edits are pixel-perfect and truly lossless.
- Zero Frame Loss: Guarantees no frames are lost at the beginning or end of your cut segments.
- Frame-Accurate Cuts: Precisely aligns cut points to the nearest "legal frame boundaries" (I-frames and specific P-frames) using FFmpeg frame logs.
- Automated Adjustment: Eliminates the need for manual keyframe hunting and adjustment.
- Proxy Editing Ready: Define cuts on your lightweight proxy videos; the script translates and adjusts for your full-resolution source.
- Open GOP Codec Support: Smart adjustments (e.g., opting for the "2nd previous I-frame") to prevent corruption (of the chosen parts) with x265 and similar codecs.
- VirtualDub2 Integration: Designed to work seamlessly with cutlists generated by this powerful editor.
- Accurate Output: Generate adjusted VirtualDub2 scripts & convert them to ExactCut FFmpeg Cutter cutlists.
- Batch Processing: Process multiple video cutlists efficiently.
Before you begin, ensure you have the following installed:
- Python: Version 3.13.2 or newer (tested with this version, others may work).
- **LosslessCut: 3.64.0 or newer (for merging the parts & access to FFmpeg).
- VirtualDub2: For creating your initial cutlists.
- HandBrake: For proxy video creation.
Works with constant frame rate only! iPhones and Android devices often utilize variable frame rates (VFR) for video recording. Unfortunately, those videos are NOT compatible with this workflow!
FFmpeg must be in your system's path! This is explained in "\ExactCut-Video-Tools\docs\FFMPEG_NOOB_GUIDE.md".
Not every video format is supported! But so far, i've had no problems cutting MP4/MKV with VP9/x264/x265 video codecs (for x265, set "i_frame_offset" to "2" in vdscript_range_adjuster.py
).
ExactCut Video Tools streamlines your workflow into 9 steps:
Step 1: Prepare Your Videos for Frame Accuracy Make sure your videos are MKV or MP4 for optimal frame accuracy. If they are not, remux them to one of those formats. LosslessCut can do this (Export options > Output container format:). This step is crucial for consistent frame indexing across the workflow.
Step 2: Organize Source Videos
- Put all your source videos into separate folders according to their frame rates (e.g.,
23.976
,25
, etc.). This helpsvdscript_info.py
&vdscript_to_timecode_cutlist_generator.py
to process them correctly. I recommend getting the frame rate from LosslessCut (advanced view), or HandBrake. DO NOT use MediaInfo for this task (it sometimes reports e.g., 59.94 fps as 60 fps).
Step 3: Create Proxy Videos (Optional)
- Create lower-resolution proxy versions of your videos using HandBrake. Use one of the custom presets provided with ExactCut Video Tools.
- Customization Tips:
- You may want to raise the "Constant Quality" values; the provided presets are set at "RF 16" (high quality). "RF 22" or higher will be good enough for most proxy uses.
- You may also want to lower the "Resolution Limit" (e.g., from the default "720p HD").
- Important: All filters are turned off in the presets. If your source video is interlaced, you will need to enable deinterlacing in HandBrake!
- Crucial: DO NOT save proxy videos to the same folder as your input source files!
Step 4: Prepare the Core Scripts
- Go to the
scripts
folder, openframe_log_extractor.bat
in a text editor and specify the full path toffmpeg.exe
within the script. Save and replace the original with this modified version. - Now, copy the contents of the
scripts
folder into your "source videos" folder. Then, copyexactcut_ffmpeg_cutter.pyw
to any location you like, e.g., "C:\PortableApps\PythonScripts".
Step 5: Generate Frame Logs
- Run
frame_log_extractor.bat
. - Be patient: This process will take a significant amount of time as it processes every video file it finds in the folder.
- Internal FFmpeg Command: The
.bat
file uses the following FFmpeg command internally to extract the necessary frame data:ffmpeg -i "your_video_file.mp4" -vf showinfo -f null - 2>&1 | findstr /i "n:" > "your_video_file.mp4_frame_log.txt"
- Each generated frame log file will have the same name as its corresponding video (including extension), with
_frame_log.txt
appended (e.g.,my_video.mp4_frame_log.txt
). These logs contain the essential frame type (I, P, B) and frame number information required for precise adjustments.
Step 6: Edit Your Proxy Videos in VirtualDub2
- Open a proxy video (or the original MKV/MP4 if you skipped proxy creation) with VirtualDub2. You can use either the 32-bit or 64-bit version; the output vdscript is identical. (For performance, the 64-bit version is generally recommended).
- Efficient Editing Tips:
- Scan at high speed using
SHIFT + LEFT
andSHIFT + RIGHT
. - Go even faster by using
ALT + LEFT
andPGDN
. - Use the
HOME
andEND
keys to mark your start and end points for each selection you want to delete. NOTE: VirtualDub2 is endpoint exclusive — meaning that the frame you end the selection on is NOT included in the selection!.
- Scan at high speed using
- Save Your Cutlist: Once your editing is complete, go to
File > Save processing settings...
(CTRL + S
). - Crucial: MAKE SURE to check "Include selection and edit list" in the save dialog. Otherwise, your cuts will NOT be saved! VirtualDub2 should remember this setting for future sessions.
- Naming Convention: The vdscript must be saved with the format
source_video_filename.extension.vdscript
. So, if your source video is calledwhatever.mp4
, your final saved vdscript should be calledwhatever.mp4.vdscript
.
Step 7: Run run_python_scripts.bat
-
This batch file performs the following operations:
-
Runs
vdscript_range_adjuster.py
-
The script will automatically process every vdscript file in the directory (provided it has a corresponding frame log file).
-
The outputted files will have
_adjusted.vdscript
appended (e.g.,whatever.mp4_adjusted.vdscript
). These adjusted scripts now contain the precise frame ranges aligned to legal frame boundaries. -
Runs
vdscript_info.py
-
This tool provides you with a detailed "before & after" comparison of your cut ranges.
-
It processes all vdscript files in the containing folder, & the output files will have '_info.txt' suffix. Then, just use Notepad++ or a diff checking app to inspect the differences between your original + "adjusted" vdscript files.
-
Runs
gop_analyzer.py
-
Creates a file called
gop_info.txt
. If the smallest starting GOP in all vdscripts is "2" or more, you're good to go. If not, you may lose frames (unless you set "Start Frame Offset" to "0" in ExactCut FFmpeg Cutter). Read the instructions in the script for more info (only for perfectionists). -
Runs
exactcut_vfr_detector.pyw
-
Creates a file called
VFR_info.txt
. It informs you about "variable frame rate" in any of your source videos. If any of your videos are VFR, they are not suitable for this workflow! -
Runs
vdscript_to_timecode_cutlist_generator.py
-
Creates the cutlists necessary for ExactCut FFmpeg Cutter to do its job.
Step 8: ExactCut FFmpeg Cutter
- Start
exactcut_ffmpeg_cutter.pyw
, & browse for your "source videos" folder. - Click the "Start Cutting" button. All the parts will be saved to subfolders (same names as source videos).
Step 9: Merge
- Open LosslessCut, go to Tools > Merge/concatenate files, browse for desired folder, select all the parts, then merge. Enable "Check compatibility" to check file compatibility before merging. Repeat this process until all the parts in each subfolder have been merged - & that's it - FINITO!
VERY IMPORTANT! - Do NOT get your original videos & proxy videos mixed up! Always ensure your proxy video matches the frame count of its corresponding source video for accurate results.
To verify a match:
- Open your
whatevervideo_frame_log.txt
file (e.g.,my_video.mp4_frame_log.txt
). - Go to the second-to-last line (the last line of actual frame data). Somewhere in this line, it will say, e.g.,
n:58357
. This is the index of the last actual frame in your video stream. - Now, open your proxy video in VirtualDub2, and hit the
[End]
key. This will bring you to the last frame of the video. - The display at the bottom of VirtualDub2 should say, e.g.,
Frame 58358
. This is the total number of frames in your proxy video. - This total frame count in VirtualDub2 SHOULD be
+1
compared to that last frame index reported in the frame log (n:58357
vsFrame 58358
), because in VirtualDub2, the last displayed frame is always an "empty" frame. - DO NOT directly compare the proxy video's frame count with the actual source video file's frame count itself (e.g., using
MediaInfo
). The frame counts might often match, but NOT ALWAYS! The critical thing (in terms of frame accuracy for this workflow) is that your FFmpeg-generated frame logs and your proxy videos (as displayed in VirtualDub2) match perfectly.
The vdscript_range_adjuster.py
script offers several configurable parameters at the bottom of the file to fine-tune its behavior:
directory
: Specify the working directory (defaults to the script's location).i_frame_offset
: Control how many I-frames to go back for start points (useful for open GOP codecs like x265).merge_ranges_option
: Enable/disable merging of overlapping or very close ranges.min_gap_between_ranges
: Define the minimum frame gap for merging ranges.short_cut_mode
: Adjusts endpoint behavior (True for shorter segments, False for full GOPs).