KonradIT / gopro-py-api

Unofficial GoPro API Library for Python - connect to GoPro via WiFi.
MIT License
1.39k stars 211 forks source link

Added webcam features #148

Closed KonradIT closed 3 years ago

KonradIT commented 3 years ago

Thanks to @gurgelx for his webcam project.

Added:

rmoriz commented 3 years ago

Issues on MacOS 10.15.6 with Hero 8:

  1. GoProCamera.GoPro.getWebcamIP() returns 10.5.5.9 but IP of GoPro is 172.28.128.51 (interface on macOS is assigned '172.28.128.54')

  2. when manually adjusting the example to:

    from goprocam import GoProCamera, constants
    gopro = GoProCamera.GoPro(ip_address="172.28.128.51") # change
    gopro.startWebcam(constants.Webcam.Resolution.R720p)
    gopro.webcamFOV(constants.Webcam.FOV.Linear)
    gopro.getWebcamPreview()

output:

python examples/launch_webcam_preview.py

HERO8 Black
HD8.01.02.00.00
Camera successfully connected!
VLC media player 3.0.11.1 Vetinari (revision 3.0.11.1-0-g52483f3ca2)                                    

but no stream is received.

GP8 display shows "webcam" but not with red background, so I assume the UDP trigger was not sent.

rmoriz commented 3 years ago

Update: GP8 works with manual IP and the following change:

diff --git i/goprocam/GoProCamera.py w/goprocam/GoProCamera.py
index fc22130..453ca0b 100644
--- i/goprocam/GoProCamera.py
+++ w/goprocam/GoProCamera.py
@@ -76,7 +77,7 @@ class GoPro:
         """Sends keep alive packet"""
         while True:
             sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
-            sock.sendto("_GPHD_:0:0:2:0.000000\n".encode(),
+            sock.sendto("_GPHD_:1:0:2:0.000000\n".encode(),
                         (self.ip_addr, 8554))
             time.sleep(2500/1000)
diff --git i/examples/launch_webcam_preview.py w/examples/launch_webcam_preview.py
index 669a42b..4e0df8c 100644
--- i/examples/launch_webcam_preview.py
+++ w/examples/launch_webcam_preview.py
@@ -1,5 +1,7 @@
 from goprocam import GoProCamera, constants
-gopro = GoProCamera.GoPro(ip_address=GoProCamera.GoPro.getWebcamIP())
+gopro = GoProCamera.GoPro(ip_address="172.28.128.51")
 gopro.startWebcam(constants.Webcam.Resolution.R720p)
 gopro.webcamFOV(constants.Webcam.FOV.Linear)
 gopro.getWebcamPreview()
+gopro.KeepAlive()

Update 2:

poor man's python to reset the camera on ctrl+c/exit:

diff --git i/examples/launch_webcam_preview.py w/examples/launch_webcam_preview.py
index 669a42b..a908dcf 100644
--- i/examples/launch_webcam_preview.py
+++ w/examples/launch_webcam_preview.py
@@ -1,5 +1,14 @@
+from signal import signal, SIGINT
 from goprocam import GoProCamera, constants
-gopro = GoProCamera.GoPro(ip_address=GoProCamera.GoPro.getWebcamIP())
+
+def handler(s, f):
+    gopro.stopWebcam()
+    quit()
+
+signal(SIGINT, handler)
+
+gopro = GoProCamera.GoPro(ip_address="172.28.128.51")
 gopro.startWebcam(constants.Webcam.Resolution.R720p)
 gopro.webcamFOV(constants.Webcam.FOV.Linear)
 gopro.getWebcamPreview()
+gopro.KeepAlive()
KonradIT commented 3 years ago

Hi, I want to debug the issue where your getWebcamIP() return 10.5.5.9, mind doing ifconfig and putting the correct interface as a parameter in getWebcamIP() (so getWebcamIP("enp0s20u2") in my case).

I'll also fix the UDP keep alive issue.

KonradIT commented 3 years ago

If you want, do a PR with the changes you made, and I'll review it and merge it.

rmoriz commented 3 years ago

@KonradIT on macos the usb ethernet appears just as regular ethernet interface:

en8: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
    options=6407<RXCSUM,TXCSUM,VLAN_MTU,CHANNEL_IO,PARTIAL_CSUM,ZEROINVERT_CSUM>
    ether 32:ff:7b:cf:c7:3f 
    inet6 fe80::26:4de7:ed48:221c%en8 prefixlen 64 secured scopeid 0x16 
    inet 172.28.128.55 netmask 0xffffff00 broadcast 172.28.128.255
    nd6 options=201<PERFORMNUD,DAD>
    media: autoselect (100baseTX <full-duplex>)
    status: active

Replugging the camera does not provide the same IP nor the same mac address. Looks like dhcp is provided by the GoPro.

print(GoProCamera.GoPro.getWebcamIP('en8'))

returns 172.28.128.51

To me it looks like it's not possible to detect the right device just by IP address. To detect the model and the right trigger string, probably just a request to the status endpoint and parsing its JSON would be enough.

KonradIT commented 3 years ago

Merging as it's pretty stable in my tests. I've been using this branch as my main branch for a week now to offload videos and photos using GoProDashboard and cannot go back to use an SD card reader or MTP connection. Webcam stream does have about 500ms-1000ms of lag in my testing.