Skip to content
This repository was archived by the owner on Mar 2, 2025. It is now read-only.

Commit e283a8f

Browse files
author
Konrad Iturbe
committed
Live tests
1 parent 0fcd8c9 commit e283a8f

File tree

9 files changed

+245
-58
lines changed

9 files changed

+245
-58
lines changed

examples/extract_clips.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import time
2+
import numpy as np
3+
from goprocam import GoProCamera, constants
4+
gpCam = GoProCamera.GoPro()
5+
6+
# Extracts clips from latest video
7+
8+
latestVideo = gpCam.getVideoInfo()
9+
print("Tag count %s" % latestVideo.get(constants.Info.TagCount))
10+
arrayLength = latestVideo[constants.Info.TagCount]
11+
if arrayLength % 2 == 0:
12+
print("Matching tag pairs!")
13+
splitArray = np.array_split(
14+
latestVideo[constants.Info.Tags], arrayLength/2)
15+
for tag in splitArray:
16+
startMs = tag[0]
17+
stopMs = tag[1]
18+
print("\n[START ms] %s\n[STOP ms] %s" %
19+
(startMs, stopMs))
20+
fileName = "%s/%s" % (gpCam.getMediaInfo("folder"),
21+
gpCam.getMediaInfo("file"))
22+
videoId = gpCam.getClip(fileName, constants.Clip.R1080p,
23+
constants.Clip.FPS_NORMAL, str(startMs), str(stopMs))
24+
print("On queue!\nVideo Id: %s\nStatus: %s" %
25+
(videoId, gpCam.clipStatus(str(videoId))))
26+
time.sleep(1)
27+
while(gpCam.clipStatus(str(videoId)) != "complete"):
28+
time.sleep(1)
29+
time.sleep(2)
30+
print("Downloading!\nVideo Id: %s\nStatus: %s" %
31+
(videoId, gpCam.clipStatus(str(videoId))))
32+
url = gpCam.getClipURL(str(videoId))
33+
download = [
34+
url.split("/")[len(url.split("/"))-1],
35+
url.split("/")[len(url.split("/"))-2]]
36+
print("Downloading %s" % download)
37+
try:
38+
gpCam.downloadLastMedia(
39+
path=url, custom_filename="output/%s_%s_%s" % (startMs, stopMs, download[0].replace("TRV", "MP4")))
40+
except(Exception) as e:
41+
time.sleep(2)
42+
gpCam.downloadLastMedia(
43+
path=url, custom_filename="output/%s_%s_%s" % (startMs, stopMs, download[0].replace("TRV", "MP4")))

goprocam/GoProCamera.py

Lines changed: 61 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ def infoCamera(self, option=""):
322322
def shutter(self, param):
323323
"""Starts/stop video or timelapse recording, pass constants.start or constants.stop as value in param"""
324324
if self.whichCam() == constants.Camera.Interface.GPControl:
325-
print(self.gpControlCommand("shutter?p=" + param))
325+
return self.gpControlCommand("shutter?p=" + param)
326326
else:
327327
if len(param) == 1:
328328
param = "0" + param
@@ -331,8 +331,8 @@ def shutter(self, param):
331331
def mode(self, mode, submode="0"):
332332
"""Changes mode of the camera. See constants.Mode and constants.Mode.SubMode for sub-modes."""
333333
if self.whichCam() == constants.Camera.Interface.GPControl:
334-
print(self.gpControlCommand(
335-
"sub_mode?mode=" + mode + "&sub_mode=" + submode))
334+
return self.gpControlCommand(
335+
"sub_mode?mode=" + mode + "&sub_mode=" + submode)
336336
else:
337337
if len(mode) == 1:
338338
mode = "0" + mode
@@ -344,49 +344,49 @@ def delete(self, option):
344344
# This allows you to delete x number of files backwards. Will delete a timelapse/burst entirely as its interpreted as a single file.
345345
if isinstance(option, int):
346346
for _ in range(option):
347-
print(self.gpControlCommand("storage/delete/" + "last"))
347+
return self.gpControlCommand("storage/delete/" + "last")
348348
else:
349-
print(self.gpControlCommand("storage/delete/" + option))
349+
return self.gpControlCommand("storage/delete/" + option)
350350
else:
351351
if isinstance(option, int) == True:
352352
for _ in range(option):
353-
print(self.sendCamera("DL"))
353+
return self.sendCamera("DL")
354354
else:
355355
if option == "last":
356-
print(self.sendCamera("DL"))
356+
return self.sendCamera("DL")
357357
if option == "all":
358-
print(self.sendCamera("DA"))
358+
return self.sendCamera("DA")
359359

360360
def deleteFile(self, folder, file):
361361
"""Deletes a file. Pass folder and file as parameters."""
362362
if folder.startswith("http://" + self.ip_addr):
363363
folder, file = self.getInfoFromURL(folder)
364364
if self.whichCam() == constants.Camera.Interface.GPControl:
365-
print(self.gpControlCommand(
366-
"storage/delete?p=" + folder + "/" + file))
365+
return self.gpControlCommand(
366+
"storage/delete?p=" + folder + "/" + file)
367367
else:
368-
print(self.sendCamera("DF", "/"+folder+"/"+file))
368+
return self.sendCamera("DF", "/"+folder+"/"+file)
369369

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

377377
def hilight(self):
378378
"""Tags a hilight in the video"""
379379
if self.whichCam() == constants.Camera.Interface.GPControl:
380-
print(self.gpControlCommand("storage/tag_moment"))
380+
return self.gpControlCommand("storage/tag_moment")
381381
else:
382382
print("Not supported.")
383383

384384
def power_off(self):
385385
"""Sends power off command"""
386386
if self.whichCam() == constants.Camera.Interface.GPControl:
387-
print(self.gpControlCommand("system/sleep"))
387+
return self.gpControlCommand("system/sleep")
388388
else:
389-
print(self.sendBacpac("PW", "00"))
389+
return self.sendBacpac("PW", "00")
390390

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

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

445445
def video_settings(self, res, fps="none"):
446446
"""Change video resolution and FPS
447447
See constants.Video.Resolution"""
448448
if self.whichCam() == constants.Camera.Interface.GPControl:
449449
x = "constants.Video.Resolution.R" + res
450450
videoRes = eval(x)
451-
print(self.gpControlSet(constants.Video.RESOLUTION, videoRes))
451+
return self.gpControlSet(constants.Video.RESOLUTION, videoRes)
452452
if fps != "none":
453453
x = "constants.Video.FrameRate.FR" + fps
454454
videoFps = eval(x)
455-
print(self.gpControlSet(constants.Video.FRAME_RATE, videoFps))
455+
return self.gpControlSet(constants.Video.FRAME_RATE, videoFps)
456456
elif self.whichCam() == constants.Camera.Interface.Auth:
457457
if res == "4k":
458-
print(self.sendCamera(
459-
constants.Hero3Commands.VIDEO_RESOLUTION, "06"))
458+
return self.sendCamera(
459+
constants.Hero3Commands.VIDEO_RESOLUTION, "06")
460460
elif res == "4K_Widescreen":
461-
print(self.sendCamera(
462-
constants.Hero3Commands.VIDEO_RESOLUTION, "08"))
461+
return self.sendCamera(
462+
constants.Hero3Commands.VIDEO_RESOLUTION, "08")
463463
elif res == "2kCin":
464-
print(self.sendCamera(
465-
constants.Hero3Commands.VIDEO_RESOLUTION, "07"))
464+
return self.sendCamera(
465+
constants.Hero3Commands.VIDEO_RESOLUTION, "07")
466466
elif res == "2_7k":
467-
print(self.sendCamera(
468-
constants.Hero3Commands.VIDEO_RESOLUTION, "05"))
467+
return self.sendCamera(
468+
constants.Hero3Commands.VIDEO_RESOLUTION, "05")
469469
elif res == "1440p":
470-
print(self.sendCamera(
471-
constants.Hero3Commands.VIDEO_RESOLUTION, "04"))
470+
return self.sendCamera(
471+
constants.Hero3Commands.VIDEO_RESOLUTION, "04")
472472
elif res == "1080p":
473-
print(self.sendCamera(
474-
constants.Hero3Commands.VIDEO_RESOLUTION, "03"))
473+
return self.sendCamera(
474+
constants.Hero3Commands.VIDEO_RESOLUTION, "03")
475475
elif res == "960p":
476-
print(self.sendCamera(
477-
constants.Hero3Commands.VIDEO_RESOLUTION, "02"))
476+
return self.sendCamera(
477+
constants.Hero3Commands.VIDEO_RESOLUTION, "02")
478478
elif res == "720p":
479-
print(self.sendCamera(
480-
constants.Hero3Commands.VIDEO_RESOLUTION, "01"))
479+
return self.sendCamera(
480+
constants.Hero3Commands.VIDEO_RESOLUTION, "01")
481481
elif res == "480p":
482-
print(self.sendCamera(
483-
constants.Hero3Commands.VIDEO_RESOLUTION, "00"))
482+
return self.sendCamera(
483+
constants.Hero3Commands.VIDEO_RESOLUTION, "00")
484484
if fps != "none":
485485
x = "constants.Hero3Commands.FrameRate.FPS" + fps
486486
videoFps = eval(x)
487-
print(self.sendCamera(constants.Hero3Commands.FRAME_RATE, videoFps))
487+
return self.sendCamera(constants.Hero3Commands.FRAME_RATE, videoFps)
488488

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

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

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

562562
def getMedia(self):
563563
"""Returns last media URL"""
@@ -574,7 +574,7 @@ def getMedia(self):
574574
for i in json_parse["media"]:
575575
for i2 in i["fs"]:
576576
file_lo = i2["n"]
577-
return "http://" + self.ip_addr + "videos/DCIM/" + folder + "/" + file_lo
577+
return "http://" + self.ip_addr + "/videos/DCIM/" + folder + "/" + file_lo
578578
except (HTTPError, URLError) as error:
579579
return ""
580580
except timeout:
@@ -603,7 +603,7 @@ def getMediaFusion(self):
603603
for mediaitem2 in mediaitem["fs"]:
604604
file_2 = mediaitem2["n"]
605605

606-
return ["http://" + self.ip_addr + "videos/DCIM/" + folder_1 + "/" + file_1, "http://" + self.ip_addr + "videos2/DCIM/" + folder_2 + "/" + file_2]
606+
return ["http://" + self.ip_addr + "/videos/DCIM/" + folder_1 + "/" + file_1, "http://" + self.ip_addr + "/videos2/DCIM/" + folder_2 + "/" + file_2]
607607
except (HTTPError, URLError) as error:
608608
return ""
609609
except timeout:
@@ -740,9 +740,9 @@ def getInfoFromURL(self, url):
740740
"""Gets information from Media URL."""
741741
media = []
742742
media.append(url.replace("http://" + self.ip_addr +
743-
"videos/DCIM/", "").replace("/", "-").rsplit("-", 1)[0])
743+
"/videos/DCIM/", "").replace("/", "-").rsplit("-", 1)[0])
744744
media.append(url.replace("http://" + self.ip_addr +
745-
"videos/DCIM/", "").replace("/", "-").rsplit("-", 1)[1])
745+
"/videos/DCIM/", "").replace("/", "-").rsplit("-", 1)[1])
746746
return media
747747

748748
##
@@ -857,9 +857,9 @@ def downloadMedia(self, folder, file, custom_filename=""):
857857
if "FS" in self.infoCamera(constants.Camera.Firmware):
858858
if "GFRNT" in folder:
859859
urllib.request.urlretrieve(
860-
"http://" + self.ip_addr + "videos2/DCIM/" + folder + "/" + file, filename)
860+
"http://" + self.ip_addr + "/videos2/DCIM/" + folder + "/" + file, filename)
861861
urllib.request.urlretrieve(
862-
"http://" + self.ip_addr + "videos/DCIM/" + folder + "/" + file, filename)
862+
"http://" + self.ip_addr + "/videos/DCIM/" + folder + "/" + file, filename)
863863
except (HTTPError, URLError) as error:
864864
print("ERROR: " + str(error))
865865
else:
@@ -879,9 +879,9 @@ def downloadRawPhoto(self, folder, file, custom_filename=""):
879879
if "FS" in self.infoCamera(constants.Camera.Firmware):
880880
if "GFRNT" in folder:
881881
urllib.request.urlretrieve(
882-
"http://" + self.ip_addr + "videos2/DCIM/" + folder + "/" + file, filename)
882+
"http://" + self.ip_addr + "/videos2/DCIM/" + folder + "/" + file, filename)
883883
urllib.request.urlretrieve(
884-
"http://" + self.ip_addr + "videos/DCIM/" + folder + "/" + file, filename)
884+
"http://" + self.ip_addr + "/videos/DCIM/" + folder + "/" + file, filename)
885885
except (HTTPError, URLError) as error:
886886
print("ERROR: " + str(error))
887887
else:
@@ -996,7 +996,7 @@ def downloadLowRes(self, path="", custom_filename=""):
996996
if "GH" in lowres_url:
997997
lowres_url = lowres_url.replace("GH", "GL")
998998
lowres_filename = "LOWRES"+path.replace("MP4", "LRV").replace(
999-
"http://" + self.ip_addr + "videos/DCIM/", "").replace("/", "-")
999+
"http://" + self.ip_addr + "/videos/DCIM/", "").replace("/", "-")
10001000
else:
10011001
print("not supported")
10021002
print("filename: " + lowres_filename)
@@ -1023,7 +1023,7 @@ def getVideoInfo(self, option="", folder="", file=""):
10231023
if option == "":
10241024
if folder == "" and file == "":
10251025
if self.getMediaInfo("file").endswith("MP4"):
1026-
return self._request("gp/gpMediaMetadata?p=" + self.getMediaInfo("folder") + "/" + self.getMediaInfo("file") + "&t=videoinfo")
1026+
return json.loads(self._request("gp/gpMediaMetadata?p=" + self.getMediaInfo("folder") + "/" + self.getMediaInfo("file") + "&t=videoinfo"))
10271027
else:
10281028
data = ""
10291029
if folder == "" and file == "":
@@ -1137,15 +1137,15 @@ def livestream(self, option):
11371137
"""
11381138
if option == "start":
11391139
if self.whichCam() == constants.Camera.Interface.GPControl:
1140-
print(self.gpControlExecute(
1141-
"p1=gpStream&a1=proto_v2&c1=restart"))
1140+
return self.gpControlExecute(
1141+
"p1=gpStream&a1=proto_v2&c1=restart")
11421142
else:
1143-
print(self.sendCamera("PV", "02"))
1143+
return self.sendCamera("PV", "02")
11441144
if option == "stop":
11451145
if self.whichCam() == constants.Camera.Interface.GPControl:
1146-
print(self.gpControlExecute("p1=gpStream&a1=proto_v2&c1=stop"))
1146+
return self.gpControlExecute("p1=gpStream&a1=proto_v2&c1=stop")
11471147
else:
1148-
print(self.sendCamera("PV", "00"))
1148+
return self.sendCamera("PV", "00")
11491149

11501150
def stream(self, addr, quality=""):
11511151
"""Starts a FFmpeg instance for streaming to an address
@@ -1336,7 +1336,10 @@ def parse_value(self, param, value):
13361336
return "30s"
13371337
if value == "06":
13381338
return "1min"
1339-
if param == constants.Hero3Status.LED or param == constants.Hero3Status.Beep or param == constants.Hero3Status.SpotMeter or param == constants.Hero3Status.IsRecording:
1339+
if param == constants.Hero3Status.LED or \
1340+
param == constants.Hero3Status.Beep or \
1341+
param == constants.Hero3Status.SpotMeter or \
1342+
param == constants.Hero3Status.IsRecording:
13401343
if value == "00":
13411344
return "OFF"
13421345
if value == "01":

install_from_source.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
python setup.py install

tests/README.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
### Testing:
2+
3+
Connect a fully-charged HERO5 Black with an SD card to your PC and run the tests.
4+
5+
python main.py
6+
7+
8+
````
9+
konrad@konrad-pc [tests (dev)]: python main.py
10+
test_has_sd_card (__main__.MainTests) ... Needs an SD card
11+
HERO5 Black
12+
HD5.02.02.60.00
13+
Camera successfully connected!
14+
ok
15+
test_photo_mode (__main__.MainTests) ... PHOTO MODE
16+
HERO5 Black
17+
HD5.02.02.60.00
18+
Camera successfully connected!
19+
ok
20+
test_power_off (__main__.MainTests) ... POWER OFF
21+
HERO5 Black
22+
HD5.02.02.60.00
23+
Camera successfully connected!
24+
ok
25+
test_power_on (__main__.MainTests) ... POWER ON
26+
Waking up...
27+
Waking up...
28+
ok
29+
test_recording_status (__main__.MainTests) ... isRecording
30+
HERO5 Black
31+
HD5.02.02.60.00
32+
Camera successfully connected!
33+
ok
34+
test_shoot_video (__main__.MainTests) ... shoot_video(5)
35+
HERO5 Black
36+
HD5.02.02.60.00
37+
Camera successfully connected!
38+
ok
39+
test_shutter (__main__.MainTests) ... SHUTTER START
40+
HERO5 Black
41+
HD5.02.02.60.00
42+
Camera successfully connected!
43+
ok
44+
test_take_photo (__main__.MainTests) ... take_photo()
45+
HERO5 Black
46+
HD5.02.02.60.00
47+
Camera successfully connected!
48+
ok
49+
test_video_mode (__main__.MainTests) ... VIDEO MODE
50+
HERO5 Black
51+
HD5.02.02.60.00
52+
Camera successfully connected!
53+
ok
54+
55+
----------------------------------------------------------------------
56+
Ran 9 tests in 87.454s
57+
58+
OK
59+
````
60+

tests/hero3.py

Whitespace-only changes.

0 commit comments

Comments
 (0)