Camera Tools Scripting Tool

The Camera Tools for GoPro Heros app allows you control multiple GoPro® cameras. The scripting tool, which is part of the app, allows you to control the app and the cameras via a JavaScript-based scripting language. This document describes all available methods for controlling the app and camera(s).

Note: On Android and iOS scripting works only while the app is running in foreground and while the screen in on.

Camera Tools for Heros - ToolsForGoPro.com

Controller.logMessage(message)

This function writes a message to the status output window.

Controller.logMessage("Hello world!");

Controller.runExternalCommand(command)

This function executes an external command. Note: This function is only available on desktop systems which do not run in a sandbox.

var cmdInfo = {"cmd": "path to command",
               "args": ["arg1"]}; // array of arguments
var result = Controller.runExternalCommand(cmdInfo);
if (result === undefined) {
	Controller.logMessage("Error executing external command.");
}

Controller.setTimeout(callback, timeMs)

This function waits for the given time in milliseconds and then calls the callback.

Example 1: Wait until a given date is reached:

var targetDate = new Date(2021, 2, 21, 17, 33, 1); // Wait for 21st March 2021, 17:33:01
var result = Controller.setTimeout(function() {
	Controller.logMessage("Waiting finished. Current date: " + new Date().toISOString());
}, targetDate.getTime() - Date.now());

Example 2: Wait 2 seconds:

var waitingTime = 2000; // 2 seconds
var result = Controller.setTimeout(function() {
	Controller.logMessage("Waiting finished. Current date: " + new Date().toISOString());
}, waitingTime);

Controller.createGoProCamera(cameraName)

This function creates a new camera object.

var camera = Controller.createGoProCamera("GoPro 1234");
if (camera === undefined)
	Controller.logMessage("Camera not found");

camera.registerConnectionStateListener(callback)

This function registers a listener which is called whenever the connection state of the camera changes.

camera.registerConnectionStateListener(function(connectionState) {
    if (connectionState === "connected") {
		// the camera is connected. It is ready to receive commands.
    }
	else if (connectionState === "connecting") {
		// the camera is connecting
    }
	else if (connectionState === "disconnected") {
		// the camera is disconnected
    }
	else if (connectionState === "loading settings") {
		// the camera is loading settings.
    }
});

camera.getConnectionState()

This function immediately returns the current camera connection state (see camera.registerConnectionStateListener() for details).

var result = camera.getConnectionState
// "result" contains a string as described in the registerConnectionStateListener() method

camera.connectToCamera()

This function connects the given camera with the app. Depending on the current power state of the camera this function also turns on the camera if the camera is switched off.

var camera = Controller.createGoProCamera("GoPro 1234");
if (camera === undefined)
	Controller.logMessage("Camera not found");
else
	camera.connectToCamera();

camera.disconnectFromCamera()

This function disconnects the given camera.

camera.disconnectFromCamera();

camera.powerOffCamera()

This function powers off the camera. The camera can be turned on again using the camera.connectToCamera() function.

var result = camera.powerOffCamera();
if (result === undefined) {
	Controller.logMessage("Failed: The camera is not connected.");
}

camera.startRecording()

This function starts video recording, multi-shot recording, or takes a photo.

var result = camera.startRecording();
if (result === undefined) {
	Controller.logMessage("Failed: The camera is not connected.");
}

camera.stopRecording()

This function stops video recording or multi-shot photos.

var result = camera.stopRecording();
if (result === undefined) {
	Controller.logMessage("Failed: The camera is not connected.");
}

camera.registerRecordingStateListener(callback)

This function registers a listener which is called whenever the recording state of the camera changes.

var result = camera.registerRecordingStateListener(function(isRecording) {
    if (isRecording) {
		// the camera is recoring or live streaming
	}
	else {
		// the camera is not recording
	}
});

camera.isRecording()

This function checks if the camera is recording. The function returns true when the camera is recording and false when it is not recording.

var result = camera.isRecording();
if (result === undefined) {
	Controller.logMessage("Failed: The camera is not connected.");
}
else {
	Controller.logMessage("Is recording: " +  result);
}

camera.getRecordingTime()

This function immediately returns the current recording time in milliseconds.

var result = camera.getRecordingTime();
if (result === undefined) {
	Controller.logMessage("Failed: The camera is not connected.");
}
else {
	Controller.logMessage("Recording duration: " +  result + " milliseconds");
}

camera.registerRecordingTimeListener(callback)

This function registers a listener which is called whenever the recording time (during video recording or live streaming) changes.

var result = camera.registerRecordingTimeListener(function(duration) {
    Controller.logMessage("Recording time: " + duration + " milliseconds");
});

camera.getRemainingPhotos()

This function returns the estimated number of remaining photo available on the camera's SD card.

var result = camera.getRemainingPhotos();
if (result === undefined) {
	Controller.logMessage("Failed: The camera is not connected.");
}
else {
	Controller.logMessage("Remaining photos: " +  result);
}

camera.getRemainingRecordingTime()

This function returns the estimated remaining video recording time in seconds available on the camera's SD card.

var result = camera.getRemainingRecordingTime();
if (result === undefined) {
	Controller.logMessage("Failed: The camera is not connected.");
}
else {
	Controller.logMessage("Remaining recording time: " +  result + " seconds");
}

camera.getRemainingSpace()

This function returns the remaining free space in bytes available on the camera's SD card.

var result = camera.getRemainingSpace();
if (result === undefined) {
	Controller.logMessage("Failed: The camera is not connected.");
}
else {
	Controller.logMessage("Remaining free space: " +  result + " bytes");
}

camera.tagMoment()

This function sends a "tag moment" command to the camera.

var result = camera.tagMoment();
if (result === undefined) {
	Controller.logMessage("Failed: The camera is not connected.");
}

camera.registerLiveStreamingStateListener(callback)

This function registers a listener which is called whenever the live video streaming state of the camera changes.

var result = camera.registerLiveStreamingStateListener(function(streamingState) {
    if (streamingState === "idle") {
		// Live streaming is not active
    }
	else if (streamingState === "configuring") {
		// Live streaming is currently being setup
    }
	else if (streamingState === "ready") {
		// The camera is ready to start live streaming
    }
	else if (streamingState === "streaming") {
		// Live streaming is active
    }
});

if (result === undefined) {
	Controller.logMessage("Error listinging to live streaming state changes. Make sure that the camera is connected.");
}

camera.getLiveStreamingState()

This function immediately returns the current live streaming state of the camera. The different states are described in the camera.registerLiveStreamingStateListener() function.

var result = camera.getLiveStreamingState();
// check the 'registerLiveStreamingStateListener()' method for details about the different connection states.

camera.isChargerAttached()

This function returns if the camera is connected to an external battery charger. The function returns true when the camera is connected to a charger and false when it is running on battery.

var result = camera.isChargerAttached();
if (result === undefined) {
	Controller.logMessage("Failed: The camera is not connected.");
}
else {
	Controller.logMessage("Is attached to charger: " +  result);
}

camera.registerBatteryLevelListener(callback)

This function registers a listener which is called whenever the battery level changes.

var result = camera.registerBatteryLevelListener(function(batteryLevel) {
    Controller.logMessage("The battery level is: " + batteryLevel + "%");
});

camera.getBatteryLevel()

This function immediately returns the current camera battery level in percent.

var result = camera.getBatteryLevel();
if (result === undefined) {
	Controller.logMessage("Failed: The camera is not connected.");
}
else {
	Controller.logMessage("Camera battery level: " +  result + "%");
}

camera.registerGpsAvailableListener(callback)

This function registers a listener which is called whenever the GPS state of the camera changes.

var result = camera.registerGpsAvailableListener(function(isGpsAvailable) {
    if (isGpsAvailable) {
		// the camera is receiving GPS location data
	}
	else {
		// the camera is not receiving GPS data
	}
});

camera.isGpsAvailable()

This function checks if the camera receiving GPS updates. The function returns true when the camera is receiving GPS updates and false when no GPS updates are received (for instance because GPS is disabled or no satellites are available).

var result = camera.isGpsAvailable();
if (result === undefined) {
	Controller.logMessage("Failed: The camera is not connected.");
}
else {
	Controller.logMessage("Is GPS available: " +  result);
}

camera.getCameraModeList()

This function returns a JSON-formatted object containing all camera mode groups, sub-modes, and presets available on the camera.

var result = camera.getCameraModeList();
if (result === undefined) {
	Controller.logMessage("Failed: The camera is not connected.");
}
else {
	Controller.logMessage("Camera mode details: " + JSON.stringify(result));
}
Example output:
[
  {
    "name": "VIDEO",
    "id": 1000,
    "presets": [
      {
        "name": "Mounted",
        "id": 6
      },
      {
        "name": "Standard",
        "id": 0
      },
      {
        "name": "Activity",
        "id": 1
      },
      {
        "name": "Cinematic",
        "id": 2
      },
      {
        "name": "Slomo",
        "id": 3
      }
    ]
  },
  {
    "name": "PHOTO",
    "id": 1001,
    "presets": [
      {
        "name": "Photo",
        "id": 65536
      },
      {
        "name": "Live burst",
        "id": 65537
      },
      {
        "name": "Burst",
        "id": 65538
      },
      {
        "name": "Night",
        "id": 65539
      }
    ]
  },
  {
    "name": "TIME LAPSE",
    "id": 1002,
    "presets": [
      {
        "name": "Air",
        "id": 131079
      },
      {
        "name": "Time warp",
        "id": 131072
      },
      {
        "name": "Time lapse",
        "id": 131073
      },
      {
        "name": "Night lapse",
        "id": 131074
      }
    ]
  }
]

camera.getCameraMode()

This function returns the current camera mode group ID.

var result = camera.getCameraMode();
if (result === undefined) {
	Controller.logMessage("Failed: The camera is not connected.");
}
else {
	Controller.logMessage("Camera mode group ID: " +  result);
}

camera.getCameraSubMode()

This function returns the current camera sub-mode ID.

var result = camera.getCameraSubMode();
if (result === undefined) {
	Controller.logMessage("Failed: The camera is not connected.");
}
else {
	Controller.logMessage("Camera sub-mode ID: " +  result);
}

camera.getCameraPreset()

This function returns the current camera preset ID. This method is only available on GoPro Hero 8 and newer models.

var result = camera.getCameraPreset();
if (result === undefined) {
	Controller.logMessage("Failed: The camera is not connected.");
}
else {
	Controller.logMessage("Camera preset ID: " +  result);
}

camera.setCameraMode(value)

This function changes the camera group mode. See getCameraModeList() for details about the IDs.

var result = camera.setCameraMode(1000); // See: 'getCameraModeList()'
if (result === undefined) {
	Controller.logMessage("Failed: The camera is not connected.");
}

camera.setCameraSubMode(value)

This function changes the camera sub-mode. See camera.getCameraModeList() for details about the IDs.

var result = camera.setCameraSubMode(0); // See: 'getCameraModeList()'
if (result === undefined) {
	Controller.logMessage("Failed: The camera is not connected.");
}

camera.setCameraPreset(value)

This function changes the current camera preset. See camera.getCameraModeList() for details about the IDs.

var result = camera.setCameraPreset(0); // See: 'getCameraModeList()'
if (result === undefined) {
	Controller.logMessage("Failed: The camera is not connected.");
}

camera.getModel()

This function returns the camera model type, for instance "Hero 8 Black".

var result = camera.getModel();
if (result === undefined) {
	Controller.logMessage("Failed: The camera is not connected.");
}
else {
	Controller.logMessage("Camera model: " +  result);
}

camera.getSettingsList()

This function returns a JSON-formatted object containing all settings currently available on the camera. Note: The settings are loaded from the camera and change dynamically! For instance, if the resolution is changed then also the available frame rates might change.

var result = camera.getSettingsList();
if (result === undefined) {
	Controller.logMessage("Failed: The camera is not connected.");
}
else {
	Controller.logMessage("Camera settings: " + JSON.stringify(result));
}
Example output:
[
  {
    "key": 2,
    "name": "Resolution",
    "options": [
      {
        "name": "4K",
        "value": 1
      },
      {
        "name": "4K 4:3",
        "value": 18
      },
      {
        "name": "2.7K",
        "value": 4
      },
      {
        "name": "2.7K 4:3",
        "value": 6
      },
      {
        "name": "1440",
        "value": 7
      },
      {
        "name": "1080",
        "value": 9
      }
    ]
  },
  {
    "key": 3,
    "name": "Frames Per Second",
    "options": [
      {
        "name": "240",
        "value": 0
      },
      {
        "name": "120",
        "value": 1
      },
      {
        "name": "60",
        "value": 5
      },
      {
        "name": "30",
        "value": 8
      },
      {
        "name": "24",
        "value": 10
      }
    ]
  }
]

camera.setCameraSetting(settingKey, settingValue)

This function changes the camera setting identified by the settingKey with the corresponding settingValue. See camera.getSettingsList() for details about the IDs.

var settingKey = 3;
var settingValue = 8;
var result = camera.setCameraSetting(settingKey, settingValue); // see 'getSettingsList()'
if (result === undefined) {
	Controller.logMessage("Failed: The camera is not connected.");
}

Controller.registerWiFiListener(callback)

This function registers a listener which is listening to changes of the currently connected WiFi network.

Controller.registerWiFiListener(function(wifiInfo) {
    if (wifiInfo.state === "connected") {
        Controller.logMessage("Connect to WiFi. Name: " + wifiInfo.ssid + ", password: " + wifiInfo.password);
    }
	else if (wifiInfo.state === "idle") {
		// no network information available.
	}
	else if (wifiInfo.state === "connecting") {
		// currently trying to connect to the WiFi network.
	}
	else if (wifiInfo.state === "failed") {
		// failed to connect to the WiFi network.
	}
	else if (wifiInfo.state === "unkown") {
		// the WiFi name is set but its status is unkown.
	}
});

Controller.queryCurrentWiFiDetailsAsync()

This function reads the current WiFi details from the system and calls camera.registerWiFiListener() when finished.

Controller.queryCurrentWiFiDetailsAsync();

camera.getWifiSsid()

This function returns the WiFi name of the camera.

var result = camera.getWifiSsid();
if (result === undefined) {
	Controller.logMessage("Failed: The camera is not connected.");
}
else {
	Controller.logMessage("Camera SSID: " +  result);
}

camera.getWifiPassword()

This function returns the WiFi password of the camera.

var result = camera.getWifiPassword();
if (result === undefined) {
	Controller.logMessage("Failed: The camera is not connected.");
}
else {
	Controller.logMessage("Camera WiFi password: " +  result);
}

camera.enableWifi()

This function enables the WiFi adapter on the camera. Note: This function does not connect to the WiFi network. Use Controller.connectToCameraWiFiAsync() for connecting to the camera's WiFi network.

var result = camera.enableWifi();
if (result === undefined) {
	Controller.logMessage("Failed: The camera is not connected.");
}

camera.disableWiFi()

This function disables the WiFi adapter on the camera.

var result = camera.disableWiFi();
if (result === undefined) {
	Controller.logMessage("Failed: The camera is not connected.");
}

Controller.connectToCameraWiFiAsync(camera, wifiInterface);

This function connects this system to the camera's WiFi network. Note: The camera's WiFi adapter has to be enabled with camera.enableWifi() first.

Controller.connectToCameraWiFiAsync(camera, "optional wifi interface name");

Controller.connectToWiFiAsync(wifiName, wifiPassword, wifiInterface);

This function connects this system to the given WiFi network.

Controller.connectToWiFiAsync("wifi name", "wifi password", "optional wifi interface name");

Controller.getCurrentWiFiDetails();

This function returns an object containing the currently stored WiFi details. Note: The WiFi details can be outdated. Call Controller.queryCurrentWiFiDetailsAsync() for getting the latest details.

var wifiInfo = Controller.getCurrentWiFiDetails();
if (wifiInfo === undefined) {
	// no WiFi information available
}
else {
	Controller.logMessage("WiFi name: " + wifiInfo.ssid + ", password: " + wifiInfo.password + ", state: " + wifiInfo.state);
}

camera.startLivePreviewFeed();

This function starts the cameras live video preview stream. This stream can for instance be view with ffmpeg/ffplay. Note: The system has to be connected with the camera's WiFi network, else this function will fail (see Controller.connectToCameraWiFiAsync()).

var result = camera.startLivePreviewFeed();
if (result === undefined) {
	Controller.logMessage("Failed: The camera is not connected.");
}

camera.stopLivePreviewFeed();

This function stops the cameras live video preview stream. Note: The system has to be connected with the camera's WiFi network, else this function will fail (see Controller.connectToCameraWiFiAsync()).

var result = camera.stopLivePreviewFeed();
if (result === undefined) {
	Controller.logMessage("Failed: The camera is not connected.");
}

camera.getMediaListAsync(callback, lrvMode)

This function returns a JSON-formatted object containing all media items available on the camera. "lrvMode" is optional and defaults to "false". If lrvMode is "true", then LRV download links are returned for videos. Note: The system has to be connected with the camera's WiFi network, else this function will fail (see Controller.connectToCameraWiFiAsync()).

var result = camera.getMediaListAsync(function(mediaList) {
	Controller.logMessage("Got media: " + JSON.stringify(mediaList));
}, false);
if (result === undefined) {
	Controller.logMessage("Failed: The camera is not connected.");
}
Example output:
[
  {
    "date": "2020-09-23T12:13:56.000Z",
    "fileName": "GH010214.MP4",
    "fileSize": 18761002,
    "path": "100GOPRO",
    "url": "http://10.5.5.9:8080/videos/DCIM/100GOPRO/GH010214.MP4"
  },
  {
    "date": "2020-09-23T12:14:14.000Z",
    "fileName": "GH010215.MP4",
    "fileSize": 187695104,
    "path": "100GOPRO",
    "url": "http://10.5.5.9:8080/videos/DCIM/100GOPRO/GH010215.MP4"
  }
]

camera.registerDownloadStateListener(callback)

This function registers a listener which is called whenever the downloading state of a media file changes. The referenceId is returned when scheduling a download (see camera.downloadMediaAsync()))

camera.registerDownloadStateListener(function(downloadState, referenceId) {
    if (downloadState === "downloaded") {
        // the download with the referenceId has finished.
    }
    else {
        // the download with the referenceId has failed.
    }

    Controller.logMessage("Got download: " + referenceId + " with state: " + downloadState);
});

camera.downloadMediaAsync()

This function adds the given files to the app's download manager. Note: The system has to be connected with the camera's WiFi network, else this function will fail (see Controller.connectToCameraWiFiAsync()).

var mediaToDownload = [{"fileName": "GH010214.MP4", "url": "http://10.5.5.9:8080/videos/DCIM/100GOPRO/GH010214.MP4", "fileSize": -1},
                       {"fileName": "GH010215.MP4", "url": "http://10.5.5.9:8080/videos/DCIM/100GOPRO/GH010215.MP4", "fileSize": -1}];
var result = camera.downloadMediaAsync(mediaToDownload);
if (result === undefined) {
	Controller.logMessage("Failed: The camera is not connected.");
}
else {
    Controller.logMessage("The download referenceIds are: " + JSON.stringify(result));
}

camera.deleteMediaAsync()

This function deletes the given files from the camera. Note: The system has to be connected with the camera's WiFi network, else this function will fail (see Controller.connectToCameraWiFiAsync()).

var mediaToDelete = [{"fileName": "GH010214.MP4", "path": "100GOPRO"},
                     {"fileName": "GH010215.MP4", "path": "100GOPRO"}];
var result = camera.deleteMediaAsync(mediaToDelete, function() {
	Controller.logMessage("Media deletion finished.");
});
if (result === undefined) {
	Controller.logMessage("Failed: The camera is not connected.");
}


camera.formatSdCard()

This functions formats the SD card attached to the camera. This deletes all files on the SD card!.

var result = camera.formatSdCard(function() {
	Controller.logMessage("SD card formatting started.");
});
if (result === undefined) {
	Controller.logMessage("Failed: The camera is not connected.");
}

camera.startTimelapseTool()

(Since version 1.4.9) This functions creates and starts a time-lapse tool on the given camera. Note: It is possible to create multiple time-lapse tools for the same camera. Each tool is identified by its unique toolId.

// Interval settings (capture every 1:30 minutes):
var hours = 0;
var minutes = 1;
var seconds = 30;

// Start and end date for the time-lapse:
var startDate = "2022-11-30 00:00:00";
var endDate = "2022-12-10 14:00:00";

// Daily time-range (from 06:00 in the morning to 18:00 in the evening):
var startTime = "06:00:00";
var endTime = "18:00:00";

// Weekdays on which we want to capture (from Monday to Friday):
var mon = true;
var tue = true;
var wed = true;
var thu = true;
var fri = true;
var sat = false;
var sun = false;

// Toggle recording. This is useful if we record a video. When this value is set
// to "true" then video recording starts in the morning and ends in the evening.
// In "photo" mode this value has no function.
var toggleRecording = false;

var toolId = camera.startTimelapseTool(
                hours, minutes, seconds,
                startDate, endDate,
                startTime, endTime,
                mon, tue, wed, thu, fri, sat, sun,
                toggleRecording,
                function(state, message)
    {
        // Possible states are:
        // -"idle": The time-lapse has not started.
        // -"capturing": The time-lapse is running.
        // -"canceling": The time-lapse is stopping.
        // -"finished": The time-lapse has finished.
        Controller.logMessage("The timelapse tool state is: " + state + ". Status message: " + message);
    }
);
Controller.logMessage("Created a new time-lapse tool with the id '" + toolId + "'.");

camera.stopTimelapsTool()

(Since version 1.4.9) This functions stops the time-lapse tool with the given id.

var result = camera.stopTimelapseTool(toolId);
if (result === undefined) {
    Controller.logMessage("Failed: the time-lapse tool with the given id '" + toolId + "' was not found.");
}