Skip to content
vulkan101Public

About

Tool for stitching GoPro Max footage files together

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

13 Commits

Folders and files

Repository files navigation

Stitch360

Drag in your split GoPro MAX .360 chapter files. Get one continuous file back. Nothing lost.

platform license python

Free for personal and other non-commercial use. Commercial use requires permission.

The problem

Long recordings on a GoPro MAX get split into multiple .360 chapter files once they cross the ~4GB card-format limit — GS010293.360, GS020293.360, GS030293.360, and so on. GoPro's own software can play them back seamlessly, but the moment you want a single continuous file for any other .360-aware tool, you're stuck manually rejoining chapters.

Stitch360 does exactly that: lossless concatenation. It doesn't touch a single pixel — video, audio (including the raw ambisonic spatial-audio track), and the embedded GPS/gyro telemetry all come through byte-for-byte, just joined end-to-end into one file.

On the word "stitch": here it means joining the chapter files together. GoPro uses the same word for something else — warping the two circular fisheye images into the pannable 360 view, which GoPro Player does live during playback. Stitch360 doesn't do that and doesn't need to; it preserves the raw dual-fisheye video untouched so Player can keep doing it exactly as it does for an original file.

Features

  • Drag and drop — drop chapter files (or a whole folder) straight onto the window
  • Auto-detects and orders chapters by GoPro's filename convention, and groups multiple recordings in one drop into separate jobs
  • Manual reorder if auto-detection ever gets it wrong — drag rows to fix the sequence, per recording (can't accidentally mix chapters between recordings)
  • One-click run, with a real progress bar per job
  • Nothing is re-encoded — pure container-level stream copy, so it's fast and doesn't degrade quality
  • Preserves everything that ffmpeg can physically write: both fisheye video tracks, both audio tracks (compressed stereo and raw ambisonic), and the GPS/gyro telemetry (GPMF) track
  • The result still opens in GoPro Player and renders as a proper pannable 360 view, exactly like an original chapter — this takes deliberate work to get right (see Technical notes)
  • Self-healing: verifies every stream it expected to carry through actually made it into the output, and automatically repairs anything ffmpeg silently dropped (see Technical notes — this is a real thing that happens on full-length recordings)
  • Never touches your originals — chapter files are only ever read, never written, moved, or deleted
  • Output written straight back into the same folder as your chapters, with a name that can't collide with the originals or GoPro's own exports
  • A separate "Repair Export" tab for when some other tool crashes partway through exporting a large video and leaves behind a huge, unplayable file — a real thing that happens with sufficiently long stitched recordings. Point it at the broken file and a healthy reference export from the same source/settings, and it rebuilds a valid, playable file from the intact data that's already there. Unrelated to GoPro chapters specifically; works on any interrupted export from the same class of problem

Install

Option 1 — download the app Grab Stitch360.zip from the Releases page, unzip it anywhere, and run Stitch360.exe. ffmpeg is bundled inside — nothing else to install.

The app ships as a folder (Stitch360.exe + a _internal folder next to it). Keep them together — if you want a Desktop shortcut, right-click the .exe → Send to → Desktop (create shortcut), don't copy the .exe out on its own.

Option 2 — run from source

git clone https://github.com/vulkan101/stitch360.git
cd stitch360
pip install -r requirements.txt
python main.py

You'll also need ffmpeg/ffprobe on your PATH (or vendor them into vendor/ffmpeg/win64/ as ffmpeg.exe/ffprobe.exe — that's what the packaged build bundles).

Usage

  1. Drag your .360 chapter files (or the folder they're in) onto the window.
  2. Check the detected order — reorder by dragging if needed.
  3. Click Run All.
  4. Find <recording>_stitched.360 in the same folder as your chapters.

Technical notes

A few non-obvious things came up building this against real GoPro MAX footage (not just synthetic test files):

  • A lossless join is not enough to keep GoPro Player working. ffmpeg preserves only the moov/udta children it recognises, so the camera's 26 KB metadata block — LENS (lens calibration), CAME (camera identity), FIRM, SETT, plus a 25 KB GPMF blob — gets replaced by a 33-byte stub holding ffmpeg's own encoder tag. Player reads that block to recognise the file as a MAX recording and to know how to warp its two circular lens images into the pannable 360 view, so without it you get flat, apparently-rotated playback of a single raw lens even though every stream and timestamp is perfect. Stitch360 transplants the block back in as the final step of a join. (Verified by experiment: two remuxes of one chapter differing only in those 26 KB — one broken in Player, one correct.) The transplant is O(1) rather than a multi-GB rewrite, because moov sits last in the file and all chunk offsets point backwards into mdat.
  • .360 isn't a container ffmpeg recognizes by extension — the muxer has to be forced explicitly (-f mov), regardless of the output filename.
  • GoPro embeds tmcd (timecode) and fdsc (internal service metadata) tracks with an unresolvable codec, even on the untouched original file. ffmpeg can't mux these at all; they're dropped (they carry no telemetry — GPS/gyro lives in the separate gpmd track, which is preserved).
  • The raw ambisonic audio track needs mov, not mp4 — ffmpeg's mp4 muxer refuses to write its "ambisonic 1" channel layout at all.
  • Even with that fix, ffmpeg can silently drop the ambisonic track at full recording scale (multi-GB, several minutes) when it's interleaved with the other streams during muxing — no error, exit code 0, just... gone. Stitch360 detects this by verifying every requested stream actually landed in the output, and automatically repairs any that didn't by isolating and remuxing them separately.

None of this requires any decision from you — it's handled automatically. It's documented here mainly because it was a genuinely surprising set of ffmpeg edge cases, and it seemed worth being upfront about rather than pretending "lossless" was trivial to guarantee.

Development

pip install -r requirements.txt
pip install pytest pyinstaller
python -m pytest tests/

Building the standalone app:

python -m PyInstaller --name Stitch360 --windowed --onedir \
  --icon "stitch360/resources/icon.ico" \
  --add-data "vendor/ffmpeg/win64/ffmpeg.exe;ffmpeg" \
  --add-data "vendor/ffmpeg/win64/ffprobe.exe;ffmpeg" \
  --add-data "vendor/ffmpeg/FFMPEG-LICENSE.txt;ffmpeg" \
  --add-data "vendor/untrunc/win64;untrunc" \
  --add-data "vendor/untrunc/UNTRUNC-LICENSE.txt;untrunc" \
  --add-data "stitch360/resources/icon.ico;resources" \
  --add-data "LICENSE;." \
  --add-data "THIRD-PARTY-LICENSES.md;." \
  --paths . main.py

# also surface the license texts at the top level, next to the .exe,
# rather than leaving them buried in _internal/
cp LICENSE THIRD-PARTY-LICENSES.md dist/Stitch360/

Shipping FFmpeg's and untrunc's GPL license text alongside their binaries isn't optional — don't drop those --add-data lines when cutting a release. untrunc powers the "Repair a broken export" tab only; the rest of the app works fine without it, but the release should still include it.

License

PolyForm Noncommercial License 1.0.0 — free to use, modify and share for any non-commercial purpose: personal projects, hobby and amateur work, study and research, and use by charities, schools, public research bodies and government.

Commercial use requires my permission. That includes using it in a business, in paid work, or as part of anything sold or monetised. If you want to use Stitch360 commercially, open an issue and ask — I'm not trying to make it hard, I just want to be asked first.

This makes Stitch360 source-available rather than open source in the strict OSI sense, since that definition doesn't permit restricting commercial use. The code is public and you're free to read, fork and modify it within the terms above.

Bundled third-party components

Releases bundle FFmpeg, which is licensed separately under the GPL v3 and is unaffected by the terms above — you keep your full GPL rights to it. Full details, source links and license texts are in THIRD-PARTY-LICENSES.md. If you'd rather not receive GPL binaries, delete the bundled ffmpeg/ folder and the app will use an FFmpeg you install yourself.

About

Tool for stitching GoPro Max footage files together

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages