Download, combine, and publish GoPro videos with ease.
A tool for automating GoPro video transfers. Download media files over WiFi, combine chapters into complete videos, clean up storage, and optionally publish to YouTube. Designed for hands-free operation via cron jobs or interactive use with detailed status reporting.
Only MP4 videos are inventoried, downloaded, combined, and cleaned up. Photos, thumbnails, and low-resolution preview files are left untouched. Chapter grouping includes only videos with recognized GoPro chapter filenames.
Download, combine, and publish GoPro videos with ease
Usage:
herosync [command]
Available Commands:
provision Connect the GoPro to a Wi-Fi network over Bluetooth
status Display GoPro hardware and storage info
list Show media inventory and sync state details
download Fetch new media files from the GoPro
combine Merge incoming media into outgoing videos
publish Upload outgoing videos to YouTube
cleanup Delete transferred media from GoPro storage
yolo Hands-free sync: download, combine, publish
help Help about any command
Flags:
-c, --config-file string configuration file path
[env: HEROSYNC_CONFIG_FILE]
[default: ~/Library/Application Support/herosync/config.toml]
--gopro-host string GoPro URL host (IP, hostname:port, "" for mDNS discovery)
[env: HEROSYNC_GOPRO_HOST]
[default: ""]
--gopro-scheme string GoPro URL scheme (http, https)
[env: HEROSYNC_GOPRO_SCHEME]
[default: http]
-h, --help help for herosync
-l, --log-level string logging level (debug, info, warn, error)
[env: HEROSYNC_LOG_LEVEL]
[default: info]
-m, --media-dir string parent directory for media storage
[env: HEROSYNC_MEDIA_DIR]
[default: ~/Library/Application Support/herosync/media]
Use "herosync [command] --help" for more information about a command.
herosync reaches the camera over your Wi-Fi network using the
Camera on Home Network
(COHN) feature, which must be provisioned once over Bluetooth:
- Put the camera in pairing mode: Preferences > Wireless Connections > Connect Device > GoPro Quik App.
- Run
herosync provision "My Network", entering the Wi-Fi password when prompted. If several cameras are nearby, select one with--cameraand the last digits of its serial number.
The password is only requested for networks the camera has not joined before;
use --update-password if the network password has changed since. The network
does not need internet access.
The command sets the camera's clock, joins it to the network, and creates a new
COHN certificate, then prints the camera's IP address and HTTPS credentials. Use
--cert-file to save the root CA certificate. Running it again replaces the
previous certificate and credentials, which is also how to recover if a firmware
update resets them.
On macOS, the first run asks to allow your terminal application to use Bluetooth.
In order to access YouTube programmatically for publishing, you'll need to turn on the YouTube Data API for your Google account:
-
Use this wizard to create or select a project in the Google Developers Console and automatically turn on the API. Click Continue, then Go to credentials.
-
On the Create credentials page, click the Cancel button.
-
At the top of the page, select the OAuth consent screen tab. Select an Email address, enter a Product name if not already set, and click the Save button.
-
Select the Credentials tab, click the Create credentials button and select OAuth client ID.
-
Select the application type Desktop app, enter the name "herosync", and click the Create button.
-
Click OK to dismiss the resulting dialog.
-
Click the (Download JSON) button to the right of the client ID.
-
Move the downloaded file to your herosync config directory and rename it
client_secret.json.
These steps were adapted from the upstream
Go Quickstart.
Use Desktop app credentials as described in Google's
desktop OAuth guide.
herosync receives the authorization callback on 127.0.0.1 using a temporary
port. Web application credentials with a fixed redirect such as port 8090
are incompatible; create a Desktop app client and replace client_secret.json.
During authorization, herosync prints a URL before attempting to open your browser. If the browser does not open, open that URL manually in a browser on the same computer. herosync waits up to five minutes for authorization.
Access tokens refresh automatically. If the refresh token expires or access is
revoked, herosync reports that authorization requires renewal and identifies the
cached token.json file beside client_secret.json. Remove that token file and
run herosync publish interactively to authorize again. Keep client_secret.json.
An unattended run reports the error rather than starting a new authorization
flow while a cached token is present.
Successful uploads are recorded under <media-dir>/.uploads/, separately for each
YouTube channel. These records supplement the channel's uploads playlist so
subsequent runs can recognize uploads before API metadata becomes available.
Keep this directory when moving your media library.
To intentionally re-upload a video that you deleted from YouTube, remove only
its local receipt. Each JSON receipt contains the YouTube video_id; its
filename and parent channel directory are hashes. Find the receipt by searching
its contents, replacing VIDEO_ID and the media directory below:
rg --hidden --glob '*.json' --files-with-matches --fixed-strings '"video_id":"VIDEO_ID"' "/path/to/media/.uploads"Inspect the matching JSON, remove that receipt, and run herosync publish again.
Videos still present in the channel's uploads playlist remain subject to
duplicate detection. Preserve the other receipts so recent uploads remain
recognized while API metadata is pending.
Every video requires a Category ID, which by default is "22" for People &
Blogs. Here are the assignable ID's for reference:
| Category | ID |
|---|---|
| Autos & Vehicles | 2 |
| Comedy | 23 |
| Education | 27 |
| Entertainment | 24 |
| Film & Animation | 1 |
| Gaming | 20 |
| Howto & Style | 26 |
| Music | 10 |
| News & Politics | 25 |
| Nonprofits & Activism | 29 |
| People & Blogs | 22 |
| Pets & Animals | 15 |
| Science & Technology | 28 |
| Sports | 17 |
| Travel & Events | 19 |
herosync was designed specifically for my niche use case and will likely not
function out of the box for more common workflows without additional
configuration.
For reference, my setup includes:
- Running the GoPro Labs firmware.
- Using a GoPro HERO13; older models may lack support for some
Labs extensions that
herosyncdepends on. - Enabling the Camera on Home Network (COHN) feature, eliminating the need for Bluetooth Low Energy (BLE) pairing before WiFi connection.
- Configuring the "Open Network" (
OPNW=1) setting for faster HTTP access without requiring HTTPS or basic authentication. - Not preserving GPMF telemetry data, as it’s not needed for my workflow.
- Keeping my GoPro always on and continuously powered via USB.
herosync is released under the Zero Clause BSD License (SPDX: 0BSD).
Copyright © 2025 Aaron Bull Schaefer and contributors