Add Seedance and Dola video removal

This commit is contained in:
Victor Kuznetsov
2026-07-29 17:56:52 -07:00
parent f330dd9c94
commit 41b6fd0682
13 changed files with 529 additions and 67 deletions
+9 -6
View File
@@ -153,18 +153,21 @@ different container extension.
Visible video labels and invisible video watermarks are not handled by this
command.
## Remove a visible Sora or Veo video mark
## Remove a supported visible video mark
```bash
remove-ai-watermarks video visible input.mp4 -o clean.mp4
remove-ai-watermarks video visible veo.mp4 --mark veo -o veo_clean.mp4
remove-ai-watermarks video visible seedance.mp4 --mark seedance -o seedance_clean.mp4
remove-ai-watermarks video visible dola.mp4 --mark dola -o dola_clean.mp4
```
The experimental command supports the moving Sora mascot and wordmark plus two
Veo corner variants: the current four-point diamond and the legacy `Veo` text.
Sora searches the whole frame at multiple scales. Veo searches the
bottom-right corner using separate synthetic silhouettes for the two variants.
Both require a spatially recurring candidate across adjacent frames. Matching
The experimental command supports the moving Sora mascot and wordmark, two Veo
corner variants, the Seedance boxed `AI` label, and the `Dola AI` text label.
Sora searches the whole frame at multiple scales. The other detectors search
bounded bottom-right regions with separate synthetic silhouettes. Every mark
requires a spatially recurring candidate across adjacent frames. Fixed marks
must also remain anchored instead of drifting with a scene object. Matching
provider provenance may relax the visual score, but metadata alone never
creates a detection. Clean API exports therefore remain untouched.
+14 -8
View File
@@ -174,16 +174,19 @@ WebM, Matroska, MP3, WAV, FLAC, OGG, Opus, and AAC container metadata is strippe
through ffmpeg with stream copying. The operation fails if ffmpeg is absent or
cannot parse the input.
### Visible video removal supports Sora and Veo and is still experimental
### Visible video removal is provider-specific and still experimental
The experimental `video metadata` command and high level video API inspect and
strip supported AI provenance metadata without transcoding streams.
`video visible` and `remove_video_visible` additionally support the moving
Sora 2 mascot and wordmark, the current Veo four-point diamond, and the legacy
`Veo` text. Detection requires a recurring visual candidate across adjacent
frames. Provider provenance can recover low-contrast runs only after visual
evidence exists, so metadata alone does not erase a clean API export.
Sora 2 mascot and wordmark, the current Veo four-point diamond, the legacy
`Veo` text, the Seedance boxed `AI` label, and the fixed `Dola AI` text.
Detection requires a recurring visual candidate across adjacent frames.
Seedance, Dola, and Veo candidates must remain anchored rather than drifting
with a scene object. Provider provenance can recover low-contrast runs only
after visual evidence exists, so metadata alone does not erase a clean API
export.
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. Other provider video labels and proprietary
@@ -194,9 +197,12 @@ 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, but OpenCV may still soften texture inside it. The current
encoder also emits a constant-frame-rate output at the decoded stream rate, so
variable-frame-rate preservation is not yet guaranteed.
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
+21 -19
View File
@@ -115,32 +115,34 @@ only a `Segment.Tags.Tag.SimpleTag` pairing `TagName=AIGC` with a JSON
those container tags without transcoding the encoded streams.
[`video_visible.py`](../src/remove_ai_watermarks/video_visible.py) implements
the first pixel stages for Sora and Veo. The Sora detector searches a normalized
frame with a fully synthetic mascot-and-text silhouette at several scales. The
Veo detector uses separate synthetic silhouettes for the current four-point
diamond and legacy `Veo` text, with bounded bottom-right searches calibrated
independently from Sora. A strong relocated-diamond match may bypass the known
the first pixel stages for Sora, Veo, Seedance, and Dola. The Sora detector
searches a normalized frame with a fully synthetic mascot-and-text silhouette
at several scales. The Veo detector uses separate synthetic silhouettes for the
current four-point diamond and legacy `Veo` text. Seedance uses a synthetic
rounded boxed-`AI` silhouette, while Dola uses an OpenCV-font `Dola AI`
silhouette. All fixed-mark searches are bounded to the bottom-right 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.
This prevents recurring scene details in clean API exports from being promoted
to a watermark.
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
after recurring visual evidence exists. Sora transition frames follow the
nearest confirmed moving position only with Sora provenance. A confirmed Veo
run can cover low-contrast frames at its fixed position. This separation keeps
clean API exports from being modified merely because metadata names the same
generator.
nearest confirmed moving position only with Sora provenance. Veo, Seedance,
and Dola additionally require candidates to remain anchored to the start of a
run. This rejects slowly drifting scene details that still have high
frame-to-frame overlap.
Removal runs in a second decode pass. Sora and legacy Veo text use padded box
masks. The square Veo diamond uses a synthetic shape mask so transparent box
corners do not erase unrelated pixels. Every mask goes through the shared
`watermark_registry.fill` backends. ffmpeg encodes the changed video stream and
copies optional audio. The default OpenCV fill is the speed floor; structured
backgrounds need MI-GAN or LaMa for better reconstruction. Invisible video
stages must continue to reuse the image and metadata implementations rather
than copying their logic.
Removal runs in a second decode pass. Sora, legacy Veo text, Dola text, and the
Seedance box use box masks. Seedance deliberately fills the complete localized
box: a synthetic outline mask passed repeat detection but left part of the real
translucent border visible during visual end-to-end review. The square Veo
diamond uses a synthetic shape mask so transparent corners do not erase
unrelated pixels. Every mask goes through the shared `watermark_registry.fill`
backends. ffmpeg encodes the changed video stream and copies optional audio.
The default OpenCV fill is the speed floor; structured backgrounds need MI-GAN
or LaMa for better reconstruction. Invisible video stages must continue to
reuse the image and metadata implementations rather than copying their logic.
The inherited ISOBMFF metadata path currently reads the complete container into
memory; replacing that with a streaming box copier is a prerequisite for large
+16 -4
View File
@@ -154,7 +154,7 @@ stream bytes. MKV/WebM inspection recognizes the corresponding
`Segment.Tags.Tag.SimpleTag` representation; its removal requires ffmpeg for a
stream-copy remux.
## Remove a visible Sora or Veo video mark
## Remove a supported visible video mark
```python
import remove_ai_watermarks as raiw
@@ -173,14 +173,26 @@ veo_result = raiw.remove_video_visible(
"veo_clean.mp4",
mark="veo",
)
seedance_result = raiw.remove_video_visible(
"seedance.mp4",
"seedance_clean.mp4",
mark="seedance",
)
dola_result = raiw.remove_video_visible(
"dola.mp4",
"dola_clean.mp4",
mark="dola",
)
```
`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` and `veo`. The Veo detector recognizes the
current four-point diamond and the legacy `Veo` text with separate synthetic
silhouettes.
supported `mark` values are `sora`, `veo`, `seedance`, and `dola`. The Veo
detector recognizes the current four-point diamond and the legacy `Veo` text.
Seedance recognizes the boxed `AI` label, while Dola recognizes its compact
text label. 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
+2
View File
@@ -35,6 +35,8 @@ when you can select the affected area yourself.
| --- | --- | --- | --- |
| `sora` | Sora 2 mascot and wordmark | Moves among frame positions | Requires a temporally recurring visual match; the older Sora Turbo corner swirl is a different unsupported mark. |
| `veo` | Current four-point diamond and legacy `Veo` text | Fixed bottom-right corner | Uses separate silhouettes and requires a recurring match; learned fill is preferable on structured backgrounds. |
| `seedance` | Boxed `AI` label | Fixed bottom-right corner | Requires an anchored recurring match; the full localized box is filled because a thinner synthetic shape mask leaves the real translucent rim behind. |
| `dola` | `Dola AI` text | Fixed bottom-right corner | Requires an anchored recurring match; ByteDance or BytePlus provenance can relax only an existing visual run. |
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.
+13 -2
View File
@@ -56,8 +56,8 @@ the existing ffmpeg stream-copy path removes the tags without transcoding.
- **Built in the dated batch:** soft-binding vendor detection, IPTC Photo
Metadata AI-disclosure fields, C2PA detection and stripping for supported
ISOBMFF video, the optional Adobe TrustMark decoder, and temporally stabilized
visible Sora and Veo removal. Other visible video logos and proprietary
audio-watermark detection remain outside the package.
visible Sora, Veo, Seedance, and Dola removal. Other visible video logos and
proprietary audio-watermark detection remain outside the package.
Metadata stripping for supported audio containers is a separate implemented
path.
@@ -90,6 +90,17 @@ pixels or alpha maps from that project: it uses two synthetic silhouettes,
known-layout searches plus a strong relocated-diamond fallback, and a separate
temporal arbiter calibrated against raw watermarked clips and clean API exports.
**ByteDance video surfaces use distinct visible labels.** Public Seedance
showcase clips contain a fixed rounded box with `AI`, while the Dola sample in
[issue #16](https://github.com/wiltodelta/remove-ai-watermarks/issues/16) uses
fixed `Dola AI` text. The independent
[Seedance remover](https://github.com/SamurAIGPT/seedance-2.0-watermark-remover)
estimates a static corner from a temporal mean frame and edge density. Our
implementation instead matches provider-specific synthetic silhouettes on
every frame, then requires an anchored temporal run. This extra anchor check
was necessary because a moving clean scene detail could retain enough adjacent
overlap to pass a recurrence-only gate.
**The faint-visible-mark precision/recall wall is fundamental, not a heuristic artifact.** The visible-watermark-detection literature has moved to LEARNED segmentation / object-detection (WDNet WACV'21 arXiv:2012.07616; SLBR ACM MM'21, open code+weights; the PRCV'18 large-scale detector; Su et al. survey 2025), but three verified findings bound what a learned detector actually buys: (1) a claim that a confidence threshold "cleanly separates" true from false matches even with a learned CNN front-end was **REFUTED** in verification (arXiv:1705.08593) -- the precision/recall wall persists even with learned features. (2) Learned detectors need a LARGE, pattern-diverse labeled dataset trained on synthetic composites (PRCV'18: 60k images / 80 watermark classes; CLWD: 60k / 160 marks), and off-distribution degradation is a documented real axis (models trained on limited-pattern LVW transfer worse; diversity of training patterns drives generalization). (3) Inference is cheap (WDNet ~8 ms at 256x256) -- the cost is the data pipeline, not runtime. Net: a learned detector shifts the frontier but does NOT remove the wall; for a SINGLE mark the cheapest next step is a small patch classifier (real-sparkle vs false-positive) on top of the existing NCC localizer, not a full segmentation model. SLBR is a ready baseline. The current NCC + false-positive gate (core-ring brightness margin + gradient-NCC crispness + white-core saturation) is a sound operating point, and the residual miss is the information-theoretic wall the literature confirms.
**Visible-mark landscape beyond the registry.** Meta stamps a visible "Imagined with AI" mark (bottom-LEFT, a small symbol) on its OWN Meta AI / "Imagine" output; for third-party images it relies on C2PA / IPTC, not a visible mark. Samsung Galaxy AI additionally uses a **four-star icon** variant in a corner alongside the localized text wordmark `samsung_engine` calibrates (only the Italian text variant is covered) -- the icon is a distinct, uncovered variant. Every source agrees visible + metadata marks are trivially removable (crop / screenshot, ~2 s), which is the tool's premise.