0
2

Open GoPro API制御 + RAW現像

Last updated at Posted at 2024-08-17

はじめに

OpenGoProのAPIがわかりにくく、詳細がよくわからないので、試しながら調べた際のメモ。やりたかったのはUSB接続したGoPro Hero12に対して、以下のような設定で撮影して、ファイルを取得すること。

  • ナイトフォト
  • RAW撮影
  • ISO最大: 100
  • シャープネス: 低

環境

  • GoPro Hero12 (USB接続)
  • macOS 14.5(23F79)
  • Python 3.11.5
  • open_gopro ver.0.16.2

準備

MacBookProとUSB Type-CでGoPro Hero12を接続。
GoProのバッテリを取り外し、USBから電源供給すると連続稼働できる。バッテリをつけていると供給電力より消費電力が多く、バッテリが減って電源が落ちる。

pip install open_gopro rawpy opencv-python

接続+カメラ情報取得

カメラのシリアル番号の末尾が"789"の場合はgopro = WiredGoPro(serial="789")のように指定する。接続するのが1台の場合は何も指定しなくてよい。GoProはUSBのNetwork Control Model (NCM)を利用しており、Ethernet接続しているかのようにGoProにアクセスできる。その際のGoProのIPアドレスは、172.2X.1YZ.51:8080のように決定され、ここでXYZはシリアル番号の末尾3桁である。シリアル番号がC0000123456789のときは、IPアドレスは172.27.189.51となる。詳細はこちら

from open_gopro import WiredGoPro, Params, constants
import asyncio
import os

useGoPro12=True
gopro = WiredGoPro()
await gopro.open()
while not await gopro.is_ready:
    pass
if useGoPro12: # 現状、GoPro Hero12のget_camera_info()を使えない様子。
    cameraInfo = await gopro.http_command.get_camera_info()
    print(cameraInfo)
出力
{
    "id" : "http://172.2X.1YZ.51:8080/gopro/camera/info",
    "status" : "ErrorCode.SUCCESS",
    "protocol" : "Protocol.HTTP",
    "data" : {
        "model_number" : "62",
        "model_name" : "HERO12 Black",
        "firmware_version" : "H23.01.01.30.70",
        "serial_number" : "C0000123456XYZ",
        "ap_mac_addr" : "0xxxxxxxxxxx",
        "ap_ssid" : "GP12345678",
    },
}

カメラの状態を確認

現在のカメラの設定、状態を取得する。

state = await gopro.http_command.get_camera_state()
print(state)
出力
{
    "id" : "http://172.2X.1YZ.51:8080/gopro/camera/state",
    "status" : "ErrorCode.SUCCESS",
    "protocol" : "Protocol.HTTP",
    "data" : {
        "StatusId.BATT_PRESENT" : "True",
        "StatusId.BATT_LEVEL" : "4",
        "StatusId.DEPRECATED_3" : "DEPRECATED",
        "StatusId.DEPRECATED_4" : "DEPRECATED",
        "StatusId.SYSTEM_HOT" : "False",
        "StatusId.SYSTEM_BUSY" : "False",
        "StatusId.QUICK_CAPTURE" : "False",
        "StatusId.ENCODING" : "False",
        "StatusId.LCD_LOCK_ACTIVE" : "False",
        "StatusId.VIDEO_PROGRESS" : "0",
        "StatusId.INTERNAL_14" : "0",
        "StatusId.WIRELESS_ENABLED" : "True",
        "StatusId.PAIR_STATE" : "PairState.NOT_STARTED",
        "StatusId.PAIR_TYPE" : "PairType.NOT_PAIRING",
        "StatusId.WAP_SCAN_STATE" : "WAPState.NEVER_STARTED",
        "StatusId.WAP_SCAN_TIME" : "0",
        "StatusId.WAP_PROV_STAT" : "WAPState.NEVER_STARTED",
        "StatusId.REMOTE_CTRL_CONN" : "False",
        "StatusId.WLAN_SSID" : "",
        "StatusId.AP_SSID" : "GP24863282",
        "StatusId.APP_COUNT" : "0",
        "StatusId.PREVIEW_ENABLED" : "False",
        "StatusId.SD_STATUS" : "SDStatus.OK",
        "StatusId.PHOTOS_REM" : "1408",
        "StatusId.VIDEO_REM" : "4306",
        "StatusId.NUM_TOTAL_PHOTO" : "4",
        "StatusId.NUM_TOTAL_VIDEO" : "1",
        "StatusId.OTA_STAT" : "OTAStatus.IDLE",
        "StatusId.DOWNLOAD_CANCEL_PEND" : "False",
        "StatusId.LOCATE_ACTIVE" : "False",
        "StatusId.MULTI_COUNT_DOWN" : "0",
        "StatusId.SPACE_REM" : "62093524",
        "StatusId.STREAMING_SUPP" : "True",
        "StatusId.WIFI_BARS" : "4",
        "StatusId.NUM_HILIGHTS" : "0",
        "StatusId.LAST_HILIGHT" : "0",
        "StatusId.NEXT_POLL" : "500",
        "StatusId.ANALYTICS_RDY" : "AnalyticsState.ON_CONNECT",
        "StatusId.TIMELAPSE_REM" : "0",
        "StatusId.EXPOSURE_TYPE" : "ExposureMode.DISABLED",
        "StatusId.EXPOSURE_X" : "100",
        "StatusId.EXPOSURE_Y" : "100",
        "StatusId.GPS_STAT" : "False",
        "StatusId.AP_STATE" : "False",
        "StatusId.INT_BATT_PER" : "100",
        "StatusId.ACC_MIC_STAT" : "ExposureMode.DISABLED",
        "StatusId.DIGITAL_ZOOM" : "0",
        "StatusId.WIRELESS_BAND" : "WifiBand.BAND_5_GHZ",
        "StatusId.DIG_ZOOM_ACTIVE" : "False",
        "StatusId.MOBILE_VIDEO" : "False",
        "StatusId.BAND_5GHZ_AVAIL" : "False",
        "StatusId.SYSTEM_READY" : "True",
        "StatusId.BATT_OK_OTA" : "True",
        "StatusId.VIDEO_LOW_TEMP" : "False",
        "StatusId.ORIENTATION" : "Orientation.UPRIGHT",
        "StatusId.ZOOM_ENCODING" : "False",
        "StatusId.FLATMODE_ID" : "Flatmode.NIGHT_PHOTO",
        "StatusId.INTERNAL_90" : "0",
        "StatusId.LOGS_READY" : "False",
        "StatusId.VIDEO_PRESETS" : "6",
        "StatusId.PHOTO_PRESETS" : "65539",
        "StatusId.TIMELAPSE_PRESETS" : "131072",
        "StatusId.PRESETS_GROUP" : "1001",
        "StatusId.ACTIVE_PRESET" : "65539",
        "StatusId.PRESET_MODIFIED" : "0",
        "StatusId.CAPT_DELAY_ACTIVE" : "False",
        "StatusId.MEDIA_MOD_MIC_STAT" : "MediaModMicStatus.REMOVED",
        "StatusId.TIMEWARP_SPEED_RAMP" : "TimeWarpSpeed.SPEED_15X",
        "StatusId.CAMERA_LENS_TYPE" : "MaxLensMode.DEFAULT",
        "StatusId.VIDEO_HINDSIGHT" : "False",
        "StatusId.SCHEDULED_PRESET" : "4294967295",
        "StatusId.SCHEDULED_CAPTURE" : "False",
        "StatusId.CREATING_PRESET" : "False",
        "StatusId.MEDIA_MOD_STAT" : "MediaModStatus.SELFIE_0_HDMI_0_MEDIAMODCONNECTED_FALSE",
        "StatusId.SD_RATING_CHECK_ERROR" : "False",
        "StatusId.SD_WRITE_SPEED_ERROR" : "0",
        "StatusId.TURBO_MODE" : "False",
        "StatusId.CAMERA_CONTROL" : "CameraControl.IDLE",
        "StatusId.USB_CONNECTED" : "False",
        "StatusId.CONTROL_OVER_USB" : "True",
        "StatusId.TOTAL_SD_SPACE_KB" : "62205722",
        "SettingId.RESOLUTION" : "Resolution.RES_4K_16_9",
        "SettingId.FPS" : "FPS.FPS_240",
        "SettingId.INTERNAL_5" : "0",
        "SettingId.INTERNAL_6" : "0",
        "SettingId.INTERNAL_13" : "0",
        "SettingId.INTERNAL_19" : "0",
        "SettingId.INTERNAL_24" : "3",
        "SettingId.INTERNAL_30" : "110",
        "SettingId.INTERNAL_31" : "0",
        "SettingId.INTERNAL_32" : "10",
        "SettingId.INTERNAL_37" : "0",
        "SettingId.INTERNAL_41" : "9",
        "SettingId.INTERNAL_42" : "8",
        "SettingId.INTERNAL_43" : "0",
        "SettingId.INTERNAL_44" : "9",
        "SettingId.INTERNAL_45" : "8",
        "SettingId.INTERNAL_47" : "7",
        "SettingId.INTERNAL_54" : "1",
        "SettingId.AUTO_OFF" : "AutoOff.MIN_5",
        "SettingId.INTERNAL_62" : "1200000",
        "SettingId.INTERNAL_64" : "4",
        "SettingId.INTERNAL_75" : "3",
        "SettingId.INTERNAL_76" : "0",
        "SettingId.INTERNAL_84" : "5",
        "SettingId.INTERNAL_85" : "0",
        "SettingId.INTERNAL_86" : "0",
        "SettingId.INTERNAL_87" : "40",
        "SettingId.INTERNAL_88" : "50",
        "SettingId.LED" : "LED.ALL_ON",
        "SettingId.INTERNAL_102" : "0",
        "SettingId.INTERNAL_103" : "3",
        "SettingId.INTERNAL_105" : "0",
        "SettingId.VIDEO_ASPECT_RATIO" : "VideoAspectRatio.RATIO_4_3",
        "SettingId.INTERNAL_111" : "0",
        "SettingId.INTERNAL_112" : "255",
        "SettingId.INTERNAL_114" : "1",
        "SettingId.INTERNAL_115" : "0",
        "SettingId.INTERNAL_116" : "2",
        "SettingId.INTERNAL_117" : "2",
        "SettingId.INTERNAL_118" : "4",
        "SettingId.VIDEO_FOV" : "VideoFOV.WIDE",
        "SettingId.PHOTO_FOV" : "PhotoFOV.WIDE",
        "SettingId.MULTI_SHOT_FOV" : "MultishotFOV.WIDE",
        "SettingId.PHOTO_OUTPUT" : "PhotoOutput.RAW",
        "SettingId.INTERNAL_126" : "0",
        "SettingId.MEDIA_FORMAT" : "MediaFormat.TIME_LAPSE_VIDEO",
        "SettingId.INTERNAL_129" : "2",
        "SettingId.INTERNAL_130" : "33",
        "SettingId.INTERNAL_131" : "20",
        "SettingId.INTERNAL_132" : "0",
        "SettingId.ANTI_FLICKER" : "AntiFlicker.HZ_50",
        "SettingId.HYPERSMOOTH" : "HypersmoothMode.OFF",
        "SettingId.INTERNAL_139" : "3",
        "SettingId.INTERNAL_144" : "18",
        "SettingId.INTERNAL_145" : "0",
        "SettingId.INTERNAL_146" : "0",
        "SettingId.INTERNAL_147" : "0",
        "SettingId.INTERNAL_148" : "0",
        "SettingId.INTERNAL_149" : "2",
        "SettingId.INTERNAL_153" : "100",
        "SettingId.INTERNAL_154" : "2",
        "SettingId.INTERNAL_156" : "100",
        "SettingId.INTERNAL_157" : "100",
        "SettingId.INTERNAL_158" : "1",
        "SettingId.INTERNAL_159" : "1",
        "SettingId.INTERNAL_160" : "0",
        "SettingId.INTERNAL_161" : "100",
        "SettingId.INTERNAL_164" : "100",
        "SettingId.INTERNAL_165" : "0",
        "SettingId.INTERNAL_166" : "0",
        "SettingId.HINDSIGHT" : "Hindsight.OFF",
        "SettingId.INTERNAL_168" : "0",
        "SettingId.INTERNAL_169" : "1",
        "SettingId.PHOTO_INTERVAL" : "PhotoInterval.OFF",
        "SettingId.PHOTO_INTERVAL_DURATION" : "PhotoDuration.OFF",
        "SettingId.CAMERA_UX_MODE" : "CameraUxMode.PRO",
        "SettingId.VIDEO_EASY_MODE" : "10",
        "SettingId.WIFI_BAND" : "WifiBand.BAND_5_GHZ",
        "SettingId.STAR_TRAIL_LENGTH" : "StarTrailLength.MAX",
        "SettingId.BIT_RATE" : "BitRate.STANDARD",
        "SettingId.BIT_DEPTH" : "BitDepth.BIT_8",
        "SettingId.VIDEO_PROFILE" : "VideoProfile.STANDARD",
        "SettingId.VIDEO_MODE" : "VideoMode.HIGHEST",
        "SettingId.TIMELAPSE_MODE" : "TimelapseMode.TIMEWARP",
        "SettingId.ADDON_MAX_LENS_MOD" : "MaxLensModType.NONE",
        "SettingId.ADDON_MAX_LENS_MOD_ENABLE" : "Toggle.DISABLE",
        "SettingId.PHOTO_MODE" : "PhotoMode.SUPER",
        "SettingId.MULTI_SHOT_NLV_ASPECT_RATIO" : "EasyAspectRatio.WIDESCREEN",
        "SettingId.FRAMING" : "Framing.WIDESCREEN",
    },
}

撮影モード(静止画、動画、タイムラプス)の取得

撮影モード(静止画、動画、タイムラプス)はプリセット/プリセットグループ機能を利用して設定する。
https://gopro.github.io/OpenGoPro/http#tag/Presets/operation/OGP_PRESET_SET_GROUP
プリセットはプリセットグループに分かれて定義され、プリセットグループにはVIDEO_PRESETS, PHOTO_PRESETS, TIMELAPSE_PRESETS がある。ナイトフォトモードはPHOTO_PRESETSプリセットグループの一つとして登録されている。
現在のプリセット(番号)は以下のように取得できるので、この番号をstateから探すと現在のモードがわかる。

active_preset_id = state.data.get(constants.StatusId.ACTIVE_PRESET)
print(f"active_preset_id: {active_preset_id}")

video_preset_id = state.data.get(constants.StatusId.VIDEO_PRESETS)
photo_preset_id = state.data.get(constants.StatusId.PHOTO_PRESETS)
timelapse_preset_id = state.data.get(constants.StatusId.TIMELAPSE_PRESETS)

# 現在のプリセットを取得
if active_preset_id == video_preset_id:
    print("VIDEO mode")
elif active_preset_id == photo_preset_id:
    print("PHOTO mode")
elif active_preset_id == timelapse_preset_id:
    print("TIMELAPSE mode")
else:
    print("Unknown mode")
出力
active_preset_id: 65539
PHOTO mode

全てのプリセット情報は以下のように得られる。

preset_status= await gopro.http_command.get_preset_status()
print(preset_status)
出力
{
    "id" : "http://172.2X.1YZ.51:8080/gopro/camera/info",
    "status" : "ErrorCode.SUCCESS",
    "protocol" : "Protocol.HTTP",
    "data" : {
        "presetGroupArray" : [
            {
                "id" : "PRESET_GROUP_ID_VIDEO",
                "presetArray" : [
                    {
                        "id" : "6",
                        "mode" : "FLAT_MODE_VIDEO",
                        "titleId" : "PRESET_TITLE_CUSTOM",
                        "userDefined" : "True",
                        "icon" : "PRESET_ICON_CUSTOM",
                        "settingArray" : [
                            {
                                "id" : "2",
                                "value" : "105",
                                "isCaption" : "True",
                            }, {
                                "id" : "3",
                                "value" : "6",
                                "isCaption" : "True",
                            }, {
                                "id" : "121",
                                "value" : "10",
                                "isCaption" : "True",
                            }
                        ],
                        "isModified" : "False",
                    }, {
                        "id" : "0",
                        "mode" : "FLAT_MODE_VIDEO",
                        "titleId" : "PRESET_TITLE_VIDEO",
                        "userDefined" : "False",
                        "icon" : "PRESET_ICON_VIDEO",
                        "settingArray" : [
                            {
                                "id" : "2",
                                "value" : "28",
                                "isCaption" : "True",
                            }, {
                                "id" : "3",
                                "value" : "6",
                                "isCaption" : "True",
                            }, {
                                "id" : "121",
                                "value" : "0",
                                "isCaption" : "True",
                            }
                        ],
                        "isModified" : "True",
                    }
                ],
                "canAddPreset" : "True",
                "icon" : "PRESET_GROUP_VIDEO_ICON_ID",
            }, {
                "id" : "PRESET_GROUP_ID_PHOTO",
                "presetArray" : [
                    {
                        "id" : "65542",
                        "mode" : "FLAT_MODE_PHOTO_NIGHT",
                        "titleId" : "PRESET_TITLE_CUSTOM",
                        "userDefined" : "True",
                        "icon" : "PRESET_ICON_CUSTOM",
                        "settingArray" : [
                            {
                                "id" : "125",
                                "value" : "1",
                                "isCaption" : "True",
                            }, {
                                "id" : "19",
                                "value" : "0",
                                "isCaption" : "True",
                            }, {
                                "id" : "122",
                                "value" : "101",
                                "isCaption" : "True",
                            }
                        ],
                        "isModified" : "False",
                    }, {
                        "id" : "65536",
                        "mode" : "FLAT_MODE_PHOTO_SINGLE",
                        "titleId" : "PRESET_TITLE_PHOTO",
                        "userDefined" : "False",
                        "icon" : "PRESET_ICON_PHOTO",
                        "settingArray" : [
                            {
                                "id" : "125",
                                "value" : "1",
                                "isCaption" : "True",
                            }, {
                                "id" : "122",
                                "value" : "101",
                                "isCaption" : "True",
                            }
                        ],
                        "isModified" : "True",
                    }, {
                        "id" : "65538",
                        "mode" : "FLAT_MODE_PHOTO_BURST",
                        "titleId" : "PRESET_TITLE_BURST",
                        "userDefined" : "False",
                        "icon" : "PRESET_ICON_BURST",
                        "settingArray" : [
                            {
                                "id" : "126",
                                "value" : "0",
                                "isCaption" : "True",
                            }, {
                                "id" : "147",
                                "value" : "9",
                                "isCaption" : "True",
                            }, {
                                "id" : "123",
                                "value" : "101",
                                "isCaption" : "True",
                            }
                        ],
                        "isModified" : "False",
                    }, {
                        "id" : "65539",
                        "mode" : "FLAT_MODE_PHOTO_NIGHT",
                        "titleId" : "PRESET_TITLE_NIGHT",
                        "userDefined" : "False",
                        "icon" : "PRESET_ICON_PHOTO_NIGHT",
                        "settingArray" : [
                            {
                                "id" : "125",
                                "value" : "1",
                                "isCaption" : "True",
                            }, {
                                "id" : "19",
                                "value" : "0",
                                "isCaption" : "True",
                            }, {
                                "id" : "122",
                                "value" : "101",
                                "isCaption" : "True",
                            }
                        ],
                        "isModified" : "True",
                    }
                ],
                "canAddPreset" : "True",
                "icon" : "PRESET_GROUP_PHOTO_ICON_ID",
            }, {
                "id" : "PRESET_GROUP_ID_TIMELAPSE",
                "presetArray" : [
                    {
                        "id" : "131072",
                        "mode" : "FLAT_MODE_TIME_WARP_VIDEO",
                        "titleId" : "PRESET_TITLE_TIME_WARP",
                        "userDefined" : "False",
                        "icon" : "PRESET_ICON_TIMEWARP",
                        "settingArray" : [
                            {
                                "id" : "2",
                                "value" : "102",
                                "isCaption" : "True",
                            }, {
                                "id" : "111",
                                "value" : "10",
                                "isCaption" : "True",
                            }, {
                                "id" : "121",
                                "value" : "0",
                                "isCaption" : "True",
                            }
                        ],
                        "isModified" : "False",
                    }, {
                        "id" : "131075",
                        "mode" : "FLAT_MODE_VIDEO_STAR_TRAIL",
                        "titleId" : "PRESET_TITLE_STAR_TRAIL",
                        "userDefined" : "False",
                        "icon" : "PRESET_ICON_STAR_TRAIL",
                        "settingArray" : [
                            {
                                "id" : "2",
                                "value" : "102",
                                "isCaption" : "True",
                            }, {
                                "id" : "32",
                                "value" : "3601",
                                "isCaption" : "True",
                            }, {
                                "id" : "121",
                                "value" : "0",
                                "isCaption" : "True",
                            }
                        ],
                        "isModified" : "False",
                    }, {
                        "id" : "131076",
                        "mode" : "FLAT_MODE_VIDEO_LIGHT_PAINTING",
                        "titleId" : "PRESET_TITLE_LIGHT_PAINTING",
                        "userDefined" : "False",
                        "icon" : "PRESET_ICON_LIGHT_PAINTING",
                        "settingArray" : [
                            {
                                "id" : "2",
                                "value" : "102",
                                "isCaption" : "True",
                            }, {
                                "id" : "32",
                                "value" : "3601",
                                "isCaption" : "True",
                            }, {
                                "id" : "121",
                                "value" : "0",
                                "isCaption" : "True",
                            }
                        ],
                        "isModified" : "False",
                    }, {
                        "id" : "131077",
                        "mode" : "FLAT_MODE_VIDEO_LIGHT_TRAIL",
                        "titleId" : "PRESET_TITLE_LIGHT_TRAIL",
                        "userDefined" : "False",
                        "icon" : "PRESET_ICON_LIGHT_TRAIL",
                        "settingArray" : [
                            {
                                "id" : "2",
                                "value" : "102",
                                "isCaption" : "True",
                            }, {
                                "id" : "32",
                                "value" : "3601",
                                "isCaption" : "True",
                            }, {
                                "id" : "121",
                                "value" : "0",
                                "isCaption" : "True",
                            }
                        ],
                        "isModified" : "False",
                    }, {
                        "id" : "131073",
                        "mode" : "FLAT_MODE_TIME_LAPSE_VIDEO",
                        "titleId" : "PRESET_TITLE_TIME_LAPSE",
                        "userDefined" : "False",
                        "icon" : "PRESET_ICON_TIMELAPSE",
                        "settingArray" : [
                            {
                                "id" : "2",
                                "value" : "102",
                                "isCaption" : "True",
                            }, {
                                "id" : "5",
                                "value" : "0",
                                "isCaption" : "True",
                            }, {
                                "id" : "121",
                                "value" : "0",
                                "isCaption" : "True",
                            }
                        ],
                        "isModified" : "False",
                    }, {
                        "id" : "131074",
                        "mode" : "FLAT_MODE_NIGHT_LAPSE_VIDEO",
                        "titleId" : "PRESET_TITLE_NIGHT_LAPSE",
                        "userDefined" : "False",
                        "icon" : "PRESET_ICON_NIGHTLAPSE",
                        "settingArray" : [
                            {
                                "id" : "2",
                                "value" : "102",
                                "isCaption" : "True",
                            }, {
                                "id" : "32",
                                "value" : "3601",
                                "isCaption" : "True",
                            }, {
                                "id" : "121",
                                "value" : "0",
                                "isCaption" : "True",
                            }
                        ],
                        "isModified" : "False",
                    }
                ],
                "canAddPreset" : "True",
                "icon" : "PRESET_GROUP_TIMELAPSE_ICON_ID",
            }
        ],
    },
}

preset_statusから現在のプリセットidの情報を取得する。

presets = preset_status.data.get("presetGroupArray")
for i, preset_group in enumerate(presets):
    for j, preset in enumerate(preset_group.get("presetArray")):
        if preset.get("id") == active_preset_id:
            print(f"preset_group: {i}, preset: {j}")
            print(preset)
出力
preset_group: 1, preset: 3
{'id': 65539, 'mode': 'FLAT_MODE_PHOTO_NIGHT', 'titleId': 'PRESET_TITLE_NIGHT', 'userDefined': False, 'icon': 'PRESET_ICON_PHOTO_NIGHT', 'settingArray': [{'id': 125, 'value': 1, 'isCaption': True}, {'id': 19, 'value': 0, 'isCaption': True}, {'id': 122, 'value': 101, 'isCaption': True}], 'isModified': True}

撮影モードの設定

ナイトフォトのプリセットidを取得し、設定する。

ナイトフォトのプリセットidを取得する

上記のget_preset_statusから、ナイトフォトのプリセットのIDを探し出す。
"titleId" : "PRESET_TITLE_NIGHT"
のidを見つける。

presets = preset_status.data.get("presetGroupArray")
for i, preset_group in enumerate(presets):
    for j, preset in enumerate(preset_group.get("presetArray")):
        if preset.get("titleId") == "PRESET_TITLE_NIGHT":
            night_preset_id = preset.get("id")
            print(f"PRESET_TITLE_NIGHT id: {night_preset_id}")
出力
PRESET_TITLE_NIGHT id: 65539

ナイトフォトに設定する

preset = await gopro.http_command.load_preset(preset=night_preset_id)
print(preset)
出力
{
    "id" : "http://172.2X.1YZ.51:8080/gopro/camera/presets/load?id=65539",
    "status" : "ErrorCode.SUCCESS",
    "protocol" : "Protocol.HTTP",
}

(参考)撮影モード(プリセットグループ)を変更する

プリセットグループを変更することで、グループ内で最後に設定されたプリセットが利用される様子。ナイトフォトに設定したあと、動画モードにし、再度、静止画モードにすると、ナイトフォトモードになる。

preset = await gopro.http_command.load_preset_group(group=Params.PresetGroup.VIDEO)
print(f"動画モード設定: {preset}")
preset = await gopro.http_command.load_preset_group(group=Params.PresetGroup.PHOTO)
print(f"静止画モード設定: {preset}")
出力
動画モード設定: {
    "id" : "http://172.2X.1YZ.51:8080/gopro/camera/presets/set_group?id=1000",
    "status" : "ErrorCode.SUCCESS",
    "protocol" : "Protocol.HTTP",
}
静止画モード設定: {
    "id" : "http://172.2X.1YZ.51:8080/gopro/camera/presets/set_group?id=1001",
    "status" : "ErrorCode.SUCCESS",
    "protocol" : "Protocol.HTTP",
}

撮影設定

RAW撮影の設定にはhttp_settingを用いることができるが、最大ISO感度などINTERNALな設定は直接WebAPIを呼び出して設定する。

  • RAW撮影

  • ISO最小: 100

  • ISO最大: 100

  • シャープネス: 低
    最大ISO感度、最小ISO感度の設定が不明なため、試してみたところ、
    SettingId.INTERNAL_75がISO最小、
    SettingId.INTERNAL_24がISO最大、
    に相当する様子。IDとISO感度の関係は以下の通り。

    ID ISO感度
    3 ISO100
    2 ISO200
    1 ISO400
    0 ISO800

    シャープネスはSettingId.INTERNAL_117に相当する様子。

    ID シャープネス
    2
    1
    0
import requests
url = "http://172.2X.1YZ.51:8080/gopro/camera/setting"

# RAW撮影設定
result = await gopro.http_setting.photo_output.set(Params.PhotoOutput.RAW)
print(f"RAW撮影設定: {result}")

# ISO最小設定 (ISO 100)
querystring = {"option":"3","setting":"75"}
response = requests.request("GET", url, params=querystring)
print("Status Code:", response.status_code)
print(f"ISO最小設定: {response.text}")

# ISO最大設定 (ISO 100)
querystring = {"option":"3","setting":"24"}
response = requests.request("GET", url, params=querystring)
print("Status Code:", response.status_code)
print(f"ISO最大設定: {response.text}")

# シャープネス設定 (LOW)
querystring = {"option":"2","setting":"117"}
response = requests.request("GET", url, params=querystring)
print("Status Code:", response.status_code)
print(f"シャープネス設定: {response.text}")
出力
RAW撮影設定: {
    "id" : "SettingId.PHOTO_OUTPUT",
    "status" : "ErrorCode.SUCCESS",
    "protocol" : "Protocol.HTTP",
}
Status Code: 200
ISO最小設定: {}

Status Code: 200
ISO最大設定: {}

Status Code: 200
シャープネス設定: {}

撮影

撮影はシャッターボタンをON/OFFすることで行う。

await gopro.http_command.set_shutter(shutter=Params.Toggle.ENABLE)
await gopro.http_command.set_shutter(shutter=Params.Toggle.DISABLE)

撮影画像の取得

画像のファイルパスを取得

最後の撮影画像は get_last_captured_media で取得できそうに思ったが、エラーとなって動作しないので、手動で探すことにした。open_gopro ver.0.16.2の問題かもしれないので、将来は動作するかもしれない。

medias = await gopro.http_command.get_media_list()
# print(medias)

if medias.data is None or medias.data.media is len(medias.data.media) == 0 or medias.data.media[0].file_system is None:
    print("No media found.")
    exit()

file_list = []
for media in medias.data.media:
    # print(media)
    for file in media.file_system:
        # print(file)
        file_list.append(file)

# creation_timestampでソート
sorted_media = sorted(file_list, key=lambda x: int(x.creation_timestamp), reverse=True)

# 最新のファイルを取得
latest_file = sorted_media[0]

# 最新のファイル名を出力
print("Latest file:", latest_file.filename)
出力
Latest file: 100GOPRO/GOPR0569.JPG

画像のダウンロード

今回はRAW(.GPR)を取得したいが、上記の方法ではJPGしかリストアップされないため、拡張子をJPGからGPRに変更して取得する。

import pathlib

# GPRファイルパス
latest_gpr = latest_file.filename.split(".")[0] + ".GPR"
print("Downloading:", latest_gpr)

# ダウンロード先のパス
local_path = pathlib.Path(os.path.join(os.getcwd(), latest_gpr))
os.makedirs(local_path.parent, exist_ok=True)

download_file = await gopro.http_command.download_file(camera_file=latest_gpr, local_file=local_path)
print(download_file)
出力
Downloading: 100GOPRO/GOPR0569.GPR
{
    "id" : "http://172.2X.1YZ.51:8080/videos/DCIM/100GOPRO/GOPR0569.GPR",
    "status" : "ErrorCode.SUCCESS",
    "protocol" : "Protocol.HTTP",
    "data" : "/Users/xxx/gopro-test/100GOPRO/GOPR0569.GPR",
}

RAW現像

RAW(.GPR)ファイルを直接現像できなかったので、Adobe DNG ConverterでDNGに変換してから、rawpyで現像する。ここで、現像設定はデフォルトのまま。

GPR -> DNG -> PNG

import rawpy
import cv2
import os

def gpr2png(gprPath, pngPath):
    # dir path
    dstDir = os.path.dirname(pngPath)
    if not os.path.exists(dstDir):
        os.makedirs(dstDir)

    gprFullPath = os.path.abspath(gprPath)
    gprBaseName = os.path.basename(gprPath)
    dstDirFullPath = os.path.abspath(dstDir)

    # gpr to dng
    dngConverter = 'C:/Program Files/Adobe/Adobe DNG Converter/DNGConverter.exe'
    if os.name == 'posix':
        # macOSの場合は以下のパスを使用
        dngConverter = '/Applications/Adobe DNG Converter.app/Contents/MacOS/Adobe DNG Converter'
    os.system(f'"{dngConverter}" {gprFullPath} -d {dstDirFullPath}')
    dngFullPath = os.path.join(dstDirFullPath, gprBaseName.replace('.GPR', '.dng'))

    # dng to png
    with rawpy.imread(dngFullPath) as raw:
        img = raw.postprocess()
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        cv2.imwrite(pngPath, img)
        print(f"Saved: {pngPath}")
        os.remove(dngFullPath)

# gpr to png
gprPath = local_path
pngPath = local_path.with_suffix('.png')
gpr2png(gprPath, pngPath)
出力
*** GPU Warning: GPU3 disabled via cr_config at init time. ***
Saved: /Users/xxx/gopro-test/100GOPRO/GOPR0569.png

まとめ

OpenGoProとそのPython SDKを使って、MacBookProとUSB接続したGoPro HERO12を制御し、RAW撮影する方法を示した。また、撮影したRAW(.GPR)ファイルを現像してPNGを取得する方法を示した。
特にOpenGoPro Python SDKはエラーや未実装が散見され、まだ完成度はそれほど高くないように思う。しかし、NCMに対応し、USBでもWifiでも同様にhttp接続できるため、Python SDKがなくてもさほど困らないかもしれない。

参考

  1. https://gopro.github.io/OpenGoPro/python_sdk/index.html
  2. https://gopro.github.io/OpenGoPro/http
0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2