Files
video_concat/README.md
T

124 lines
4.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 <folder with ffmpeg> --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`.