{"id":15220492,"url":"https://github.com/alichtman/gopro-chaptered-video-assembler","last_synced_at":"2026-03-06T06:03:21.013Z","repository":{"id":147780584,"uuid":"589951670","full_name":"alichtman/gopro-chaptered-video-assembler","owner":"alichtman","description":"GoPro breaks long videos into multiple files. This tool stitches them back together.","archived":false,"fork":false,"pushed_at":"2025-11-06T11:37:26.000Z","size":612,"stargazers_count":7,"open_issues_count":3,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-11-06T13:05:01.889Z","etag":null,"topics":["assemble","chaptered","gopro","gopro-camera","gopro-cameras","video"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alichtman.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-01-17T10:24:02.000Z","updated_at":"2025-11-06T11:37:30.000Z","dependencies_parsed_at":"2024-01-20T20:29:48.711Z","dependency_job_id":"749e63c8-6cec-4830-a7d8-44fab88a8317","html_url":"https://github.com/alichtman/gopro-chaptered-video-assembler","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/alichtman/gopro-chaptered-video-assembler","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alichtman%2Fgopro-chaptered-video-assembler","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alichtman%2Fgopro-chaptered-video-assembler/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alichtman%2Fgopro-chaptered-video-assembler/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alichtman%2Fgopro-chaptered-video-assembler/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alichtman","download_url":"https://codeload.github.com/alichtman/gopro-chaptered-video-assembler/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alichtman%2Fgopro-chaptered-video-assembler/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30164532,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-06T04:43:31.446Z","status":"ssl_error","status_checked_at":"2026-03-06T04:40:30.133Z","response_time":250,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["assemble","chaptered","gopro","gopro-camera","gopro-cameras","video"],"created_at":"2024-09-28T13:11:05.018Z","updated_at":"2026-03-06T06:03:20.968Z","avatar_url":"https://github.com/alichtman.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# GoPro Chaptered Video Assembler\n\n**GoPro breaks long videos into multiple files. This utility stitches them back together.**\n\n## Quickstart\n\n```bash\n# Install from cargo\n$ cargo install gopro-chaptered-video-assembler\n\n# Run the tool\n$ gopro-chaptered-video-assembler --input PATH_TO_DIRECTORY_WITH_GOPRO_FILES --output PATH_TO_OUTPUT_DIRECTORY\n```\n\n## Why does this exist?\n\nI shoot a lot of long-form videos on my GoPro. Any video longer than a few minutes gets split into multiple files. These are unpleasant to deal with when it's time to edit -- it's tedious and time-consuming to reassemble them. Here's an example of the output structure for multiple long videos:\n\n![](assets/Example.drawio.png)\n\nFiguring out _which video goes where_ did not spark joy. So, this tool does it for me.\n\nIt is:\n\n- Easy to use\n- Lossless (thanks to [`mp4-merge`](https://github.com/gyroflow/mp4-merge))\n- Non-destructive (will never delete your data without asking)\n- End-to-end tested with real GoPro videos\n- Compatible with Linux, macOS, and Windows\n\n### Why can't you sort the files by creation time in the video editor?\n\n- Not all video editors conveniently support this workflow. [Here's how you do this in Premiere Pro](https://www.youtube.com/watch?v=J-qcGNaneMc). It's not exactly a one-click operation.\n- Even if this were easy to do, it's the wrong mental model for the clips. When you record the footage, it's one continuous clip. So you should be working with it as one file, too.\n\n## How does it work?\n\nWhen you record long-form videos on a GoPro, the videos get split into `~4GB` chunks. In the [file naming conventions spec](https://community.gopro.com/s/article/GoPro-Camera-File-Naming-Convention?language=en_US), GoPro refers to these as chaptered video files.\n\nThe naming scheme is:\n\n```bash\nGXYYZZZZ.mp4, where:\n X       is the encoding type (X for HEVC, H for AVC .... yes... I know)\n  YY     is the chapter number\n    ZZZZ is the video number\n```\n\nHere is an example directory structure for a single GoPro video (about ~10min long) that was split into three chapters.\n\n```bash\ngopro-chaptered-video-example/\n├── GX010119.MP4 [Video 0119, chapter 01]\n├── GX020119.MP4 [Video 0119, chapter 02]\n└── GX030119.MP4 [Video 0119, chapter 03]\n```\n\nAnd here's that example with multiple chaptered videos.\n\n![](assets/Example.drawio.png)\n\nYou can see how this gets complicated quickly.\n\n### This tool gives you one single output directory with your GoPro footage\n\nAll output files will have the form: `GoPro_{video_number}.MP4`.\n\n#### For Multichapter Videos...\n\nIt finds and combines multi-chapter videos using [`mp4-merge`](https://github.com/gyroflow/mp4-merge). If a multi-chapter merge operation is done, a set of commands will be printed at the end to clean up the original source directory. These commands are destructive, and therefore need to be run manually.\n\n#### For Single Chapter Videos...\n\nIt renames, or copies (if you use `--no-single-chapter-rename`), single chapter videos.\n\n## Installation\n\nThis package is available on [`crates.io`](https://crates.io/crates/gopro-chaptered-video-assembler).\n\n```bash\n$ cargo install gopro-chaptered-video-assembler\n```\n\n### Building and Installing Source\n\n```\n$ git clone https://github.com/alichtman/gopro-chaptered-video-assembler\n$ cd gopro-chaptered-video-assembler\n\n# Compile\n$ cargo build\n\n# Run dev build\n$ cargo run -- [ARGUMENTS]\n\n# Install to machine\n$ cargo install --path .\n```\n\nDebugging in VSCode works well.\n\n## Example Usage\n\n```bash\n$ gopro-chaptered-video-assembler --input \"/media/alichtman/Extreme SSD/Rock-Climbing/Gunks/High Exposure/\" --output output\n╔═══════════════════════════════════════╗\n║ gopro-chaptered-video-assembler 0.5.1 ║\n╚═══════════════════════════════════════╝\n01:49:33 [INFO] Found 39 files in directory: /media/alichtman/Extreme SSD/Rock-Climbing/Gunks/High Exposure\n01:49:33 [INFO] Found 5 video(s) with 11 total chapters to combine\n01:49:33 [INFO] {\n    7515: [\n        GoProChapteredVideoFile {\n            abs_path: \"/media/alichtman/Extreme SSD/Rock-Climbing/Gunks/High Exposure/GH017515.MP4\",\n            video_number: 7515,\n            chapter: 1,\n        },\n        GoProChapteredVideoFile {\n            abs_path: \"/media/alichtman/Extreme SSD/Rock-Climbing/Gunks/High Exposure/GH027515.MP4\",\n            video_number: 7515,\n            chapter: 2,\n        },\n    ],\n    7517: [\n        GoProChapteredVideoFile {\n            abs_path: \"/media/alichtman/Extreme SSD/Rock-Climbing/Gunks/High Exposure/GH017517.MP4\",\n            video_number: 7517,\n            chapter: 1,\n        },\n        GoProChapteredVideoFile {\n            abs_path: \"/media/alichtman/Extreme SSD/Rock-Climbing/Gunks/High Exposure/GH027517.MP4\",\n            video_number: 7517,\n            chapter: 2,\n        },\n    ],\n    7511: [\n        GoProChapteredVideoFile {\n            abs_path: \"/media/alichtman/Extreme SSD/Rock-Climbing/Gunks/High Exposure/GH017511.MP4\",\n            video_number: 7511,\n            chapter: 1,\n        },\n        GoProChapteredVideoFile {\n            abs_path: \"/media/alichtman/Extreme SSD/Rock-Climbing/Gunks/High Exposure/GH027511.MP4\",\n            video_number: 7511,\n            chapter: 2,\n        },\n        GoProChapteredVideoFile {\n            abs_path: \"/media/alichtman/Extreme SSD/Rock-Climbing/Gunks/High Exposure/GH037511.MP4\",\n            video_number: 7511,\n            chapter: 3,\n        },\n    ],\n    7477: [\n        GoProChapteredVideoFile {\n            abs_path: \"/media/alichtman/Extreme SSD/Rock-Climbing/Gunks/High Exposure/GH017477.MP4\",\n            video_number: 7477,\n            chapter: 1,\n        },\n        GoProChapteredVideoFile {\n            abs_path: \"/media/alichtman/Extreme SSD/Rock-Climbing/Gunks/High Exposure/GH027477.MP4\",\n            video_number: 7477,\n            chapter: 2,\n        },\n    ],\n    7485: [\n        GoProChapteredVideoFile {\n            abs_path: \"/media/alichtman/Extreme SSD/Rock-Climbing/Gunks/High Exposure/GH017485.MP4\",\n            video_number: 7485,\n            chapter: 1,\n        },\n        GoProChapteredVideoFile {\n            abs_path: \"/media/alichtman/Extreme SSD/Rock-Climbing/Gunks/High Exposure/GH027485.MP4\",\n            video_number: 7485,\n            chapter: 2,\n        },\n    ],\n}\n01:49:33 [INFO] And 27 single chapter video(s) to rename\nProceed? (y/n)\n...\n```\n\nThe `output` directory will be created (in the current directory if a relative path is given, or at an absolute path otherwise), and all output files will be found there.\n\nAdditionally, paths with apostrophes (and other special characters) are supported:\n\n```bash\n$ gopro-chaptered-video-assembler -i \"tests/working_test_data/Test\\'s Apostrophe\"  -o tests/output\n...\n```\n\n## Which GoPro models are supported?\n\nAny GoPro model that uses the GoPro file format linked above should be supported. This includes:\n\n- HERO11 Black / Black Mini\n- HERO10 Black\n- HERO9 Black\n- HERO8 Black\n- HERO7 White / Silver / Black\n- HERO6 Black\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falichtman%2Fgopro-chaptered-video-assembler","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falichtman%2Fgopro-chaptered-video-assembler","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falichtman%2Fgopro-chaptered-video-assembler/lists"}