mirror of
https://github.com/wiltodelta/remove-ai-watermarks.git
synced 2026-08-09 23:50:40 +02:00
Harden automatic video watermark removal for product use
This commit is contained in:
+11
-2
@@ -210,7 +210,15 @@ must also remain anchored instead of drifting with a scene object. Matching
|
||||
provider provenance may relax the visual score only for registered
|
||||
provenance-aware marks; metadata alone never creates a detection.
|
||||
|
||||
The video stream is transcoded and the original audio stream is copied.
|
||||
`--mark auto` is the default. It evaluates all providers in one decode pass and
|
||||
selects the first stable match in specificity order: Sora, Veo, Seedance, Dola,
|
||||
Hailuo, then Kling. Their confidence scores are independently calibrated and
|
||||
are not compared across providers. Pass an explicit `--mark` to scan only that
|
||||
provider.
|
||||
|
||||
The video stream is transcoded and the complete original audio stream is
|
||||
copied without truncating an audio tail that extends beyond the final video
|
||||
frame.
|
||||
Supported input and output containers are MP4, MOV, M4V, WebM, MKV, AVI, and
|
||||
FLV; the output extension must match the input. The default `cv2` backend is
|
||||
fast but can smear structured backgrounds. Select `--backend migan` or
|
||||
@@ -220,7 +228,8 @@ installed backend.
|
||||
AI metadata is stripped from the encoded output by default. Use
|
||||
`--keep-metadata` to retain mapped container metadata. When no temporally stable
|
||||
mark is found, the command writes no output and exits with the no-visible-mark
|
||||
status.
|
||||
status. The final path is replaced atomically only after ffmpeg completes, so a
|
||||
failed encode does not overwrite an existing result.
|
||||
|
||||
## Remove invisible watermarks
|
||||
|
||||
|
||||
+18
-11
@@ -215,6 +215,11 @@ drifting with a scene object. Kling also requires a bright low-saturation
|
||||
candidate near the expected frame edge. Provider provenance can recover
|
||||
low-contrast runs only after visual evidence exists for the marks that define a
|
||||
provenance prior, so metadata alone does not erase a clean API export.
|
||||
The default auto-router evaluates all detectors in one decode pass but does not
|
||||
rank their raw confidence values. Those scores are provider-specific and known
|
||||
to cross-match in some layouts, so the router applies the independent temporal
|
||||
policies and selects the first stable result in specificity order. Use an
|
||||
explicit mark when the provider is already known.
|
||||
Historical Sora Turbo exports use a small OpenAI swirl in the corner rather
|
||||
than the moving mascot-and-wordmark design; that earlier variant is not
|
||||
detected by the `sora` video mark. Hailuo and Kling coverage is specific to the
|
||||
@@ -223,17 +228,19 @@ silhouette. Other provider video labels are not supported yet. Google video
|
||||
SynthID has a candidate-producing VAE path, while other proprietary invisible
|
||||
video watermarks have no registered attack.
|
||||
|
||||
Visible removal transcodes the video stream and copies audio. Its frame-local
|
||||
fill is not a motion-aware video inpainting model. OpenCV can leave a visible
|
||||
smear where the mark overlaps a hard edge or structured texture, and the smear
|
||||
can vary over time. MI-GAN and LaMa improve individual frames but do not
|
||||
guarantee temporal coherence. The Veo diamond uses a shape mask to limit damage
|
||||
outside the symbol. Seedance fills the full localized box because a synthetic
|
||||
outline mask left part of the real translucent border visible in an end-to-end
|
||||
check. OpenCV may therefore soften texture inside that small box; use MI-GAN or
|
||||
LaMa when reconstruction quality matters. The current encoder also emits a
|
||||
constant-frame-rate output at the decoded stream rate, so variable-frame-rate
|
||||
preservation is not yet guaranteed.
|
||||
Visible removal transcodes the video stream and copies the complete audio
|
||||
stream without shortening an audio tail. Completed visible and invisible
|
||||
encodes are published atomically, so an encode failure preserves an existing
|
||||
output. Its frame-local fill is not a motion-aware video inpainting model.
|
||||
OpenCV can leave a visible smear where the mark overlaps a hard edge or
|
||||
structured texture, and the smear can vary over time. MI-GAN and LaMa improve
|
||||
individual frames but do not guarantee temporal coherence. The Veo diamond
|
||||
uses a shape mask to limit damage outside the symbol. Seedance fills the full
|
||||
localized box because a synthetic outline mask left part of the real
|
||||
translucent border visible in an end-to-end check. OpenCV may therefore soften
|
||||
texture inside that small box; use MI-GAN or LaMa when reconstruction quality
|
||||
matters. The current encoder also emits a constant-frame-rate output at the
|
||||
decoded stream rate, so variable-frame-rate preservation is not yet guaranteed.
|
||||
|
||||
Native TC260 metadata in MP4/MOV is supported at its normative
|
||||
`moov.udta.meta.keys/ilst` placement, including non-faststart files whose
|
||||
|
||||
@@ -125,7 +125,9 @@ use the verified ffmpeg stream-copy path for removal.
|
||||
[`video_encoding.py`](../src/remove_ai_watermarks/video_encoding.py) owns the
|
||||
raw-BGR ffmpeg command and pipe lifecycle shared by visible removal and
|
||||
invisible regeneration. It centralizes container codecs, optional audio stream
|
||||
copying, metadata/chapter policy, and encode-failure reporting.
|
||||
copying, metadata/chapter policy, encode-failure reporting, and atomic
|
||||
same-directory publication. Each mapped stream is allowed to reach its own end,
|
||||
so a copied audio tail is not shortened to the raw-video input duration.
|
||||
|
||||
[`video_invisible.py`](../src/remove_ai_watermarks/video_invisible.py)
|
||||
implements the oracle-gated video SynthID candidate engine. It samples frames
|
||||
@@ -161,6 +163,14 @@ expected lower-frame area and calibrated independently. A strong relocated Veo
|
||||
diamond may bypass the known layout anchors, but weak free-corner matches never
|
||||
enter the temporal arbiter.
|
||||
|
||||
The default `auto` route decodes each frame once, shares its grayscale and
|
||||
normalized representations across all detectors, and caches resized synthetic
|
||||
template features for the fixed stream geometry. Provider confidence scales
|
||||
are not comparable: selection applies each provider's temporal arbiter and
|
||||
takes the first stable result in specificity order (`sora`, `veo`, `seedance`,
|
||||
`dola`, `hailuo`, `kling`). An explicit mark uses the same scan path with one
|
||||
candidate.
|
||||
|
||||
Every per-frame result is untrusted. The provider-specific stabilization
|
||||
wrappers share one recurrence implementation, while retaining separate visual
|
||||
floors and minimum-run policy. Provenance can relax a low-contrast run only
|
||||
|
||||
+20
-12
@@ -174,8 +174,8 @@ if result.remaining_metadata:
|
||||
|
||||
`remove_video_invisible` supports MP4, MOV, and M4V. It regenerates the complete
|
||||
video through a VAE in bounded batches, shares one seeded latent-noise field
|
||||
across all frames, streams pixels to ffmpeg, copies audio, and strips source
|
||||
metadata. The default output is
|
||||
across all frames, streams pixels to ffmpeg, copies complete audio, strips
|
||||
source metadata, and publishes atomically. The default output is
|
||||
`input_synthid_candidate.mp4`; a distinct same-container output is required.
|
||||
|
||||
The returned `VideoInvisibleResult` includes output geometry, frame rate, frame
|
||||
@@ -191,13 +191,15 @@ Flash's built-in content verification before treating it as watermark-negative.
|
||||
import remove_ai_watermarks as raiw
|
||||
|
||||
result = raiw.remove_video_visible(
|
||||
"sora.mp4",
|
||||
"sora_clean.mp4",
|
||||
"input.mp4",
|
||||
"clean.mp4",
|
||||
backend="cv2",
|
||||
strip_metadata=True,
|
||||
)
|
||||
if result.output is None:
|
||||
print("No temporally stable Sora mark was found")
|
||||
print("No temporally stable supported mark was found")
|
||||
else:
|
||||
print(result.mark)
|
||||
|
||||
veo_result = raiw.remove_video_visible(
|
||||
"veo.mp4",
|
||||
@@ -228,18 +230,24 @@ kling_result = raiw.remove_video_visible(
|
||||
|
||||
`remove_video_visible` scans the complete video before writing output. It
|
||||
combines synthetic multi-scale visual matching with temporal consistency, so an
|
||||
isolated lookalike in one frame is not enough to authorize inpainting. The
|
||||
supported `mark` values are `sora`, `veo`, `seedance`, `dola`, `hailuo`, and
|
||||
`kling`. The Veo detector recognizes the current four-point diamond and the
|
||||
isolated lookalike in one frame is not enough to authorize inpainting.
|
||||
`mark="auto"` is the default: it evaluates all providers in one decode pass and
|
||||
selects the first stable match in specificity order (`sora`, `veo`, `seedance`,
|
||||
`dola`, `hailuo`, `kling`). Provider confidence values are calibrated
|
||||
independently and are not compared across detectors. Pass one of those explicit
|
||||
values to restrict the scan to a single provider. The Veo detector recognizes
|
||||
the current four-point diamond and the
|
||||
legacy `Veo` text. Seedance recognizes the boxed `AI` label, Dola recognizes
|
||||
its compact text label, Hailuo recognizes the composite MINIMAX/Hailuo label,
|
||||
and Kling recognizes its bottom-right logo, wordmark, and version suffix. Each
|
||||
variant has an independent synthetic silhouette and calibrated temporal policy.
|
||||
|
||||
The returned `VideoVisibleResult` records the total, detected, and removed frame
|
||||
counts plus any AI metadata that survived the output encode. The function
|
||||
returns `output=None` and writes no file when no stable mark is selected. Video
|
||||
pixels are transcoded through ffmpeg while the source audio stream is copied.
|
||||
The returned `VideoVisibleResult` records the selected `mark`, the total,
|
||||
detected, and removed frame counts, plus any AI metadata that survived the
|
||||
output encode. The function returns `output=None` and writes no file when no
|
||||
stable mark is selected. Video pixels are transcoded through ffmpeg while the
|
||||
complete source audio stream is copied. A failed encode preserves any existing
|
||||
output; only a completed result is published atomically.
|
||||
|
||||
## Remove invisible watermarks
|
||||
|
||||
|
||||
@@ -41,7 +41,10 @@ when you can select the affected area yourself.
|
||||
| `kling` | Kling swirl, `KLING AI`, version, and optional `PRO` suffix | Fixed bottom-right edge | Combines a synthetic logo rescue with font variants, an edge gate, a white-label gate, and anchored temporal recurrence. |
|
||||
|
||||
Use `video visible` for this registry. It is separate from the image `visible`
|
||||
command because selection is made over a sequence rather than one raster.
|
||||
command because selection is made over a sequence rather than one raster. Its
|
||||
default `auto` mode scans all six entries in one decode pass and selects the
|
||||
first temporally stable match in table order; an explicit mark restricts the
|
||||
scan to that row.
|
||||
|
||||
## Fill backends
|
||||
|
||||
|
||||
Reference in New Issue
Block a user