# Video Concat A small, focused desktop app that **merges split stream recordings into one file** using ffmpeg stream-copy (`-c copy`, no re-encoding — fast and lossless). Built with Tauri 2 (Rust backend + TypeScript UI). This is a standalone spin-off of Stream Studio with the song-detection feature removed, so it needs **no Python and no ML model** — just ffmpeg. ## Features - Drag-and-drop / browse to add videos, reorder, select which to merge. - Stream-copy concat with honest real-time progress. On local NVMe a merge runs at ~95 % of plain file-copy speed — the disk is the limit, not the app. - **History** tab: every merge (done, failed, stopped, or interrupted by a crash) with its files, size, time and MB/s. Show the output in its folder, or load the same files again with "Merge again". - BiliBili-Live filename helper (`[date][uploader][title]` → readable name). - Optionally delete the originals after a successful merge. - Optional **Web-optimize MP4 (`+faststart`)**, off by default. It moves the MP4 index to the front so playback can begin mid-download, but ffmpeg has to re-read and re-write the whole file to do it — measured at 17–56 % extra time locally and 60 % over a NAS. Local players don't need it. ## Portable: everything stays in one folder Nothing is written outside the app folder — not to `%APPDATA%`, not to the registry. Copy the folder to another PC and history, theme and options come with it: ``` VideoConcat\ Video Concat.exe ffmpeg.exe, ffprobe.exe data\ history.jsonl <- merge history, one JSON line per job running.json <- only while a merge runs; left behind = "interrupted" webview\ <- WebView2 profile (theme, options) ``` `data\` is created on first run. If the folder isn't writable (say, under Program Files), the app still works but shows a banner and keeps no history. It needs the WebView2 runtime, which ships with Windows 10 and 11. ## Build a standalone (copy-paste) version Double-click **`build.bat`**. It compiles the app and assembles a portable folder with ffmpeg bundled: ``` dist-portable\VideoConcat\ Video Concat.exe <- double-click this ffmpeg.exe <- bundled ffprobe.exe <- bundled ``` Copy that whole `VideoConcat` folder to any Windows PC and run it — nothing else to install. To **upgrade** an existing copy, replace only `Video Concat.exe` and keep its `data\` folder; history carries over. ### Build requirements (on the build machine only) - [Node.js](https://nodejs.org/) - [Rust](https://rustup.rs/) (`winget install Rustlang.Rustup`) - Visual Studio 2022 with the **Desktop development with C++** workload - ffmpeg: in `C:\ffmpeg\bin`, on `PATH`, or point `FFMPEG_DIR` at any folder holding `ffmpeg.exe` + `ffprobe.exe` (an existing portable copy works: `set FFMPEG_DIR=%USERPROFILE%\Documents\VideoConcat`) Building from a network share is slow and fragile (thousands of small files in `node_modules` and `target`). Copy the source to a local disk first. ## Develop Double-click **`dev.bat`** (hot-reload UI + Rust). Needs ffmpeg on `PATH`. In dev mode the `data\` folder sits next to the debug exe in `src-tauri\target\debug\`. ## Test ``` npm run build # the Rust tests embed dist/, so build the UI first cd src-tauri && cargo test ``` Covers the BiliBili rename parser, concat-list path escaping (`\\?\` and UNC prefixes, quotes), duration reuse, "never delete the output", and history crash recovery. ## Benchmark `tools/bench_concat.py` times each pipeline stage with the exact ffmpeg flags the app uses, against the I/O floor of a plain file copy: ``` python tools/bench_concat.py --ffmpeg-dir --make 6 --src D:\bench --dst D:\bench\out ``` ## Icons The app icon lives as vector art in `src-tauri/icons/icon.svg` — a rounded-square gradient tile with the three-filmstrips-into-one-arrow mark. Everything else in `src-tauri/icons/` is generated from it: ``` python tools/make_icons.py ``` That rewrites the PNGs and `icon.ico` with 8x supersampling and a real alpha channel, dropping sub-pixel detail (sprocket holes below 48px, the play-triangle knockout below 64px) rather than smearing it. Only the Windows/desktop icons are regenerated; the `android/` and `ios/` subfolders are untouched. To fix the icon on an **already-built** exe without recompiling it: ``` python tools/patch_exe_icon.py "path\to\Video Concat.exe" ``` That rewrites only the `RT_ICON` / `RT_GROUP_ICON` resources — `.text`, `.rdata` and `.data` come out byte-identical — and keeps a `.bak` alongside. Explorer caches icons aggressively, so follow it with `ie4uinit.exe -show`. Both tools need `pillow` and `numpy`.