Skip to content

Commit

Permalink
Live tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Konrad Iturbe committed Jul 7, 2019
1 parent 0fcd8c9 commit e283a8f
Show file tree
Hide file tree
Showing 9 changed files with 245 additions and 58 deletions.
43 changes: 43 additions & 0 deletions examples/extract_clips.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import time
import numpy as np
from goprocam import GoProCamera, constants
gpCam = GoProCamera.GoPro()

# Extracts clips from latest video

latestVideo = gpCam.getVideoInfo()
print("Tag count %s" % latestVideo.get(constants.Info.TagCount))
arrayLength = latestVideo[constants.Info.TagCount]
if arrayLength % 2 == 0:
print("Matching tag pairs!")
splitArray = np.array_split(
latestVideo[constants.Info.Tags], arrayLength/2)
for tag in splitArray:
startMs = tag[0]
stopMs = tag[1]
print("\n[START ms] %s\n[STOP ms] %s" %
(startMs, stopMs))
fileName = "%s/%s" % (gpCam.getMediaInfo("folder"),
gpCam.getMediaInfo("file"))
videoId = gpCam.getClip(fileName, constants.Clip.R1080p,
constants.Clip.FPS_NORMAL, str(startMs), str(stopMs))
print("On queue!\nVideo Id: %s\nStatus: %s" %
(videoId, gpCam.clipStatus(str(videoId))))
time.sleep(1)
while(gpCam.clipStatus(str(videoId)) != "complete"):
time.sleep(1)
time.sleep(2)
print("Downloading!\nVideo Id: %s\nStatus: %s" %
(videoId, gpCam.clipStatus(str(videoId))))
url = gpCam.getClipURL(str(videoId))
download = [
url.split("/")[len(url.split("/"))-1],
url.split("/")[len(url.split("/"))-2]]
print("Downloading %s" % download)
try:
gpCam.downloadLastMedia(
path=url, custom_filename="output/%s_%s_%s" % (startMs, stopMs, download[0].replace("TRV", "MP4")))
except(Exception) as e:
time.sleep(2)
gpCam.downloadLastMedia(
path=url, custom_filename="output/%s_%s_%s" % (startMs, stopMs, download[0].replace("TRV", "MP4")))
119 changes: 61 additions & 58 deletions goprocam/GoProCamera.py
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ def infoCamera(self, option=""):
def shutter(self, param):
"""Starts/stop video or timelapse recording, pass constants.start or constants.stop as value in param"""
if self.whichCam() == constants.Camera.Interface.GPControl:
print(self.gpControlCommand("shutter?p=" + param))
return self.gpControlCommand("shutter?p=" + param)
else:
if len(param) == 1:
param = "0" + param
Expand All @@ -331,8 +331,8 @@ def shutter(self, param):
def mode(self, mode, submode="0"):
"""Changes mode of the camera. See constants.Mode and constants.Mode.SubMode for sub-modes."""
if self.whichCam() == constants.Camera.Interface.GPControl:
print(self.gpControlCommand(
"sub_mode?mode=" + mode + "&sub_mode=" + submode))
return self.gpControlCommand(
"sub_mode?mode=" + mode + "&sub_mode=" + submode)
else:
if len(mode) == 1:
mode = "0" + mode
Expand All @@ -344,49 +344,49 @@ def delete(self, option):
# This allows you to delete x number of files backwards. Will delete a timelapse/burst entirely as its interpreted as a single file.
if isinstance(option, int):
for _ in range(option):
print(self.gpControlCommand("storage/delete/" + "last"))
return self.gpControlCommand("storage/delete/" + "last")
else:
print(self.gpControlCommand("storage/delete/" + option))
return self.gpControlCommand("storage/delete/" + option)
else:
if isinstance(option, int) == True:
for _ in range(option):
print(self.sendCamera("DL"))
return self.sendCamera("DL")
else:
if option == "last":
print(self.sendCamera("DL"))
return self.sendCamera("DL")
if option == "all":
print(self.sendCamera("DA"))
return self.sendCamera("DA")

def deleteFile(self, folder, file):
"""Deletes a file. Pass folder and file as parameters."""
if folder.startswith("http://" + self.ip_addr):
folder, file = self.getInfoFromURL(folder)
if self.whichCam() == constants.Camera.Interface.GPControl:
print(self.gpControlCommand(
"storage/delete?p=" + folder + "/" + file))
return self.gpControlCommand(
"storage/delete?p=" + folder + "/" + file)
else:
print(self.sendCamera("DF", "/"+folder+"/"+file))
return self.sendCamera("DF", "/"+folder+"/"+file)

def locate(self, param):
"""Starts or stops locating (beeps camera)"""
if self.whichCam() == constants.Camera.Interface.GPControl:
print(self.gpControlCommand("system/locate?p=" + param))
return self.gpControlCommand("system/locate?p=" + param)
else:
print(self.sendCamera("LL", "0"+param))
return self.sendCamera("LL", "0"+param)

def hilight(self):
"""Tags a hilight in the video"""
if self.whichCam() == constants.Camera.Interface.GPControl:
print(self.gpControlCommand("storage/tag_moment"))
return self.gpControlCommand("storage/tag_moment")
else:
print("Not supported.")

def power_off(self):
"""Sends power off command"""
if self.whichCam() == constants.Camera.Interface.GPControl:
print(self.gpControlCommand("system/sleep"))
return self.gpControlCommand("system/sleep")
else:
print(self.sendBacpac("PW", "00"))
return self.sendBacpac("PW", "00")

def power_on(self, _mac_address=""):
"""Sends power on command. Mac address might need to be defined"""
Expand Down Expand Up @@ -440,51 +440,51 @@ def pair(self, usepin=True):

def power_on_auth(self):
"""Sends power on command to Hero 3/3+ cameras"""
print(self.sendBacpac("PW", "01"))
return self.sendBacpac("PW", "01")

def video_settings(self, res, fps="none"):
"""Change video resolution and FPS
See constants.Video.Resolution"""
if self.whichCam() == constants.Camera.Interface.GPControl:
x = "constants.Video.Resolution.R" + res
videoRes = eval(x)
print(self.gpControlSet(constants.Video.RESOLUTION, videoRes))
return self.gpControlSet(constants.Video.RESOLUTION, videoRes)
if fps != "none":
x = "constants.Video.FrameRate.FR" + fps
videoFps = eval(x)
print(self.gpControlSet(constants.Video.FRAME_RATE, videoFps))
return self.gpControlSet(constants.Video.FRAME_RATE, videoFps)
elif self.whichCam() == constants.Camera.Interface.Auth:
if res == "4k":
print(self.sendCamera(
constants.Hero3Commands.VIDEO_RESOLUTION, "06"))
return self.sendCamera(
constants.Hero3Commands.VIDEO_RESOLUTION, "06")
elif res == "4K_Widescreen":
print(self.sendCamera(
constants.Hero3Commands.VIDEO_RESOLUTION, "08"))
return self.sendCamera(
constants.Hero3Commands.VIDEO_RESOLUTION, "08")
elif res == "2kCin":
print(self.sendCamera(
constants.Hero3Commands.VIDEO_RESOLUTION, "07"))
return self.sendCamera(
constants.Hero3Commands.VIDEO_RESOLUTION, "07")
elif res == "2_7k":
print(self.sendCamera(
constants.Hero3Commands.VIDEO_RESOLUTION, "05"))
return self.sendCamera(
constants.Hero3Commands.VIDEO_RESOLUTION, "05")
elif res == "1440p":
print(self.sendCamera(
constants.Hero3Commands.VIDEO_RESOLUTION, "04"))
return self.sendCamera(
constants.Hero3Commands.VIDEO_RESOLUTION, "04")
elif res == "1080p":
print(self.sendCamera(
constants.Hero3Commands.VIDEO_RESOLUTION, "03"))
return self.sendCamera(
constants.Hero3Commands.VIDEO_RESOLUTION, "03")
elif res == "960p":
print(self.sendCamera(
constants.Hero3Commands.VIDEO_RESOLUTION, "02"))
return self.sendCamera(
constants.Hero3Commands.VIDEO_RESOLUTION, "02")
elif res == "720p":
print(self.sendCamera(
constants.Hero3Commands.VIDEO_RESOLUTION, "01"))
return self.sendCamera(
constants.Hero3Commands.VIDEO_RESOLUTION, "01")
elif res == "480p":
print(self.sendCamera(
constants.Hero3Commands.VIDEO_RESOLUTION, "00"))
return self.sendCamera(
constants.Hero3Commands.VIDEO_RESOLUTION, "00")
if fps != "none":
x = "constants.Hero3Commands.FrameRate.FPS" + fps
videoFps = eval(x)
print(self.sendCamera(constants.Hero3Commands.FRAME_RATE, videoFps))
return self.sendCamera(constants.Hero3Commands.FRAME_RATE, videoFps)

def take_photo(self, timer=1):
"""Takes a photo. Set timer to an integer to set a wait time"""
Expand Down Expand Up @@ -546,18 +546,18 @@ def syncTime(self):
datestr = str("%" + str(datestr_year)+"%"+str(datestr_month)+"%"+str(
datestr_day)+"%"+str(datestr_hour)+"%"+str(datestr_min)+"%"+str(datestr_sec))
if self.whichCam() == constants.Camera.Interface.GPControl:
print(self.gpControlCommand("setup/date_time?p=" + datestr))
return self.gpControlCommand("setup/date_time?p=" + datestr)
else:
print(self.sendCamera("TM", datestr))
return self.sendCamera("TM", datestr)

def reset(self, r):
"""Resets video/photo/multishot protune values"""
self.gpControlCommand(r + "/protune/reset")
return self.gpControlCommand(r + "/protune/reset")

def setZoom(self, zoomLevel):
"""Sets camera zoom (Hero6/Hero7), zoomLevel is an integer"""
if zoomLevel >= 0 and zoomLevel <= 100:
self.gpControlCommand("digital_zoom?range_pcnt=" + str(zoomLevel))
return self.gpControlCommand("digital_zoom?range_pcnt=" + str(zoomLevel))

def getMedia(self):
"""Returns last media URL"""
Expand All @@ -574,7 +574,7 @@ def getMedia(self):
for i in json_parse["media"]:
for i2 in i["fs"]:
file_lo = i2["n"]
return "http://" + self.ip_addr + "videos/DCIM/" + folder + "/" + file_lo
return "http://" + self.ip_addr + "/videos/DCIM/" + folder + "/" + file_lo
except (HTTPError, URLError) as error:
return ""
except timeout:
Expand Down Expand Up @@ -603,7 +603,7 @@ def getMediaFusion(self):
for mediaitem2 in mediaitem["fs"]:
file_2 = mediaitem2["n"]

return ["http://" + self.ip_addr + "videos/DCIM/" + folder_1 + "/" + file_1, "http://" + self.ip_addr + "videos2/DCIM/" + folder_2 + "/" + file_2]
return ["http://" + self.ip_addr + "/videos/DCIM/" + folder_1 + "/" + file_1, "http://" + self.ip_addr + "/videos2/DCIM/" + folder_2 + "/" + file_2]
except (HTTPError, URLError) as error:
return ""
except timeout:
Expand Down Expand Up @@ -740,9 +740,9 @@ def getInfoFromURL(self, url):
"""Gets information from Media URL."""
media = []
media.append(url.replace("http://" + self.ip_addr +
"videos/DCIM/", "").replace("/", "-").rsplit("-", 1)[0])
"/videos/DCIM/", "").replace("/", "-").rsplit("-", 1)[0])
media.append(url.replace("http://" + self.ip_addr +
"videos/DCIM/", "").replace("/", "-").rsplit("-", 1)[1])
"/videos/DCIM/", "").replace("/", "-").rsplit("-", 1)[1])
return media

##
Expand Down Expand Up @@ -857,9 +857,9 @@ def downloadMedia(self, folder, file, custom_filename=""):
if "FS" in self.infoCamera(constants.Camera.Firmware):
if "GFRNT" in folder:
urllib.request.urlretrieve(
"http://" + self.ip_addr + "videos2/DCIM/" + folder + "/" + file, filename)
"http://" + self.ip_addr + "/videos2/DCIM/" + folder + "/" + file, filename)
urllib.request.urlretrieve(
"http://" + self.ip_addr + "videos/DCIM/" + folder + "/" + file, filename)
"http://" + self.ip_addr + "/videos/DCIM/" + folder + "/" + file, filename)
except (HTTPError, URLError) as error:
print("ERROR: " + str(error))
else:
Expand All @@ -879,9 +879,9 @@ def downloadRawPhoto(self, folder, file, custom_filename=""):
if "FS" in self.infoCamera(constants.Camera.Firmware):
if "GFRNT" in folder:
urllib.request.urlretrieve(
"http://" + self.ip_addr + "videos2/DCIM/" + folder + "/" + file, filename)
"http://" + self.ip_addr + "/videos2/DCIM/" + folder + "/" + file, filename)
urllib.request.urlretrieve(
"http://" + self.ip_addr + "videos/DCIM/" + folder + "/" + file, filename)
"http://" + self.ip_addr + "/videos/DCIM/" + folder + "/" + file, filename)
except (HTTPError, URLError) as error:
print("ERROR: " + str(error))
else:
Expand Down Expand Up @@ -996,7 +996,7 @@ def downloadLowRes(self, path="", custom_filename=""):
if "GH" in lowres_url:
lowres_url = lowres_url.replace("GH", "GL")
lowres_filename = "LOWRES"+path.replace("MP4", "LRV").replace(
"http://" + self.ip_addr + "videos/DCIM/", "").replace("/", "-")
"http://" + self.ip_addr + "/videos/DCIM/", "").replace("/", "-")
else:
print("not supported")
print("filename: " + lowres_filename)
Expand All @@ -1023,7 +1023,7 @@ def getVideoInfo(self, option="", folder="", file=""):
if option == "":
if folder == "" and file == "":
if self.getMediaInfo("file").endswith("MP4"):
return self._request("gp/gpMediaMetadata?p=" + self.getMediaInfo("folder") + "/" + self.getMediaInfo("file") + "&t=videoinfo")
return json.loads(self._request("gp/gpMediaMetadata?p=" + self.getMediaInfo("folder") + "/" + self.getMediaInfo("file") + "&t=videoinfo"))
else:
data = ""
if folder == "" and file == "":
Expand Down Expand Up @@ -1137,15 +1137,15 @@ def livestream(self, option):
"""
if option == "start":
if self.whichCam() == constants.Camera.Interface.GPControl:
print(self.gpControlExecute(
"p1=gpStream&a1=proto_v2&c1=restart"))
return self.gpControlExecute(
"p1=gpStream&a1=proto_v2&c1=restart")
else:
print(self.sendCamera("PV", "02"))
return self.sendCamera("PV", "02")
if option == "stop":
if self.whichCam() == constants.Camera.Interface.GPControl:
print(self.gpControlExecute("p1=gpStream&a1=proto_v2&c1=stop"))
return self.gpControlExecute("p1=gpStream&a1=proto_v2&c1=stop")
else:
print(self.sendCamera("PV", "00"))
return self.sendCamera("PV", "00")

def stream(self, addr, quality=""):
"""Starts a FFmpeg instance for streaming to an address
Expand Down Expand Up @@ -1336,7 +1336,10 @@ def parse_value(self, param, value):
return "30s"
if value == "06":
return "1min"
if param == constants.Hero3Status.LED or param == constants.Hero3Status.Beep or param == constants.Hero3Status.SpotMeter or param == constants.Hero3Status.IsRecording:
if param == constants.Hero3Status.LED or \
param == constants.Hero3Status.Beep or \
param == constants.Hero3Status.SpotMeter or \
param == constants.Hero3Status.IsRecording:
if value == "00":
return "OFF"
if value == "01":
Expand Down
1 change: 1 addition & 0 deletions install_from_source.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
python setup.py install
60 changes: 60 additions & 0 deletions tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
### Testing:

Connect a fully-charged HERO5 Black with an SD card to your PC and run the tests.

python main.py


````
konrad@konrad-pc [tests (dev)]: python main.py
test_has_sd_card (__main__.MainTests) ... Needs an SD card
HERO5 Black
HD5.02.02.60.00
Camera successfully connected!
ok
test_photo_mode (__main__.MainTests) ... PHOTO MODE
HERO5 Black
HD5.02.02.60.00
Camera successfully connected!
ok
test_power_off (__main__.MainTests) ... POWER OFF
HERO5 Black
HD5.02.02.60.00
Camera successfully connected!
ok
test_power_on (__main__.MainTests) ... POWER ON
Waking up...
Waking up...
ok
test_recording_status (__main__.MainTests) ... isRecording
HERO5 Black
HD5.02.02.60.00
Camera successfully connected!
ok
test_shoot_video (__main__.MainTests) ... shoot_video(5)
HERO5 Black
HD5.02.02.60.00
Camera successfully connected!
ok
test_shutter (__main__.MainTests) ... SHUTTER START
HERO5 Black
HD5.02.02.60.00
Camera successfully connected!
ok
test_take_photo (__main__.MainTests) ... take_photo()
HERO5 Black
HD5.02.02.60.00
Camera successfully connected!
ok
test_video_mode (__main__.MainTests) ... VIDEO MODE
HERO5 Black
HD5.02.02.60.00
Camera successfully connected!
ok
----------------------------------------------------------------------
Ran 9 tests in 87.454s
OK
````

Empty file added tests/hero3.py
Empty file.
Loading

0 comments on commit e283a8f

Please sign in to comment.