πŸ“‹ AdSlicerProXP Help
_
β–‘
βœ•
🏠 Contents
β–Ά Quick Start
βš™ How It Works
πŸ”§ Parameters
πŸŽ› Tuning
πŸ–¨ Print
Contents
Getting Started
Reference
Guides

AdSlicerProXP

Broadcast Archival Commercial Slicer β€” Help Documentation

AdSlicerProXP is a fully automated advertisement detection and removal system built for long-form VHS captures, analog transfers, and TV recordings. It analyzes black slugs between program segments, determines likely commercial blocks, and outputs:

  • A clean show file (ads removed)
  • A folder of isolated commercial clips
  • Full diagnostic logs in JSON, CSV, and EDL
  • ffmeta chapter markers for media player navigation
  • A structured ML dataset (dataset.jsonl) with 74 per-segment feature columns
  • A run manifest recording all parameters and detection statistics

The pipeline is self-contained (ffmpeg bundled), batch-friendly, and designed for noisy analog sources where black slugs vary in length and clarity.

Topics

βœ‚οΈHow It Works β€” Detection pipeline, confidence scoring, export modes
β–ΆQuick Start β€” Get from launch to a clean show master
πŸ”§All Parameters β€” Complete parameter reference
πŸ’ΎPreset System β€” Built-in presets, saving, and file format
πŸŽ›Tuning Guide β€” Fixing false positives, missed breaks, noisy tape
πŸ“ŠML Dataset Output β€” The 74-column dataset.jsonl format
πŸ’‘Use Cases β€” Archiving, batch processing, ML, compilations

Quick Start

1. Choose your input

Select a single video file, or switch to Batch Folder mode and select a directory. All matching video files inside will be queued.

2. Set your output folder

A subfolder is created per input file β€” you'll never lose track of which output came from which tape. Results are never overwritten; re-processing appends _1, _2, etc.

3. Pick a preset

Open the Presets menu and choose the one closest to your source material. See Preset System for descriptions.

4. Dry run first

Enable Dry Run before committing to a full export. This runs the full detection pipeline and writes all logs, but cuts no media. Review detect.json and check dataset.jsonl for cuts where only sig_black_boundary fired and confidence is below 0.90 β€” those are the weakest detections and worth inspecting first.

5. Final export

Disable Dry Run. Enable Re-encode for frame-accurate archival cuts (H.264/AAC). Run.

Recommended workflow:

  1. Enable Dry Run
  2. Review activity log and detect.json
  3. Adjust parameters if needed, re-run dry
  4. Disable Dry Run, enable Re-encode
  5. Run final export
πŸ’‘
We default to -c copy for speed. Stream copy snaps to the nearest keyframe β€” a few frames of error at each boundary. Enable reencode for surgical precision.

Output Structure

<outdir>/ <basename>/ commercials/ <basename>_ad_0001.mp4 <basename>_ad_0002.mp4 ... show/ _parts/ part_0001.mp4 part_0002.mp4 <basename>_show.mp4 logs/ detect.json ← full structured plan detect.csv ← flat interval table detect.edl ← EDL (Kodi, MPC-HC, mkvmerge) chapters.ffmeta ← ffmpeg chapter metadata run_manifest.json ← all parameters + detection counts dataset.jsonl ← ML feature vectors (74 columns) ffmpeg_blackdetect.log ← verbosity β‰₯ 1 ffmpeg_silencedetect.log ← verbosity β‰₯ 1 ffmpeg_uniformdetect.log ← verbosity β‰₯ 2 ffmpeg_scenechange.log ← verbosity β‰₯ 2

Embedding chapter markers

Keep segments become Content N chapters; commercial blocks become Advertisement N. Embed into the show file:

ffmpeg -i show.mp4 -i logs/chapters.ffmeta \
  -map_metadata 1 -c copy show_with_chapters.mp4

Recognized by VLC, mpv, Kodi, and any player that reads ffmpeg metadata.

How It Works

Each commercial candidate passes through four independent detection passes in sequence. Every signal that fires is recorded against the interval and reflected in its confidence score.

Detection Passes

1
Black Frame Detection
Uses ffmpeg blackdetect to locate near-black frames. Segments shorter than blackMinDur are discarded. Segments within mergeGap seconds are merged.
2
Audio Silence Corroboration (Comskip: validate_silence)
Uses ffmpeg silencedetect. Candidates overlapping a silence segment by β‰₯ 0.5 s receive silence_overlap and a +0.05 confidence boost. Set silenceNoiseDb β‰₯ 0 to disable.
3
Uniform Frame Corroboration (Comskip: validate_uniform)
Uses ffmpeg showinfo to compute per-frame luma stddev. Frames with stddev ≀ uniformMaxStddev are classified as uniform slates. Candidates overlapping β‰₯ 0.3 s receive uniform_overlap and +0.04 boost. Set uniformMaxStddev to 0 to disable.
4
Scene Change Rate Scoring (Comskip: validate_scenechange)
Uses ffmpeg select=scene. Blocks exceeding 1.3Γ— the file average scene rate receive high_scene_rate and +0.04 boost. Set sceneThreshold to 0 to disable.

Scoring Guards

GuardParameterComskip equivalent
Uncorroborated penaltyautomaticpunish_modifier
Minimum show segmentminShowSegmentmin_show_segment_length
Edge protectionalwaysKeepFirst / alwaysKeepLastalways_keep_first/last_seconds
30s boundary snappingrequireDiv5require_div5
Asymmetric trimremoveBefore / removeAfterremove_before / remove_after

Confidence Score

Every CutInterval carries a confidence float (0.0–1.0) and a signals list. The activity log renders confidence as a star rating:

ScoreDisplayMeaning
β‰₯ 1.0β˜…β˜…β˜…Multiple corroborating signals
β‰₯ 0.8β˜…β˜…β˜†At least one corroborating signal
< 0.8β˜…β˜†β˜†Black boundary only β€” no corroboration

All Parameters

Input / Output

ParameterTypeDescription
inputModesingleFile | batchDirProcess one file or a whole folder
inputPathpathInput file or folder path
globpatternComma-separated globs for batch mode (e.g. *.mp4,*.mov,*.dv)
outdirpathBase output directory β€” a subfolder is created per input file

Black Frame Detection

ParameterDefaultDescription
blackMinDur0.10 sMinimum black segment duration. Shorter flashes are discarded.
pixTh0.08Pixel luma threshold for blackdetect. Lower = stricter black definition.
picTh0.98Fraction of pixels per frame that must be below pixTh.
mergeGap1.5 sMerge black segments separated by ≀ this gap. Prevents flickering slugs from splitting boundaries.

Cut Behaviour

ParameterDefaultDescription
edgePadPre0.20 sPadding added before each cut boundary.
edgePadPost0.06 sPadding added after each cut boundary.
minCommercial5 sMinimum gap to classify as a commercial break.
maxCommercial240 sMaximum gap to classify as a commercial break.
includeBlackfalseInclude surrounding black frames inside exported commercial clips.
reencodefalseRe-encode output with H.264/AAC for frame-accurate cuts.
dryRunfalseWrite logs only β€” no media files are created.

Advanced Detection (Comskip-derived)

ParameterDefaultComskip equiv.Description
silenceNoiseDb-40 dBmax_silenceAudio noise floor. Set β‰₯ 0 to disable silence detection.
silenceMinDur0.5 smin_silenceMinimum silence duration to register as a segment.
minShowSegment30 smin_show_segment_lengthMinimum keep-segment length. Cuts that would leave shorter keeps are demoted.
alwaysKeepFirst0 salways_keep_first_secondsHard-protect first N seconds from being cut.
alwaysKeepLast0 salways_keep_last_secondsHard-protect last N seconds from being cut.
uniformMaxStddev8.0non_uniformityLuma stddev ceiling for uniform frame detection. Set to 0 to disable.
sceneThreshold0.4schange_thresholdScene change sensitivity. Set to 0 to disable.
removeBefore0 sremove_beforeTrim from the content side of each cut.
removeAfter0 sremove_afterTrim from the ad side of each cut.
requireDiv5falserequire_div5Snap or drop candidates not within 3 s of a 30-second multiple.

Verbosity

ValueOutput
0Errors only
1Milestones + raw blackdetect/silencedetect logs written to logs/
2Full step-by-step + all raw filter logs written to logs/

Preset System

AdSlicerProXP ships with three built-in presets and a full save/load system.

Built-in Presets

FilePurpose
default.jsonBalanced starting point for typical VHS
vhs_noisy.jsonLoose thresholds for degraded/worn tape
broadcast_strict.jsonStrict thresholds with 30s snapping for clean off-air captures

Preset Menu

Presets
  ── BUILT-IN ──────────────
  Broadcast strict
  Default
  VHS noisy
  ── MY PRESETS ────────────
  my_custom_settings
  ──────────────────────────
  Save Current as Preset…
  ──────────────────────────
  Open User Presets Folder…
  Reload Presets

User Preset Locations

PlatformPath
macOS~/Library/Application Support/net.schwwaaa.adslicerproxp/presets/
Windows%APPDATA%\net.schwwaaa.adslicerproxp\presets\
Linux~/.config/net.schwwaaa.adslicerproxp/presets/

Use Presets β†’ Open User Presets Folder… to open this location. Drop any .json file there and use Reload Presets to make it appear in the menu.

Preset File Format

Plain JSON. _preset sets the menu label; _description sets the tooltip. Unrecognized keys are silently ignored.

{
  "_preset": "My custom VHS settings",
  "_description": "Tuned for my specific deck and capture card.",
  "blackMinDur": 0.10,
  "pixTh": 0.08,
  "picTh": 0.98,
  "mergeGap": 1.5,
  "minCommercial": 5,
  "maxCommercial": 240,
  "silenceNoiseDb": -40,
  "requireDiv5": false
}

Adding a Built-in Preset to the Build

Drop a .json file into src-tauri/presets/ and rebuild. The tauri.conf.json resources glob picks it up β€” no code changes needed.

Tuning Guide

Thresholds may require tuning for darker or noisier analog captures. Always Dry Run first and review dataset.jsonl before committing to export.

Too many false positives (content being cut)

  • Raise blackMinDur (0.15–0.25) β€” require longer slugs
  • Raise picTh (0.99) β€” require nearly pure black frames
  • Increase minShowSegment (60–120 s) β€” prevent short content being consumed
  • Enable requireDiv5 for clean broadcast β€” non-multiples of 30 s are not real ad breaks
  • Raise minCommercial β€” filter breaks too short to be real commercials
  • Check dataset.jsonl for cuts where only sig_black_boundary fired β€” weakest detections

Missed commercials (breaks not detected)

  • Lower blackMinDur (0.06–0.08) β€” accept shorter slugs
  • Raise pixTh (0.10–0.14) β€” more permissive black definition
  • Lower picTh (0.90–0.95) β€” allow noisier black frames
  • Increase mergeGap for flickering VHS slug patterns
  • Lower sceneThreshold (0.25–0.35) β€” catch more cuts within blocks

Noisy or degraded VHS

  • Raise pixTh + lower picTh β€” the standard analog adjustment
  • Raise uniformMaxStddev (12–18) β€” VHS black slugs are never truly uniform
  • Set removeBefore 0.1 β€” recovers content clipped by ambiguous slug entry points
  • Disable requireDiv5 β€” VHS timing is irregular
  • Lower silenceNoiseDb to -35 dB β€” VHS audio floor is noisier

Clean off-air broadcast

  • Enable requireDiv5 β€” US TV commercials are exact 15/30/60/90 s units
  • Set alwaysKeepFirst 15 and alwaysKeepLast 15 β€” protect cold opens and credits
  • Lower uniformMaxStddev to 5–6 β€” broadcast slates are near-perfect
  • Raise sceneThreshold to 0.45 β€” hard cuts only; avoid dissolve false positives

Recommended workflow

  1. Run with dryRun enabled β€” review detect.json and the activity log
  2. Check dataset.jsonl β€” confidence below 0.90 or only sig_black_boundary firing is worth inspecting
  3. Adjust parameters and re-run dry until the plan is correct
  4. Remove dryRun and enable reencode for final archival export

ML Dataset Output

Every run writes logs/dataset.jsonl β€” one JSON object per line, one line per segment, 74 columns. Load it directly:

import pandas as pd
df = pd.read_json("logs/dataset.jsonl", lines=True)

Column Groups

Identity (4 cols)

ColumnTypeDescription
run_idstringISO-8601 UTC timestamp of the processing run
source_filestringInput filename stem
segment_indexintIndex within this label type
timeline_positionintSequential position in the overall file timeline

Timing (9 cols)

ColumnDescription
start_s, end_s, dur_sAbsolute timestamps and duration in seconds
start_norm, end_norm, dur_normPosition and duration as fraction of file length (0–1)
offset_from_start_sSeconds from start of recording
offset_from_end_sSeconds from end of recording

Signal Indicators β€” all 0.0 or 1.0 (11 cols)

ColumnFires when
sig_black_boundaryInterval is bracketed by a black slug
sig_within_commercial_rangeDuration within [min_commercial, max_commercial]
sig_silence_overlapSilence corroboration fired
sig_uniform_overlapUniform frame corroboration fired
sig_high_scene_rateScene rate exceeds 1.3Γ— file average
sig_demoted_min_show_segmentWas a commercial candidate, demoted by show guard
sig_always_keep_first/lastInterval falls within the always-keep window
sig_content_between_commercialsStandard keep between two commercial blocks
sig_div5_snappedBoundary was snapped to a 30 s multiple

Classification (3 cols)

ColumnValues
label"commercial" or "keep"
label_int1 = commercial, 0 = keep
confidenceDetection confidence score 0.0–1.0

Usage Examples

import pandas as pd
from sklearn.ensemble import RandomForestClassifier

df = pd.read_json("logs/dataset.jsonl", lines=True)

# Feature matrix
X = df[[
    "dur_s", "dur_norm", "start_norm",
    "black_left_dur_s", "black_right_dur_s",
    "silence_coverage", "has_silence_overlap",
    "scene_change_rate", "scene_change_rate_vs_avg",
    "sig_black_boundary", "sig_silence_overlap",
]]
y = df["label_int"]

# Compare across parameter tuning runs
runs = pd.concat([
    pd.read_json("run1/logs/dataset.jsonl", lines=True),
    pd.read_json("run2/logs/dataset.jsonl", lines=True),
])
runs.groupby("param_scene_threshold")["run_commercial_ratio"].mean()

# Inspect low-confidence cuts
df[(df["label"] == "commercial") & (df["confidence"] < 0.9)]
β„Ή
All param_* columns are fully denormalised. Individual files can be concatenated across runs and remain independently queryable.

Use Cases

Archiving Full Broadcasts With and Without Commercials

A collector digitizes a 1992 NBC Sunday Night Movie from VHS. They want to preserve the entire broadcast β€” including vintage promos and ads β€” but also need a clean version for watching. AdSlicerProXP outputs both automatically: show/ (clean movie) and commercials/ (all ad blocks), plus detect.json for reproducible archive metadata.

Digitizing VHS Tapes With Automatic Cleanup

A preservation group receives 300 home-recorded VHS tapes spanning 1986–2004. Batch-mode processing handles entire shelves at once. Threshold tuning ensures detection works across varied analog sources. Hundreds of hours are segmented, cleaned, exported into uniform directory structures, and logged for verification β€” eliminating months of manual editing.

Preparing Footage for YouTube or Streaming

A creator uploading 1990s cartoons needs commercial breaks removed to avoid Content ID strikes. AdSlicerProXP with reencode produces frame-accurate clean masters with no leftover partial-commercial frames.

Building ML Training Sets

A research lab training a commercial-boundary detection model needs ground-truth timestamps for black slugs, silence regions, ad gaps, and keep segments. AdSlicerProXP's dataset.jsonl provides a complete labeled dataset β€” 74 feature columns per segment β€” without manual annotation.

Creating Commercial Compilations

An editor wants all McDonald's commercials from 1997 ABC broadcasts. Commercials are already cleanly extracted into individual files in commercials/ β€” drop them into a timeline or sort by brand via captioning or logo detection.

High-Volume TV Archive Processing

A university lab processes 1,200 Betacam SP and VHS tapes from 1980–2002. AdSlicerProXP's structured run_manifest.json and detect.json provide the audit trail. Every tape gets a uniform directory layout with consistent metadata ready for digital asset management ingestion.

Building from Source

First-time setup

Download static ffmpeg/ffprobe builds into src-tauri/binaries/. Run once before first build.

./build.sh setup-bins

Dev mode

cd src-tauri
cargo tauri dev

Release builds

CommandTarget
./build.shAuto-detect current OS
./build.sh mac-universalmacOS arm64 + x86_64 fat binary
./build.sh mac-armmacOS Apple Silicon only
./build.sh mac-x86macOS Intel only
./build.sh windowsWindows x86_64

ffmpeg and ffprobe are bundled automatically. Users need no external dependencies.

Adding a built-in preset

Drop a .json file into src-tauri/presets/ and run ./build.sh. The tauri.conf.json resources glob picks it up β€” no code changes needed.

Introduction
AdSlicerProXP Help v2.0