quak-camera 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. quak_camera-0.1.0/LICENSE +21 -0
  2. quak_camera-0.1.0/NOTICE +10 -0
  3. quak_camera-0.1.0/PKG-INFO +156 -0
  4. quak_camera-0.1.0/README.md +119 -0
  5. quak_camera-0.1.0/THIRD_PARTY_NOTICES.md +73 -0
  6. quak_camera-0.1.0/pyproject.toml +65 -0
  7. quak_camera-0.1.0/setup.cfg +4 -0
  8. quak_camera-0.1.0/src/quak/__init__.py +7 -0
  9. quak_camera-0.1.0/src/quak/__main__.py +3 -0
  10. quak_camera-0.1.0/src/quak/camera.py +321 -0
  11. quak_camera-0.1.0/src/quak/cli/__init__.py +0 -0
  12. quak_camera-0.1.0/src/quak/cli/main.py +887 -0
  13. quak_camera-0.1.0/src/quak/config.py +98 -0
  14. quak_camera-0.1.0/src/quak/connect.py +75 -0
  15. quak_camera-0.1.0/src/quak/core/__init__.py +1 -0
  16. quak_camera-0.1.0/src/quak/core/codec.py +228 -0
  17. quak_camera-0.1.0/src/quak/core/errors.py +66 -0
  18. quak_camera-0.1.0/src/quak/core/proto.py +307 -0
  19. quak_camera-0.1.0/src/quak/core/redact.py +55 -0
  20. quak_camera-0.1.0/src/quak/core/registry.py +333 -0
  21. quak_camera-0.1.0/src/quak/core/tables.py +442 -0
  22. quak_camera-0.1.0/src/quak/describe.py +126 -0
  23. quak_camera-0.1.0/src/quak/e2e/__init__.py +1 -0
  24. quak_camera-0.1.0/src/quak/e2e/__main__.py +3 -0
  25. quak_camera-0.1.0/src/quak/e2e/gui.py +375 -0
  26. quak_camera-0.1.0/src/quak/e2e/gui_steps.py +232 -0
  27. quak_camera-0.1.0/src/quak/e2e/runner.py +252 -0
  28. quak_camera-0.1.0/src/quak/e2e/scenarios.py +436 -0
  29. quak_camera-0.1.0/src/quak/flows.py +309 -0
  30. quak_camera-0.1.0/src/quak/guard.py +167 -0
  31. quak_camera-0.1.0/src/quak/gui/__init__.py +1 -0
  32. quak_camera-0.1.0/src/quak/gui/app.py +683 -0
  33. quak_camera-0.1.0/src/quak/gui/assets/THIRD_PARTY_NOTICES.md +73 -0
  34. quak_camera-0.1.0/src/quak/gui/assets/favicon.png +0 -0
  35. quak_camera-0.1.0/src/quak/gui/assets/fonts/Inter.ttf +0 -0
  36. quak_camera-0.1.0/src/quak/gui/assets/fonts/JetBrainsMono.ttf +0 -0
  37. quak_camera-0.1.0/src/quak/gui/assets/fonts/OFL-Inter.txt +93 -0
  38. quak_camera-0.1.0/src/quak/gui/assets/fonts/OFL-JetBrainsMono.txt +93 -0
  39. quak_camera-0.1.0/src/quak/gui/assets/fonts/OFL-SpaceGrotesk.txt +93 -0
  40. quak_camera-0.1.0/src/quak/gui/assets/fonts/README.md +10 -0
  41. quak_camera-0.1.0/src/quak/gui/assets/fonts/SpaceGrotesk.ttf +0 -0
  42. quak_camera-0.1.0/src/quak/gui/assets/icon.ico +0 -0
  43. quak_camera-0.1.0/src/quak/gui/assets/icon.png +0 -0
  44. quak_camera-0.1.0/src/quak/gui/assets/icon_linux.png +0 -0
  45. quak_camera-0.1.0/src/quak/gui/assets/icon_web.png +0 -0
  46. quak_camera-0.1.0/src/quak/gui/assets/icon_windows.png +0 -0
  47. quak_camera-0.1.0/src/quak/gui/assets/licenses/GPL-3.0.txt +674 -0
  48. quak_camera-0.1.0/src/quak/gui/assets/licenses/LGPL-2.1.txt +501 -0
  49. quak_camera-0.1.0/src/quak/gui/assets/licenses/LGPL-3.0.txt +165 -0
  50. quak_camera-0.1.0/src/quak/gui/assets/logo-duck.svg +1 -0
  51. quak_camera-0.1.0/src/quak/gui/assets/logo-mono-black.svg +1 -0
  52. quak_camera-0.1.0/src/quak/gui/assets/logo-mono-white.svg +1 -0
  53. quak_camera-0.1.0/src/quak/gui/assets/logo.png +0 -0
  54. quak_camera-0.1.0/src/quak/gui/assets/logo.svg +1 -0
  55. quak_camera-0.1.0/src/quak/gui/kit.py +452 -0
  56. quak_camera-0.1.0/src/quak/gui/preview.py +109 -0
  57. quak_camera-0.1.0/src/quak/gui/screens/__init__.py +12 -0
  58. quak_camera-0.1.0/src/quak/gui/screens/add_camera.py +341 -0
  59. quak_camera-0.1.0/src/quak/gui/screens/cameras.py +304 -0
  60. quak_camera-0.1.0/src/quak/gui/screens/common.py +206 -0
  61. quak_camera-0.1.0/src/quak/gui/screens/live.py +318 -0
  62. quak_camera-0.1.0/src/quak/gui/screens/media.py +644 -0
  63. quak_camera-0.1.0/src/quak/gui/screens/more.py +546 -0
  64. quak_camera-0.1.0/src/quak/gui/screens/remote.py +481 -0
  65. quak_camera-0.1.0/src/quak/gui/screens/schedule.py +323 -0
  66. quak_camera-0.1.0/src/quak/gui/screens/settings.py +86 -0
  67. quak_camera-0.1.0/src/quak/gui/theme.py +110 -0
  68. quak_camera-0.1.0/src/quak/gui/tour.py +142 -0
  69. quak_camera-0.1.0/src/quak/net/__init__.py +1 -0
  70. quak_camera-0.1.0/src/quak/net/android_wifi.py +47 -0
  71. quak_camera-0.1.0/src/quak/net/hotspot.py +78 -0
  72. quak_camera-0.1.0/src/quak/net/http.py +212 -0
  73. quak_camera-0.1.0/src/quak/net/netsh.py +149 -0
  74. quak_camera-0.1.0/src/quak/net/nmcli.py +297 -0
  75. quak_camera-0.1.0/src/quak/net/profiles.py +3 -0
  76. quak_camera-0.1.0/src/quak/net/stream.py +259 -0
  77. quak_camera-0.1.0/src/quak/net/wifi.py +134 -0
  78. quak_camera-0.1.0/src/quak/service.py +472 -0
  79. quak_camera-0.1.0/src/quak/session.py +254 -0
  80. quak_camera-0.1.0/src/quak/transport/__init__.py +1 -0
  81. quak_camera-0.1.0/src/quak/transport/android.py +88 -0
  82. quak_camera-0.1.0/src/quak/transport/base.py +28 -0
  83. quak_camera-0.1.0/src/quak/transport/ble.py +174 -0
  84. quak_camera-0.1.0/src/quak/transport/bluez.py +110 -0
  85. quak_camera-0.1.0/src/quak/transport/sim.py +954 -0
  86. quak_camera-0.1.0/src/quak/transport/sim_http.py +302 -0
  87. quak_camera-0.1.0/src/quak_camera.egg-info/PKG-INFO +156 -0
  88. quak_camera-0.1.0/src/quak_camera.egg-info/SOURCES.txt +109 -0
  89. quak_camera-0.1.0/src/quak_camera.egg-info/dependency_links.txt +1 -0
  90. quak_camera-0.1.0/src/quak_camera.egg-info/entry_points.txt +3 -0
  91. quak_camera-0.1.0/src/quak_camera.egg-info/requires.txt +19 -0
  92. quak_camera-0.1.0/src/quak_camera.egg-info/top_level.txt +1 -0
  93. quak_camera-0.1.0/tests/test_android_link.py +139 -0
  94. quak_camera-0.1.0/tests/test_ble_errors.py +62 -0
  95. quak_camera-0.1.0/tests/test_byte_log.py +27 -0
  96. quak_camera-0.1.0/tests/test_cli.py +28 -0
  97. quak_camera-0.1.0/tests/test_cli_sim.py +135 -0
  98. quak_camera-0.1.0/tests/test_codec.py +186 -0
  99. quak_camera-0.1.0/tests/test_footage_safety.py +121 -0
  100. quak_camera-0.1.0/tests/test_gui_screens.py +563 -0
  101. quak_camera-0.1.0/tests/test_gui_steps.py +123 -0
  102. quak_camera-0.1.0/tests/test_net.py +723 -0
  103. quak_camera-0.1.0/tests/test_packaging.py +40 -0
  104. quak_camera-0.1.0/tests/test_phone_imports.py +52 -0
  105. quak_camera-0.1.0/tests/test_preview_decoder.py +92 -0
  106. quak_camera-0.1.0/tests/test_proto.py +215 -0
  107. quak_camera-0.1.0/tests/test_redaction.py +95 -0
  108. quak_camera-0.1.0/tests/test_registry.py +99 -0
  109. quak_camera-0.1.0/tests/test_safety.py +94 -0
  110. quak_camera-0.1.0/tests/test_session.py +180 -0
  111. quak_camera-0.1.0/tests/test_sim_camera.py +257 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Adriel Santos
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,10 @@
1
+ Quak is an independent open-source project. It is not affiliated with, endorsed by, or
2
+ sponsored by GoPro, Inc.
3
+
4
+ GoPro, HERO and Quik are trademarks or registered trademarks of GoPro, Inc. They are used
5
+ here only to identify the cameras and the app this software interoperates with.
6
+
7
+ The camera protocol details used by Quak come from GoPro's public Open GoPro specification
8
+ (https://gopro.github.io/OpenGoPro/) and from our own testing. Quak's settings tables are
9
+ generated from GoPro's MIT-licensed Open GoPro Python SDK, whose notice is reproduced in
10
+ THIRD_PARTY_NOTICES.md, along with the notices of the software the packaged apps contain.
@@ -0,0 +1,156 @@
1
+ Metadata-Version: 2.4
2
+ Name: quak-camera
3
+ Version: 0.1.0
4
+ Summary: Open-source remote for GoPro HERO11 cameras over BLE and Wi-Fi: a CLI and a cross-platform GUI on one backend
5
+ Author: Adriel Santos
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/ADCDS/quak
8
+ Project-URL: Issues, https://github.com/ADCDS/quak/issues
9
+ Project-URL: Changelog, https://github.com/ADCDS/quak/blob/main/CHANGELOG.md
10
+ Keywords: gopro,hero11,open-gopro,ble,camera,remote,flet
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Environment :: Console
13
+ Classifier: Environment :: X11 Applications
14
+ Classifier: Intended Audience :: End Users/Desktop
15
+ Classifier: Operating System :: POSIX :: Linux
16
+ Classifier: Operating System :: Microsoft :: Windows
17
+ Classifier: Operating System :: Android
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Topic :: Multimedia :: Video :: Capture
20
+ Requires-Python: >=3.11
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ License-File: NOTICE
24
+ License-File: THIRD_PARTY_NOTICES.md
25
+ Requires-Dist: bleak<2,>=0.22
26
+ Requires-Dist: dbus-fast>=2.0; sys_platform == "linux"
27
+ Provides-Extra: gui
28
+ Requires-Dist: flet[all]==1.1.0; extra == "gui"
29
+ Requires-Dist: flet-video==1.1.0; extra == "gui"
30
+ Provides-Extra: e2e
31
+ Requires-Dist: websockets>=13; extra == "e2e"
32
+ Provides-Extra: test
33
+ Requires-Dist: open_gopro==0.22.0; python_version < "3.14" and extra == "test"
34
+ Provides-Extra: dev
35
+ Requires-Dist: ruff; extra == "dev"
36
+ Dynamic: license-file
37
+
38
+ <p align="center"><img src="https://raw.githubusercontent.com/ADCDS/quak/main/src/quak/gui/assets/logo.png" width="128" alt="Quak logo: a yellow duck with a camera lens for an eye"></p>
39
+
40
+ <h1 align="center">Quak</h1>
41
+
42
+ <p align="center">An open-source remote for the GoPro HERO11 Black: a command-line tool and an app for desktop and Android.</p>
43
+
44
+ <p align="center"><img src="https://raw.githubusercontent.com/ADCDS/quak/main/docs/images/hero.png" alt="Quak on desktop and phone, showing a live preview from a simulated camera"></p>
45
+
46
+ Quak talks to the camera over Bluetooth and the camera's own Wi-Fi, using GoPro's public
47
+ [Open GoPro API](https://gopro.github.io/OpenGoPro/). No account and no cloud.
48
+
49
+ > **Status: early, and tested on one camera.** It's built around one HERO11 Black (firmware 2.20). Other models get a
50
+ > warning and may not work. See [what has been tested](#what-has-been-tested) before you rely on it.
51
+
52
+ ## Try it without a camera
53
+
54
+ Quak includes a simulated camera that speaks the real protocol, so you can try everything first. You need Python 3.11 or
55
+ newer.
56
+
57
+ ```bash
58
+ pipx install 'quak-camera[gui]' # or pip, in a virtual environment
59
+
60
+ quak --sim info # the command line
61
+ quak --sim schedule arm +2m --duration 15s
62
+ quak-gui --sim # the app (the first launch downloads about 45 MB)
63
+ ```
64
+
65
+ Or download a ready-made app for Linux, Windows or Android from [Releases](https://github.com/ADCDS/quak/releases). The
66
+ [install guide](https://github.com/ADCDS/quak/blob/main/docs/install.md) has the details for each system.
67
+
68
+ <p align="center"><img src="https://raw.githubusercontent.com/ADCDS/quak/main/docs/images/terminal.gif" width="720" alt="The quak command reading a simulated camera and arming a scheduled capture"></p>
69
+
70
+ ## What it does
71
+
72
+ - **Remote control:** record, take photos, tag HiLights, change presets and every HERO11 setting.
73
+ - **Scheduled capture:** arm the camera for a time and a length, with its clock synced first. It starts and stops by itself,
74
+ even if you switch it off after arming.
75
+ - **Live preview** over the camera's Wi-Fi. The camera can't stream while it records, so preview pauses until you stop.
76
+ - **Media:** browse the card, download clips, and delete them, with a confirmation that names the file.
77
+ - **Livestream** to an RTMP server such as YouTube or Twitch. This is **experimental**: see [known issues](https://github.com/ADCDS/quak/blob/main/docs/troubleshooting.md#known-issues).
78
+
79
+ <p align="center">
80
+ <img src="https://raw.githubusercontent.com/ADCDS/quak/main/docs/images/phone-cameras.png" width="230" alt="The Cameras screen, showing battery, card space and clock">
81
+ <img src="https://raw.githubusercontent.com/ADCDS/quak/main/docs/images/phone-schedule.png" width="230" alt="An armed scheduled capture with a countdown">
82
+ <img src="https://raw.githubusercontent.com/ADCDS/quak/main/docs/images/phone-settings.png" width="230" alt="Camera settings, with Pro-only settings greyed out and the reason shown">
83
+ </p>
84
+
85
+ <p align="center"><img src="https://raw.githubusercontent.com/ADCDS/quak/main/docs/images/desktop-media.png" width="760" alt="The desktop Media screen: a grid of clips and the details of the selected one"></p>
86
+
87
+ Screenshots come from the simulated camera, with a drawn scene instead of real footage.
88
+
89
+ ## Use it with your camera
90
+
91
+ Install it as above, plus what [the install guide](https://github.com/ADCDS/quak/blob/main/docs/install.md) lists for your system. Then pair once. On the camera, open
92
+ **Preferences > Connections > Connect Device > GoPro Quik App**, and leave that screen open while you run:
93
+
94
+ ```bash
95
+ quak pair # finds the camera on its pairing screen and remembers it
96
+ quak info
97
+ quak record --seconds 5
98
+ quak schedule arm +2m --duration 15s
99
+ quak media list
100
+ ```
101
+
102
+ `quak --help` lists every command. In the app, use **Add camera**, which walks you through the same steps.
103
+
104
+ **Android:** download the APK from [Releases](https://github.com/ADCDS/quak/releases). It needs Android 10 or newer.
105
+
106
+ Before you use it for real, read [what Quak changes on your computer and camera](https://github.com/ADCDS/quak/blob/main/docs/safety.md). In short:
107
+
108
+ - On a computer, viewing media or the preview moves a Wi-Fi adapter onto the camera's network for a while. Quak avoids the
109
+ adapter you're online through, and asks first if it's the only one.
110
+ - A scheduled capture changes the camera's Duration setting and leaves it changed, which also limits recordings you start
111
+ by hand. Quak tells you when this happens.
112
+
113
+ <p align="center"><img src="https://raw.githubusercontent.com/ADCDS/quak/main/docs/images/how-it-connects.svg" width="760" alt="Bluetooth carries controls and settings. The camera's own Wi-Fi carries preview and media. For a livestream, the camera joins your Wi-Fi."></p>
114
+
115
+ ## What has been tested
116
+
117
+ Tested on one real HERO11 Black, with the end-to-end suites on Linux and by hand on one Android phone:
118
+
119
+ | Feature | Linux | Android | Windows |
120
+ |---|---|---|---|
121
+ | Pairing and reconnecting | Tested | Tested | Not tested |
122
+ | Status, clock sync | Tested | Tested | Not tested |
123
+ | Recording | Tested | Tested | Not tested |
124
+ | HiLights, presets, settings | Tested | Not tested | Not tested |
125
+ | Scheduled capture | Tested | Not tested | Not tested |
126
+ | Live preview | Tested | Tested | Not tested |
127
+ | Media: list, download, delete | Tested | Tested | Not tested |
128
+ | Livestream | Experimental | Not tested | Not tested |
129
+
130
+ **Windows is experimental.** The Windows build compiles and its unit tests pass, but it has never been launched or used with a
131
+ camera. Livestream worked end to end, then stopped working on the test camera for a reason that isn't known yet.
132
+ [`docs/testing.md`](https://github.com/ADCDS/quak/blob/main/docs/testing.md) has the details.
133
+
134
+ ## Documentation
135
+
136
+ - [Install guide](https://github.com/ADCDS/quak/blob/main/docs/install.md): Linux, Windows and Android, and building the packages
137
+ - [Safety](https://github.com/ADCDS/quak/blob/main/docs/safety.md): what Quak changes and stores, what it can delete, and how to recover
138
+ - [Troubleshooting](https://github.com/ADCDS/quak/blob/main/docs/troubleshooting.md): common problems and known issues
139
+ - [Architecture](https://github.com/ADCDS/quak/blob/main/docs/architecture.md): how the code is organised
140
+ - [Testing](https://github.com/ADCDS/quak/blob/main/docs/testing.md): the test suites and hardware results
141
+ - [Protocol notes](https://github.com/ADCDS/quak/blob/main/docs/protocol.md): what we learned about the camera, beyond the official docs
142
+ - [Contributing](https://github.com/ADCDS/quak/blob/main/CONTRIBUTING.md)
143
+
144
+ ## How it was built
145
+
146
+ Quak was built with heavy AI assistance. Claude wrote most of the code, tests, documentation and the logo, and ran the test
147
+ suites on a real camera, directed by a person who also tried it on the camera and phone. The hardware claims above come from
148
+ those tests, and from nothing else.
149
+
150
+ ## Licence and disclaimer
151
+
152
+ MIT: see [LICENSE](https://github.com/ADCDS/quak/blob/main/LICENSE). The packaged apps include other software under its own licences, including LGPL libraries: see
153
+ [THIRD_PARTY_NOTICES.md](https://github.com/ADCDS/quak/blob/main/THIRD_PARTY_NOTICES.md).
154
+
155
+ Quak is an independent project, not affiliated with, endorsed by or sponsored by GoPro, Inc. GoPro, HERO and Quik are
156
+ trademarks of GoPro, Inc. See [NOTICE](https://github.com/ADCDS/quak/blob/main/NOTICE).
@@ -0,0 +1,119 @@
1
+ <p align="center"><img src="https://raw.githubusercontent.com/ADCDS/quak/main/src/quak/gui/assets/logo.png" width="128" alt="Quak logo: a yellow duck with a camera lens for an eye"></p>
2
+
3
+ <h1 align="center">Quak</h1>
4
+
5
+ <p align="center">An open-source remote for the GoPro HERO11 Black: a command-line tool and an app for desktop and Android.</p>
6
+
7
+ <p align="center"><img src="https://raw.githubusercontent.com/ADCDS/quak/main/docs/images/hero.png" alt="Quak on desktop and phone, showing a live preview from a simulated camera"></p>
8
+
9
+ Quak talks to the camera over Bluetooth and the camera's own Wi-Fi, using GoPro's public
10
+ [Open GoPro API](https://gopro.github.io/OpenGoPro/). No account and no cloud.
11
+
12
+ > **Status: early, and tested on one camera.** It's built around one HERO11 Black (firmware 2.20). Other models get a
13
+ > warning and may not work. See [what has been tested](#what-has-been-tested) before you rely on it.
14
+
15
+ ## Try it without a camera
16
+
17
+ Quak includes a simulated camera that speaks the real protocol, so you can try everything first. You need Python 3.11 or
18
+ newer.
19
+
20
+ ```bash
21
+ pipx install 'quak-camera[gui]' # or pip, in a virtual environment
22
+
23
+ quak --sim info # the command line
24
+ quak --sim schedule arm +2m --duration 15s
25
+ quak-gui --sim # the app (the first launch downloads about 45 MB)
26
+ ```
27
+
28
+ Or download a ready-made app for Linux, Windows or Android from [Releases](https://github.com/ADCDS/quak/releases). The
29
+ [install guide](https://github.com/ADCDS/quak/blob/main/docs/install.md) has the details for each system.
30
+
31
+ <p align="center"><img src="https://raw.githubusercontent.com/ADCDS/quak/main/docs/images/terminal.gif" width="720" alt="The quak command reading a simulated camera and arming a scheduled capture"></p>
32
+
33
+ ## What it does
34
+
35
+ - **Remote control:** record, take photos, tag HiLights, change presets and every HERO11 setting.
36
+ - **Scheduled capture:** arm the camera for a time and a length, with its clock synced first. It starts and stops by itself,
37
+ even if you switch it off after arming.
38
+ - **Live preview** over the camera's Wi-Fi. The camera can't stream while it records, so preview pauses until you stop.
39
+ - **Media:** browse the card, download clips, and delete them, with a confirmation that names the file.
40
+ - **Livestream** to an RTMP server such as YouTube or Twitch. This is **experimental**: see [known issues](https://github.com/ADCDS/quak/blob/main/docs/troubleshooting.md#known-issues).
41
+
42
+ <p align="center">
43
+ <img src="https://raw.githubusercontent.com/ADCDS/quak/main/docs/images/phone-cameras.png" width="230" alt="The Cameras screen, showing battery, card space and clock">
44
+ <img src="https://raw.githubusercontent.com/ADCDS/quak/main/docs/images/phone-schedule.png" width="230" alt="An armed scheduled capture with a countdown">
45
+ <img src="https://raw.githubusercontent.com/ADCDS/quak/main/docs/images/phone-settings.png" width="230" alt="Camera settings, with Pro-only settings greyed out and the reason shown">
46
+ </p>
47
+
48
+ <p align="center"><img src="https://raw.githubusercontent.com/ADCDS/quak/main/docs/images/desktop-media.png" width="760" alt="The desktop Media screen: a grid of clips and the details of the selected one"></p>
49
+
50
+ Screenshots come from the simulated camera, with a drawn scene instead of real footage.
51
+
52
+ ## Use it with your camera
53
+
54
+ Install it as above, plus what [the install guide](https://github.com/ADCDS/quak/blob/main/docs/install.md) lists for your system. Then pair once. On the camera, open
55
+ **Preferences > Connections > Connect Device > GoPro Quik App**, and leave that screen open while you run:
56
+
57
+ ```bash
58
+ quak pair # finds the camera on its pairing screen and remembers it
59
+ quak info
60
+ quak record --seconds 5
61
+ quak schedule arm +2m --duration 15s
62
+ quak media list
63
+ ```
64
+
65
+ `quak --help` lists every command. In the app, use **Add camera**, which walks you through the same steps.
66
+
67
+ **Android:** download the APK from [Releases](https://github.com/ADCDS/quak/releases). It needs Android 10 or newer.
68
+
69
+ Before you use it for real, read [what Quak changes on your computer and camera](https://github.com/ADCDS/quak/blob/main/docs/safety.md). In short:
70
+
71
+ - On a computer, viewing media or the preview moves a Wi-Fi adapter onto the camera's network for a while. Quak avoids the
72
+ adapter you're online through, and asks first if it's the only one.
73
+ - A scheduled capture changes the camera's Duration setting and leaves it changed, which also limits recordings you start
74
+ by hand. Quak tells you when this happens.
75
+
76
+ <p align="center"><img src="https://raw.githubusercontent.com/ADCDS/quak/main/docs/images/how-it-connects.svg" width="760" alt="Bluetooth carries controls and settings. The camera's own Wi-Fi carries preview and media. For a livestream, the camera joins your Wi-Fi."></p>
77
+
78
+ ## What has been tested
79
+
80
+ Tested on one real HERO11 Black, with the end-to-end suites on Linux and by hand on one Android phone:
81
+
82
+ | Feature | Linux | Android | Windows |
83
+ |---|---|---|---|
84
+ | Pairing and reconnecting | Tested | Tested | Not tested |
85
+ | Status, clock sync | Tested | Tested | Not tested |
86
+ | Recording | Tested | Tested | Not tested |
87
+ | HiLights, presets, settings | Tested | Not tested | Not tested |
88
+ | Scheduled capture | Tested | Not tested | Not tested |
89
+ | Live preview | Tested | Tested | Not tested |
90
+ | Media: list, download, delete | Tested | Tested | Not tested |
91
+ | Livestream | Experimental | Not tested | Not tested |
92
+
93
+ **Windows is experimental.** The Windows build compiles and its unit tests pass, but it has never been launched or used with a
94
+ camera. Livestream worked end to end, then stopped working on the test camera for a reason that isn't known yet.
95
+ [`docs/testing.md`](https://github.com/ADCDS/quak/blob/main/docs/testing.md) has the details.
96
+
97
+ ## Documentation
98
+
99
+ - [Install guide](https://github.com/ADCDS/quak/blob/main/docs/install.md): Linux, Windows and Android, and building the packages
100
+ - [Safety](https://github.com/ADCDS/quak/blob/main/docs/safety.md): what Quak changes and stores, what it can delete, and how to recover
101
+ - [Troubleshooting](https://github.com/ADCDS/quak/blob/main/docs/troubleshooting.md): common problems and known issues
102
+ - [Architecture](https://github.com/ADCDS/quak/blob/main/docs/architecture.md): how the code is organised
103
+ - [Testing](https://github.com/ADCDS/quak/blob/main/docs/testing.md): the test suites and hardware results
104
+ - [Protocol notes](https://github.com/ADCDS/quak/blob/main/docs/protocol.md): what we learned about the camera, beyond the official docs
105
+ - [Contributing](https://github.com/ADCDS/quak/blob/main/CONTRIBUTING.md)
106
+
107
+ ## How it was built
108
+
109
+ Quak was built with heavy AI assistance. Claude wrote most of the code, tests, documentation and the logo, and ran the test
110
+ suites on a real camera, directed by a person who also tried it on the camera and phone. The hardware claims above come from
111
+ those tests, and from nothing else.
112
+
113
+ ## Licence and disclaimer
114
+
115
+ MIT: see [LICENSE](https://github.com/ADCDS/quak/blob/main/LICENSE). The packaged apps include other software under its own licences, including LGPL libraries: see
116
+ [THIRD_PARTY_NOTICES.md](https://github.com/ADCDS/quak/blob/main/THIRD_PARTY_NOTICES.md).
117
+
118
+ Quak is an independent project, not affiliated with, endorsed by or sponsored by GoPro, Inc. GoPro, HERO and Quik are
119
+ trademarks of GoPro, Inc. See [NOTICE](https://github.com/ADCDS/quak/blob/main/NOTICE).
@@ -0,0 +1,73 @@
1
+ # Third-party notices
2
+
3
+ Quak's own source code is under the MIT License (see `LICENSE`). The packaged apps also contain the software below, each
4
+ under its own licence. Links point to where you can get the source code and the full licence text.
5
+
6
+ ## mpv and FFmpeg (LGPL)
7
+
8
+ The Android and Windows packages contain `libmpv`, which plays the camera's live preview, and FFmpeg inside it. The Linux
9
+ package uses the `libmpv` installed on your system.
10
+
11
+ | Component | Version | Licence | Source |
12
+ |---|---|---|---|
13
+ | mpv, built without GPL parts (`-Dgpl=false`) | from the builds below | LGPL-2.1-or-later | <https://github.com/mpv-player/mpv> |
14
+ | FFmpeg | n6.0 | LGPL-3.0-or-later | <https://ffmpeg.org/download.html> |
15
+ | Android build of the two (`media_kit_libs_android_video` 1.3.8) | | as above | <https://github.com/media-kit/libmpv-android-video-build> |
16
+ | Windows build of the two (`media_kit_libs_windows_video` 1.0.11) | | as above | <https://github.com/media-kit/libmpv-win32-video-build> |
17
+
18
+ Quak loads these as separate shared libraries (`libmpv.so`, `libmpv-2.dll`), so you can replace them with your own builds.
19
+ On Android that means rebuilding the app from this repository, as described in `docs/install.md`.
20
+
21
+ The full licence texts are in `src/quak/gui/assets/licenses/`, and they ship inside the apps: `LGPL-2.1.txt`, `LGPL-3.0.txt`
22
+ and `GPL-3.0.txt`, which LGPL-3.0 builds on.
23
+
24
+ ## Fonts (SIL Open Font License 1.1)
25
+
26
+ Inter, Space Grotesk and JetBrains Mono. Their licences are in `src/quak/gui/assets/fonts/`.
27
+
28
+ ## Other components
29
+
30
+ | Component | Version | Licence | Where |
31
+ |---|---|---|---|
32
+ | Flutter | 3.47.9 | BSD-3-Clause | packaged apps |
33
+ | Flet and flet-video | 1.1.0 | Apache-2.0 | packaged apps, `quak-gui` |
34
+ | Python | 3.14 | PSF-2.0 | packaged apps |
35
+ | media_kit | 1.2.6 | MIT | packaged apps |
36
+ | media_kit_video | 2.0.1 | MIT | packaged apps |
37
+ | universal_ble | 3.1.0 | BSD-3-Clause | Android |
38
+ | wifi_iot | 0.4.0 | MIT | Android |
39
+ | bleak | 1.x or 0.22 | MIT | CLI and desktop |
40
+ | dbus-fast | 2.x | MIT | Linux |
41
+ | certifi | | MPL-2.0 | through Flet |
42
+ | typing_extensions | | PSF-2.0 | through Flet |
43
+
44
+ Flutter apps also bundle the notices of every Dart package they use, in their `NOTICES` asset.
45
+
46
+ ## GoPro's Open GoPro SDK
47
+
48
+ Quak doesn't use this SDK at run time, but `tools/gen_tables.py` generates Quak's settings tables from it, and its tests
49
+ compare Quak's messages with it. Its notice:
50
+
51
+ ```text
52
+ The OpenGoPro Python SDK is licensed under the MIT License
53
+
54
+ Copyright © 2021-2024 GoPro, Inc.
55
+
56
+ Permission is hereby granted, free of charge, to any person obtaining a copy
57
+ of this software and associated documentation files (the "Software"), to deal
58
+ in the Software without restriction, including without limitation the rights
59
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
60
+ copies of the Software, and to permit persons to whom the Software is
61
+ furnished to do so, subject to the following conditions:
62
+
63
+ The above copyright notice and this permission notice shall be included in all
64
+ copies or substantial portions of the Software.
65
+
66
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
67
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
68
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
69
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
70
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
71
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
72
+ SOFTWARE.
73
+ ```
@@ -0,0 +1,65 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "quak-camera" # "quak" on PyPI is an unrelated project; the commands are still quak and quak-gui
7
+ dynamic = ["version"]
8
+ description = "Open-source remote for GoPro HERO11 cameras over BLE and Wi-Fi: a CLI and a cross-platform GUI on one backend"
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ license-files = ["LICENSE", "NOTICE", "THIRD_PARTY_NOTICES.md"]
12
+ authors = [{ name = "Adriel Santos" }]
13
+ keywords = ["gopro", "hero11", "open-gopro", "ble", "camera", "remote", "flet"]
14
+ classifiers = [
15
+ "Development Status :: 3 - Alpha",
16
+ "Environment :: Console",
17
+ "Environment :: X11 Applications",
18
+ "Intended Audience :: End Users/Desktop",
19
+ "Operating System :: POSIX :: Linux",
20
+ "Operating System :: Microsoft :: Windows",
21
+ "Operating System :: Android",
22
+ "Programming Language :: Python :: 3",
23
+ "Topic :: Multimedia :: Video :: Capture",
24
+ ]
25
+ requires-python = ">=3.11"
26
+ dependencies = [
27
+ "bleak>=0.22,<2",
28
+ "dbus-fast>=2.0; sys_platform == 'linux'",
29
+ ]
30
+
31
+ [project.optional-dependencies]
32
+ gui = ["flet[all]==1.1.0", "flet-video==1.1.0"]
33
+ # GUI end-to-end driver (Chrome DevTools protocol)
34
+ e2e = ["websockets>=13"]
35
+ # Test-only: GoPro's SDK, used to cross-check our protobuf bytes. Never imported at runtime.
36
+ test = ["open_gopro==0.22.0; python_version < '3.14'"]
37
+ dev = ["ruff"]
38
+
39
+ [project.urls]
40
+ Homepage = "https://github.com/ADCDS/quak"
41
+ Issues = "https://github.com/ADCDS/quak/issues"
42
+ Changelog = "https://github.com/ADCDS/quak/blob/main/CHANGELOG.md"
43
+
44
+ [project.scripts]
45
+ quak = "quak.cli.main:main"
46
+ quak-gui = "quak.gui.app:run"
47
+
48
+ [tool.setuptools.packages.find]
49
+ where = ["src"]
50
+
51
+ [tool.setuptools.dynamic]
52
+ version = { attr = "quak.__version__" }
53
+
54
+ [tool.setuptools.package-data]
55
+ "quak.gui" = ["assets/*", "assets/fonts/*", "assets/licenses/*"]
56
+
57
+ [tool.ruff]
58
+ line-length = 120
59
+ extend-exclude = ["app/src/quak", "app/build"]
60
+
61
+ [tool.ruff.lint]
62
+ select = ["E9", "F", "I"]
63
+
64
+ [tool.ruff.lint.isort]
65
+ known-first-party = ["quak"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,7 @@
1
+ """Quak: an open-source remote for GoPro HERO11 cameras.
2
+
3
+ One backend (``quak.service.CameraService``) is shared by the ``quak`` CLI, the Flet GUI
4
+ and the end-to-end test runner.
5
+ """
6
+
7
+ __version__ = "0.1.0"
@@ -0,0 +1,3 @@
1
+ from quak.cli.main import main
2
+
3
+ main()