v5.1.0: history tab, portable data folder, optional faststart, new icons & build tools
This commit is contained in:
@@ -10,10 +10,37 @@ 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 (and a `+faststart`
|
||||
finalising pass so the output seeks instantly).
|
||||
- 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
|
||||
|
||||
@@ -28,15 +55,69 @@ dist-portable\VideoConcat\
|
||||
```
|
||||
|
||||
Copy that whole `VideoConcat` folder to any Windows PC and run it — nothing else
|
||||
to install.
|
||||
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` or on `PATH`)
|
||||
- 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`.
|
||||
|
||||
Reference in New Issue
Block a user