fastled 1.2.50__tar.gz → 1.2.59__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.
- {fastled-1.2.50 → fastled-1.2.59}/.github/workflows/test_macos.yml +1 -1
- {fastled-1.2.50 → fastled-1.2.59}/.github/workflows/test_ubuntu.yml +1 -1
- {fastled-1.2.50 → fastled-1.2.59}/.github/workflows/test_win.yml +1 -1
- {fastled-1.2.50 → fastled-1.2.59}/.gitignore +1 -1
- {fastled-1.2.50 → fastled-1.2.59}/Dockerfile +2 -2
- {fastled-1.2.50 → fastled-1.2.59}/PKG-INFO +17 -4
- {fastled-1.2.50 → fastled-1.2.59}/README.md +13 -1
- {fastled-1.2.50 → fastled-1.2.59}/compiler/compile.py +3 -0
- fastled-1.2.59/compiler/entrypoint.sh +16 -0
- fastled-1.2.59/compiler/extra/micdemo.html +136 -0
- fastled-1.2.59/compiler/process_extended.py +109 -0
- fastled-1.2.59/compiler/pyproject.toml +22 -0
- {fastled-1.2.50 → fastled-1.2.59}/compiler/server.py +3 -0
- {fastled-1.2.50 → fastled-1.2.59}/lint +1 -3
- {fastled-1.2.50 → fastled-1.2.59}/pyproject.toml +3 -2
- {fastled-1.2.50 → fastled-1.2.59}/src/fastled/__init__.py +1 -1
- {fastled-1.2.50 → fastled-1.2.59}/src/fastled/app.py +1 -2
- fastled-1.2.59/src/fastled/assets/localhost-key.pem +28 -0
- fastled-1.2.59/src/fastled/assets/localhost.pem +27 -0
- fastled-1.2.59/src/fastled/cli_test.py +20 -0
- {fastled-1.2.50 → fastled-1.2.59}/src/fastled/client_server.py +8 -7
- {fastled-1.2.50 → fastled-1.2.59}/src/fastled/docker_manager.py +2 -1
- {fastled-1.2.50 → fastled-1.2.59}/src/fastled/filewatcher.py +78 -1
- fastled-1.2.59/src/fastled/keyz.py +30 -0
- {fastled-1.2.50 → fastled-1.2.59}/src/fastled/open_browser.py +55 -65
- fastled-1.2.59/src/fastled/open_browser2.py +108 -0
- fastled-1.2.59/src/fastled/server_fastapi.py +60 -0
- fastled-1.2.59/src/fastled/server_fastapi_cli.py +60 -0
- {fastled-1.2.50 → fastled-1.2.59}/src/fastled/settings.py +1 -0
- {fastled-1.2.50 → fastled-1.2.59}/src/fastled/site/build.py +2 -10
- fastled-1.2.59/src/fastled/site/examples.py +10 -0
- {fastled-1.2.50 → fastled-1.2.59}/src/fastled/string_diff.py +23 -5
- {fastled-1.2.50 → fastled-1.2.59}/src/fastled.egg-info/PKG-INFO +17 -4
- {fastled-1.2.50 → fastled-1.2.59}/src/fastled.egg-info/SOURCES.txt +31 -21
- {fastled-1.2.50 → fastled-1.2.59}/src/fastled.egg-info/requires.txt +3 -2
- {fastled-1.2.50 → fastled-1.2.59}/test +2 -2
- {fastled-1.2.50/tests → fastled-1.2.59/tests/integration}/test_build_examples.py +12 -1
- {fastled-1.2.50/tests → fastled-1.2.59/tests/integration}/test_examples.py +1 -1
- {fastled-1.2.50/tests → fastled-1.2.59/tests/unit}/test_embedded_data.py +8 -2
- {fastled-1.2.50/tests → fastled-1.2.59/tests/unit}/test_http_server.py +2 -2
- fastled-1.2.59/tests/unit/test_string_diff.py +80 -0
- fastled-1.2.50/compiler/entrypoint.sh +0 -7
- fastled-1.2.50/compiler/requirements.txt +0 -12
- fastled-1.2.50/src/fastled/open_browser2.py +0 -111
- {fastled-1.2.50 → fastled-1.2.59}/.aiderignore +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/.dockerignore +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/.github/workflows/build_multi_docker_image.yml +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/.github/workflows/build_webpage.yml +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/.github/workflows/lint.yml +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/.github/workflows/publish_release.yml +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/.github/workflows/template_build_docker_image.yml +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/.github/workflows/test_build_exe.yml +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/.pylintrc +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/.vscode/launch.json +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/.vscode/settings.json +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/.vscode/tasks.json +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/LICENSE +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/MANIFEST.in +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/RELEASE.md +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/TODO.md +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/build_exe.py +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/build_site.py +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/clean +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/compiler/CMakeLists.txt +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/compiler/__init__.py +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/compiler/arduino-pre-process.sh +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/compiler/build.sh +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/compiler/build_archive.sh +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/compiler/build_fast.sh +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/compiler/code_sync.py +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/compiler/compile_lock.py +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/compiler/extra/100dots.html +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/compiler/extra/demo_threejs.html +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/compiler/extra/webgl_postprocessing_unreal_bloom.html +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/compiler/final_prewarm.sh +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/compiler/init_runtime.py +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/compiler/install-arduino-cli.sh +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/compiler/libcompile/CMakeLists.txt +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/compiler/paths.py +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/compiler/pre-process.sh +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/compiler/prewarm.sh +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/compiler/process-ino.py +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/compiler/run.py +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/compiler/sketch_hasher.py +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/compiler/wasm_compiler_flags.py +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/docker-compose.yml +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/install +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/install_linux.sh +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/requirements.testing.txt +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/setup.cfg +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/setup.py +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/src/fastled/assets/example.txt +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/src/fastled/cli.py +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/src/fastled/compile_server.py +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/src/fastled/compile_server_impl.py +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/src/fastled/interactive_srcs.py +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/src/fastled/keyboard.py +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/src/fastled/live_client.py +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/src/fastled/parse_args.py +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/src/fastled/paths.py +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/src/fastled/project_init.py +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/src/fastled/select_sketch_directory.py +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/src/fastled/sketch.py +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/src/fastled/spinner.py +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/src/fastled/test/can_run_local_docker_tests.py +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/src/fastled/test/examples.py +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/src/fastled/types.py +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/src/fastled/util.py +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/src/fastled/web_compile.py +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/src/fastled.egg-info/dependency_links.txt +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/src/fastled.egg-info/entry_points.txt +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/src/fastled.egg-info/top_level.txt +0 -0
- {fastled-1.2.50/tests → fastled-1.2.59/tests/unit}/html/index.html +0 -0
- {fastled-1.2.50/tests → fastled-1.2.59/tests/unit}/test_api.py +0 -0
- {fastled-1.2.50/tests → fastled-1.2.59/tests/unit}/test_bad_ino.py +0 -0
- {fastled-1.2.50/tests → fastled-1.2.59/tests/unit}/test_cli.py +0 -0
- {fastled-1.2.50/tests → fastled-1.2.59/tests/unit}/test_compile_server.py +0 -0
- {fastled-1.2.50/tests → fastled-1.2.59/tests/unit}/test_docker_linux_on_windows.py +0 -0
- {fastled-1.2.50/tests → fastled-1.2.59/tests/unit}/test_filechanger.py +0 -0
- {fastled-1.2.50/tests → fastled-1.2.59/tests/unit}/test_ino/bad/bad.ino +0 -0
- {fastled-1.2.50/tests → fastled-1.2.59/tests/unit}/test_ino/bad_platformio/bad_platformio.ino +0 -0
- {fastled-1.2.50/tests → fastled-1.2.59/tests/unit}/test_ino/bad_platformio/platformio.ini +0 -0
- {fastled-1.2.50/tests → fastled-1.2.59/tests/unit}/test_ino/embedded/data/bigdata.dat +0 -0
- {fastled-1.2.50/tests → fastled-1.2.59/tests/unit}/test_ino/embedded/wasm.ino +0 -0
- {fastled-1.2.50/tests → fastled-1.2.59/tests/unit}/test_ino/wasm/wasm.ino +0 -0
- {fastled-1.2.50/tests → fastled-1.2.59/tests/unit}/test_project_init.py +0 -0
- {fastled-1.2.50/tests → fastled-1.2.59/tests/unit}/test_server_and_client_seperatly.py +0 -0
- {fastled-1.2.50/tests → fastled-1.2.59/tests/unit}/test_webcompile.py +0 -0
- {fastled-1.2.50 → fastled-1.2.59}/upload_package.sh +0 -0
@@ -26,4 +26,4 @@ jobs:
|
|
26
26
|
run: ./test
|
27
27
|
|
28
28
|
- name: live run
|
29
|
-
run: pip install . && cd tests/test_ino/wasm && sudo rm -rf fastled_js && time fastled-wasm --just-compile && find fastled_js | sort
|
29
|
+
run: pip install . && cd tests/unit/test_ino/wasm && sudo rm -rf fastled_js && time fastled-wasm --just-compile && find fastled_js | sort
|
@@ -26,4 +26,4 @@ jobs:
|
|
26
26
|
run: ./test
|
27
27
|
|
28
28
|
- name: live run
|
29
|
-
run: pip install . && cd tests/test_ino/wasm && sudo rm -rf fastled_js && time fastled-wasm --just-compile && find fastled_js | sort
|
29
|
+
run: pip install . && cd tests/unit/test_ino/wasm && sudo rm -rf fastled_js && time fastled-wasm --just-compile && find fastled_js | sort
|
@@ -28,5 +28,5 @@ jobs:
|
|
28
28
|
shell: bash -l {0}
|
29
29
|
|
30
30
|
- name: live run
|
31
|
-
run: pip install . && cd tests/test_ino/wasm && rm -rf fastled_js && time fastled-wasm --web --just-compile && find fastled_js | sort
|
31
|
+
run: pip install . && cd tests/unit/test_ino/wasm && rm -rf fastled_js && time fastled-wasm --web --just-compile && find fastled_js | sort
|
32
32
|
shell: bash -l {0}
|
@@ -124,8 +124,8 @@ RUN echo 'export LANG=en_US.UTF-8' >> /etc/profile && \
|
|
124
124
|
RUN pip install uv==0.6.5
|
125
125
|
|
126
126
|
# Get the compiler requirements and install them.
|
127
|
-
COPY compiler/
|
128
|
-
RUN uv pip install --system -r /install/
|
127
|
+
COPY compiler/pyproject.toml /install/pyproject.toml
|
128
|
+
RUN uv pip install --system -r /install/pyproject.toml
|
129
129
|
|
130
130
|
RUN pio settings set check_platformio_interval 9999
|
131
131
|
RUN pio settings set enable_telemetry 0
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: fastled
|
3
|
-
Version: 1.2.
|
3
|
+
Version: 1.2.59
|
4
4
|
Summary: FastLED Wasm Compiler
|
5
5
|
Home-page: https://github.com/zackees/fastled-wasm
|
6
6
|
Maintainer: Zachary Vorhies
|
@@ -19,8 +19,9 @@ Requires-Dist: disklru>=2.0.1
|
|
19
19
|
Requires-Dist: appdirs>=1.4.4
|
20
20
|
Requires-Dist: rapidfuzz>=3.10.1
|
21
21
|
Requires-Dist: progress>=1.6
|
22
|
-
Requires-Dist:
|
23
|
-
Requires-Dist:
|
22
|
+
Requires-Dist: fastapi>=0.115.12
|
23
|
+
Requires-Dist: uvicorn>=0.34.2
|
24
|
+
Requires-Dist: pywebview>=5.4
|
24
25
|
Dynamic: home-page
|
25
26
|
Dynamic: license-file
|
26
27
|
Dynamic: maintainer
|
@@ -295,8 +296,8 @@ A: `delay()` will block `loop()` which blocks the main thread of the browser. Th
|
|
295
296
|
Q: How can I get the compiled size of my FastLED sketch smaller?
|
296
297
|
A: A big chunk of space is being used by unnecessary javascript `emscripten` bundling. The wasm_compiler_settings.py file in the FastLED repo can tweak this.
|
297
298
|
|
298
|
-
# Revisions
|
299
299
|
|
300
|
+
# Revisions
|
300
301
|
* 1.2.31 - Bunch of fixes and ease of use while compiling code in the repo.
|
301
302
|
* 1.2.22 - Prefer to use `live-server` from npm. If npm exists on the system then do a background install of `live-server` for next run.
|
302
303
|
* 1.2.20 - Fixed up path issue for web browser launch for hot reload.
|
@@ -382,3 +383,15 @@ A: A big chunk of space is being used by unnecessary javascript `emscripten` bun
|
|
382
383
|
* 1.0.2 - Small bug with new installs.
|
383
384
|
* 1.0.1 - Re-use is no longer the default, due to problems.
|
384
385
|
* 1.0.0 - Initial release.
|
386
|
+
|
387
|
+
|
388
|
+
# TODO
|
389
|
+
* `live-server --https --cert=localhost.pem --key=localhost-key.pem --port=5500`
|
390
|
+
* `live-server --port=8416 --host=localhost . --https --cert=C:/Users/niteris/dev/fastled-wasm/src/fastled/assets/localhost-key.pem --key=C:/Users/niteris/dev/fastled-wasm/src/fastled/assets/localhost.pem --no-browser`
|
391
|
+
|
392
|
+
|
393
|
+
|
394
|
+
live-server --https --port=8416 --host=localhost . --cert=C:/Users/niteris/dev/fastled-wasm/src/fastled/assets/localhost-key.pem --key=C:/Users/niteris/dev/fastled-wasm/src/fastled/assets/localhost.pem --no-browser
|
395
|
+
|
396
|
+
|
397
|
+
live-server --https --cert=src/fastled/assets/localhost.pem --key=src/fastled/assets/localhost-key.pem --port=5500
|
@@ -268,8 +268,8 @@ A: `delay()` will block `loop()` which blocks the main thread of the browser. Th
|
|
268
268
|
Q: How can I get the compiled size of my FastLED sketch smaller?
|
269
269
|
A: A big chunk of space is being used by unnecessary javascript `emscripten` bundling. The wasm_compiler_settings.py file in the FastLED repo can tweak this.
|
270
270
|
|
271
|
-
# Revisions
|
272
271
|
|
272
|
+
# Revisions
|
273
273
|
* 1.2.31 - Bunch of fixes and ease of use while compiling code in the repo.
|
274
274
|
* 1.2.22 - Prefer to use `live-server` from npm. If npm exists on the system then do a background install of `live-server` for next run.
|
275
275
|
* 1.2.20 - Fixed up path issue for web browser launch for hot reload.
|
@@ -355,3 +355,15 @@ A: A big chunk of space is being used by unnecessary javascript `emscripten` bun
|
|
355
355
|
* 1.0.2 - Small bug with new installs.
|
356
356
|
* 1.0.1 - Re-use is no longer the default, due to problems.
|
357
357
|
* 1.0.0 - Initial release.
|
358
|
+
|
359
|
+
|
360
|
+
# TODO
|
361
|
+
* `live-server --https --cert=localhost.pem --key=localhost-key.pem --port=5500`
|
362
|
+
* `live-server --port=8416 --host=localhost . --https --cert=C:/Users/niteris/dev/fastled-wasm/src/fastled/assets/localhost-key.pem --key=C:/Users/niteris/dev/fastled-wasm/src/fastled/assets/localhost.pem --no-browser`
|
363
|
+
|
364
|
+
|
365
|
+
|
366
|
+
live-server --https --port=8416 --host=localhost . --cert=C:/Users/niteris/dev/fastled-wasm/src/fastled/assets/localhost-key.pem --key=C:/Users/niteris/dev/fastled-wasm/src/fastled/assets/localhost.pem --no-browser
|
367
|
+
|
368
|
+
|
369
|
+
live-server --https --cert=src/fastled/assets/localhost.pem --key=src/fastled/assets/localhost-key.pem --port=5500
|
@@ -40,6 +40,7 @@ _FASTLED_MODULES_DIR = FASTLED_COMPILER_DIR / "modules"
|
|
40
40
|
_INDEX_HTML_SRC = FASTLED_COMPILER_DIR / "index.html"
|
41
41
|
_INDEX_CSS_SRC = FASTLED_COMPILER_DIR / "index.css"
|
42
42
|
_INDEX_JS_SRC = FASTLED_COMPILER_DIR / "index.js"
|
43
|
+
_PIO_VERBOSE = True
|
43
44
|
|
44
45
|
|
45
46
|
_WASM_COMPILER_SETTTINGS = FASTLED_COMPILER_DIR / "wasm_compiler_flags.py"
|
@@ -108,6 +109,8 @@ def compile(
|
|
108
109
|
cmd_list.extend(["pio", "run"])
|
109
110
|
if not auto_clean:
|
110
111
|
cmd_list.append("--disable-auto-clean")
|
112
|
+
if _PIO_VERBOSE:
|
113
|
+
cmd_list.append("-v")
|
111
114
|
|
112
115
|
def _open_process(cmd_list: list[str] = cmd_list) -> subprocess.Popen:
|
113
116
|
out = subprocess.Popen(
|
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
# load emsdk environment
|
4
|
+
source /emsdk/emsdk_env.sh
|
5
|
+
export PATH="$PATH:/emsdk/upstream/bin"
|
6
|
+
|
7
|
+
# initialize runtime
|
8
|
+
python init_runtime.py
|
9
|
+
|
10
|
+
# only do the final prewarm if RUNTIME_PREWARM is set to "1"
|
11
|
+
if [[ "${RUNTIME_PREWARM:-0}" == "1" ]]; then
|
12
|
+
./final_prewarm.sh
|
13
|
+
fi
|
14
|
+
|
15
|
+
# hand off to the main command
|
16
|
+
exec "$@"
|
@@ -0,0 +1,136 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html lang="en">
|
3
|
+
<head>
|
4
|
+
<meta charset="UTF-8">
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
6
|
+
<title>Mic & System Audio Demo</title>
|
7
|
+
<style>
|
8
|
+
body { font-family: sans-serif; text-align: center; padding: 2rem; }
|
9
|
+
#controls { margin-bottom: 1rem; }
|
10
|
+
#volume { font-size: 2rem; margin-bottom: 1rem; }
|
11
|
+
#bar {
|
12
|
+
width: 300px;
|
13
|
+
height: 30px;
|
14
|
+
background: #eee;
|
15
|
+
margin: 0 auto;
|
16
|
+
border: 1px solid #ccc;
|
17
|
+
border-radius: 4px;
|
18
|
+
overflow: hidden;
|
19
|
+
}
|
20
|
+
#fill {
|
21
|
+
height: 100%;
|
22
|
+
width: 0%;
|
23
|
+
background: #76ce60;
|
24
|
+
transition: width 0.1s ease;
|
25
|
+
}
|
26
|
+
#mic-select { margin-left: 0.5rem; }
|
27
|
+
</style>
|
28
|
+
</head>
|
29
|
+
<body>
|
30
|
+
<h1>Audio Volume Demo</h1>
|
31
|
+
<div id="controls">
|
32
|
+
<label><input type="radio" name="source" value="mic" checked> Microphone</label>
|
33
|
+
<label><input type="radio" name="source" value="tab"> Tab/Screen Audio</label>
|
34
|
+
<select id="mic-select"></select>
|
35
|
+
</div>
|
36
|
+
<div id="volume">-∞ dBFS</div>
|
37
|
+
<div id="bar"><div id="fill"></div></div>
|
38
|
+
|
39
|
+
<script>
|
40
|
+
let audioCtx, analyser, dataArray;
|
41
|
+
let currentStream;
|
42
|
+
|
43
|
+
async function listAudioInputs() {
|
44
|
+
const devices = await navigator.mediaDevices.enumerateDevices();
|
45
|
+
const mics = devices.filter(d => d.kind === 'audioinput');
|
46
|
+
const select = document.getElementById('mic-select');
|
47
|
+
select.innerHTML = '';
|
48
|
+
mics.forEach((mic, i) => {
|
49
|
+
const option = document.createElement('option');
|
50
|
+
option.value = mic.deviceId;
|
51
|
+
option.text = mic.label || `Microphone ${i+1}`;
|
52
|
+
select.appendChild(option);
|
53
|
+
});
|
54
|
+
select.onchange = () => startMic(select.value);
|
55
|
+
if (mics.length) startMic(mics[0].deviceId);
|
56
|
+
}
|
57
|
+
|
58
|
+
async function startMic(deviceId) {
|
59
|
+
stopStream();
|
60
|
+
try {
|
61
|
+
currentStream = await navigator.mediaDevices.getUserMedia({ audio: { deviceId: { exact: deviceId } } });
|
62
|
+
setupAudioGraph(currentStream);
|
63
|
+
} catch (err) {
|
64
|
+
alert('Error accessing microphone: ' + err.message);
|
65
|
+
}
|
66
|
+
}
|
67
|
+
|
68
|
+
async function startTabAudio() {
|
69
|
+
stopStream();
|
70
|
+
try {
|
71
|
+
currentStream = await navigator.mediaDevices.getDisplayMedia({ audio: true, video: false });
|
72
|
+
setupAudioGraph(currentStream);
|
73
|
+
} catch (err) {
|
74
|
+
alert('Error capturing tab/screen audio: ' + err.message);
|
75
|
+
}
|
76
|
+
}
|
77
|
+
|
78
|
+
function stopStream() {
|
79
|
+
if (currentStream) {
|
80
|
+
currentStream.getTracks().forEach(track => track.stop());
|
81
|
+
}
|
82
|
+
}
|
83
|
+
|
84
|
+
function setupAudioGraph(stream) {
|
85
|
+
if (!audioCtx) {
|
86
|
+
audioCtx = new (window.AudioContext || window.webkitAudioContext)();
|
87
|
+
}
|
88
|
+
const source = audioCtx.createMediaStreamSource(stream);
|
89
|
+
analyser = audioCtx.createAnalyser();
|
90
|
+
analyser.fftSize = 2048;
|
91
|
+
source.connect(analyser);
|
92
|
+
dataArray = new Float32Array(analyser.fftSize);
|
93
|
+
updateVolume();
|
94
|
+
}
|
95
|
+
|
96
|
+
function updateVolume() {
|
97
|
+
analyser.getFloatTimeDomainData(dataArray);
|
98
|
+
let max = 0;
|
99
|
+
for (let i = 0; i < dataArray.length; i++) {
|
100
|
+
const v = Math.abs(dataArray[i]);
|
101
|
+
if (v > max) max = v;
|
102
|
+
}
|
103
|
+
|
104
|
+
const db = max > 0 ? 20 * Math.log10(max) : -Infinity;
|
105
|
+
const dbDisplay = db === -Infinity ? '-∞' : db.toFixed(1);
|
106
|
+
document.getElementById('volume').textContent = `${dbDisplay} dBFS`;
|
107
|
+
|
108
|
+
const percent = Math.min(max * 100, 100);
|
109
|
+
document.getElementById('fill').style.width = percent + '%';
|
110
|
+
|
111
|
+
requestAnimationFrame(updateVolume);
|
112
|
+
}
|
113
|
+
|
114
|
+
// Switcher
|
115
|
+
document.querySelectorAll('input[name="source"]').forEach(radio => {
|
116
|
+
radio.addEventListener('change', e => {
|
117
|
+
const mode = e.target.value;
|
118
|
+
if (mode === 'mic') {
|
119
|
+
document.getElementById('mic-select').style.display = '';
|
120
|
+
listAudioInputs();
|
121
|
+
} else {
|
122
|
+
document.getElementById('mic-select').style.display = 'none';
|
123
|
+
startTabAudio();
|
124
|
+
}
|
125
|
+
});
|
126
|
+
});
|
127
|
+
|
128
|
+
// Initialize
|
129
|
+
if (navigator.mediaDevices && navigator.mediaDevices.enumerateDevices) {
|
130
|
+
listAudioInputs();
|
131
|
+
} else {
|
132
|
+
alert('enumerateDevices() not supported.');
|
133
|
+
}
|
134
|
+
</script>
|
135
|
+
</body>
|
136
|
+
</html>
|
@@ -0,0 +1,109 @@
|
|
1
|
+
"""
|
2
|
+
Experimental module that extends the multiprocessing.Process class to redirect
|
3
|
+
stdout and stderr to pipes that can be read line-by-line in real time.
|
4
|
+
|
5
|
+
"""
|
6
|
+
|
7
|
+
import multiprocessing
|
8
|
+
import os
|
9
|
+
import sys
|
10
|
+
import time
|
11
|
+
|
12
|
+
|
13
|
+
class ProcessExtended(multiprocessing.Process):
|
14
|
+
def __init__(self, target, args=(), kwargs=None):
|
15
|
+
if kwargs is None:
|
16
|
+
kwargs = {}
|
17
|
+
# Store the target function and its arguments.
|
18
|
+
self._target_func = target
|
19
|
+
self._target_args = args
|
20
|
+
self._target_kwargs = kwargs
|
21
|
+
# Create OS pipes for stdout and stderr.
|
22
|
+
self._stdout_pipe_read, self._stdout_pipe_write = os.pipe()
|
23
|
+
self._stderr_pipe_read, self._stderr_pipe_write = os.pipe()
|
24
|
+
super().__init__()
|
25
|
+
|
26
|
+
def run(self):
|
27
|
+
"""
|
28
|
+
In the child process, close the parent's copy of the read ends,
|
29
|
+
duplicate the write ends to stdout and stderr, and execute the target function.
|
30
|
+
"""
|
31
|
+
# In child: close the parent's read ends.
|
32
|
+
os.close(self._stdout_pipe_read)
|
33
|
+
os.close(self._stderr_pipe_read)
|
34
|
+
|
35
|
+
# Redirect stdout and stderr to the write ends of the pipes.
|
36
|
+
os.dup2(self._stdout_pipe_write, sys.stdout.fileno())
|
37
|
+
os.dup2(self._stderr_pipe_write, sys.stderr.fileno())
|
38
|
+
|
39
|
+
# Reassign the Python-level streams with line buffering.
|
40
|
+
sys.stdout = os.fdopen(sys.stdout.fileno(), "w", buffering=1)
|
41
|
+
sys.stderr = os.fdopen(sys.stderr.fileno(), "w", buffering=1)
|
42
|
+
|
43
|
+
try:
|
44
|
+
self._target_func(*self._target_args, **self._target_kwargs)
|
45
|
+
finally:
|
46
|
+
# Flush and close the write ends so the parent can detect EOF.
|
47
|
+
sys.stdout.flush()
|
48
|
+
sys.stderr.flush()
|
49
|
+
os.close(self._stdout_pipe_write)
|
50
|
+
os.close(self._stderr_pipe_write)
|
51
|
+
|
52
|
+
def start(self):
|
53
|
+
"""
|
54
|
+
Start the child process and, in the parent process, close the write ends
|
55
|
+
of the pipes so that reading from the read ends will end once the child closes them.
|
56
|
+
"""
|
57
|
+
super().start()
|
58
|
+
# In the parent process, close the write ends.
|
59
|
+
os.close(self._stdout_pipe_write)
|
60
|
+
os.close(self._stderr_pipe_write)
|
61
|
+
|
62
|
+
@property
|
63
|
+
def stdout(self):
|
64
|
+
"""
|
65
|
+
Returns a file object that can be iterated line-by-line to read the child's stdout.
|
66
|
+
"""
|
67
|
+
if not hasattr(self, "_stdout_file"):
|
68
|
+
self._stdout_file = os.fdopen(self._stdout_pipe_read, "r", buffering=1)
|
69
|
+
return self._stdout_file
|
70
|
+
|
71
|
+
@property
|
72
|
+
def stderr(self):
|
73
|
+
"""
|
74
|
+
Returns a file object that can be iterated line-by-line to read the child's stderr.
|
75
|
+
"""
|
76
|
+
if not hasattr(self, "_stderr_file"):
|
77
|
+
self._stderr_file = os.fdopen(self._stderr_pipe_read, "r", buffering=1)
|
78
|
+
return self._stderr_file
|
79
|
+
|
80
|
+
|
81
|
+
# -------------------------------
|
82
|
+
# Example usage:
|
83
|
+
# -------------------------------
|
84
|
+
def worker():
|
85
|
+
for i in range(5):
|
86
|
+
print(f"stdout line {i}")
|
87
|
+
print(f"stderr line {i}", file=sys.stderr)
|
88
|
+
time.sleep(1)
|
89
|
+
|
90
|
+
|
91
|
+
if __name__ == "__main__":
|
92
|
+
proc = ProcessExtended(target=worker)
|
93
|
+
proc.start()
|
94
|
+
|
95
|
+
# Iterate over stdout in real time.
|
96
|
+
# Note: In a real-world scenario you might want to use threads or select/poll to
|
97
|
+
# concurrently process stdout and stderr if both are needed in real time.
|
98
|
+
try:
|
99
|
+
for line in proc.stdout:
|
100
|
+
print("Streamed stdout:", line, end="")
|
101
|
+
except KeyboardInterrupt:
|
102
|
+
pass
|
103
|
+
|
104
|
+
# Wait for the process to finish.
|
105
|
+
proc.join()
|
106
|
+
|
107
|
+
# Optionally, process any remaining stderr output.
|
108
|
+
for line in proc.stderr:
|
109
|
+
print("Streamed stderr:", line, end="")
|
@@ -0,0 +1,22 @@
|
|
1
|
+
[build-system]
|
2
|
+
requires = ["setuptools>=42", "wheel"]
|
3
|
+
build-backend = "setuptools.build_meta"
|
4
|
+
|
5
|
+
[project]
|
6
|
+
name = "fastled_server"
|
7
|
+
version = "0.1.0"
|
8
|
+
description = "FastLED Server"
|
9
|
+
requires-python = ">=3.10"
|
10
|
+
|
11
|
+
dependencies = [
|
12
|
+
"platformio==6.1.17",
|
13
|
+
"fastapi==0.115.11",
|
14
|
+
"uvicorn[standard]==0.34.0",
|
15
|
+
"python-multipart==0.0.20",
|
16
|
+
"disklru==2.0.0",
|
17
|
+
"psutil==6.1.1",
|
18
|
+
"wormhole-tx",
|
19
|
+
]
|
20
|
+
|
21
|
+
[tool.setuptools]
|
22
|
+
package-dir = {"" = "."}
|
@@ -11,9 +11,7 @@ echo Running black src tests compiler
|
|
11
11
|
black src tests compiler
|
12
12
|
echo Running isort src tests compiler
|
13
13
|
isort --profile black src tests compiler
|
14
|
-
echo Running mypy src compiler
|
15
|
-
mypy src tests compiler
|
16
14
|
echo Running pyright src tests compiler
|
17
|
-
pyright src compiler tests
|
15
|
+
uv run pyright src compiler tests
|
18
16
|
echo Linting complete!
|
19
17
|
exit 0
|
@@ -13,7 +13,7 @@ from .types import BuildMode, CompileResult, CompileServerError
|
|
13
13
|
# IMPORTANT! There's a bug in github which will REJECT any version update
|
14
14
|
# that has any other change in the repo. Please bump the version as the
|
15
15
|
# ONLY change in a commit, or else the pypi update and the release will fail.
|
16
|
-
__version__ = "1.2.
|
16
|
+
__version__ = "1.2.59"
|
17
17
|
|
18
18
|
DOCKER_FILE = (
|
19
19
|
"https://raw.githubusercontent.com/zackees/fastled-wasm/refs/heads/main/Dockerfile"
|
@@ -122,8 +122,7 @@ if __name__ == "__main__":
|
|
122
122
|
import os
|
123
123
|
|
124
124
|
os.chdir("../fastled")
|
125
|
-
sys.argv.append("examples/
|
126
|
-
sys.argv.append("--just-compile")
|
125
|
+
sys.argv.append("examples/FxWave2d")
|
127
126
|
sys.exit(main())
|
128
127
|
except KeyboardInterrupt:
|
129
128
|
print("\nExiting from main...")
|
@@ -0,0 +1,28 @@
|
|
1
|
+
-----BEGIN PRIVATE KEY-----
|
2
|
+
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDlxbWcpUXPpjqs
|
3
|
+
DJPgFF1FsXPZqq0JPJqssHh4ZLfN0h4yJmj+kRcHS+pkgXnG46g6bUcL/AK5Ba08
|
4
|
+
vwnUUGkPH0v4ShKiAGYwvOcbWaqTmvvJuIoaDBXh2jSCeOTagNoaHLYEugARkkEu
|
5
|
+
0/FEW5P/79wU5vJ5G+SyZ8rBCVdxlU57pL1hKWBU7K+BLWsCiZ308NMpzHF5APZ6
|
6
|
+
YxVjhFosJPr4TjN6yXr+whrsAjSTHamD5690MbXWyyPG0jwPQyjBot/cNtt8GrsN
|
7
|
+
gcjA1E+8VKFvxO8RvZanMZLb0CGEpt7u3oaJ/jprHEsw+/UhnG6Qhksm8C/DN9kP
|
8
|
+
hselewffAgMBAAECggEARjQ6YTo+Mkvf8WGGbRjLxteJRiBX7lKOD+V7aY2ce06P
|
9
|
+
21LREbbTCm+vljXZN2OnqvJomsjNLCsH21+jaTOIZg5x79LyDn2Au7N8CWdELwVT
|
10
|
+
mTbBO2Ql63P4R0UY54onGYNcOeV6z+OX9u7a8L/qYHCxFdHalBZpsfj0gjaQeStJ
|
11
|
+
JSnvGjo6tKkwC/nUmX01qEVQgUO1+39WYqCaIWjijZNXt6XiKclEuu1AkL0u6Mpt
|
12
|
+
CzvzEDrEA66D0Lvl3Tek9B4O16Oie5anNnNMHigwU9yVc6dI8vDCRSEiz7laPTFK
|
13
|
+
xzOCQmqPGClKXkX3U+OvZp/Ss9U26Wpu0AbRKTvzAQKBgQDsMR9NjMpOmUaWkAwl
|
14
|
+
1wlUxsZ9YkRuTy7R3RfIdYWj6Lcoc4/iN0qILFM7xidkHhYTFqnsnP1SQkV6lEHV
|
15
|
+
OalYxZu9F2l1rHPc8G5YWh/KOg1rAEI47MVT4iwhA2fw6JLti/rm25AeSTMjSTqu
|
16
|
+
ht3146036opcIF3v86oGUrSXDwKBgQD5CsNcwLeUDGXozjq62T8/mTYwd2Tw3aiY
|
17
|
+
KaGp+exAW321vYm5SKsMitBMGU2tGFlv5eptSI48h7SCpgnszaexw7yj30KuvqjG
|
18
|
+
bBqq/MsKuXHyn2sG0A7MJ6zfk+4l46B45blDJZ+x7xL0dyS4UCU3zUeesgSGo4zK
|
19
|
+
ZOspPIQCMQKBgQCk35VuWP1P6IbxyxPvxi/pUeh01gfWyMdyD9fuQrtLM8PHJQQn
|
20
|
+
cVlBvU9MxoHwzV+za3qqhNwAc+p0KtHZuiqQoUCZuqIPVpZ6gAtG+YJ/dA6xxrhz
|
21
|
+
bDRC3frYALyp2m/WCoTWaiYsPgTIePHRqqt+XbQo+DwlGyL3wSvKxijx2QKBgCb0
|
22
|
+
OwioEE70/X/DukX9szn0chh0pHJUiYl7gZD/yadraCdkRUWZC0BD+j7c+lxn4Z1y
|
23
|
+
HhAH+E+Zfm+tHwJOTLuufTQ4uMpygh2/TRCPyAaeaSdlLi17n8TpM84o6mg8yZ3/
|
24
|
+
eNH68Za4aYOZm0HFL30h++DjwXd534zM6keh8pgRAoGBAKUrsjDGjuSo8l1fi4Cq
|
25
|
+
INu/rQop2h/db02zyJP5q7NKhE1nqogeLwwn+2M/LtHQ1nIzZR+rvrLNgt6oWY31
|
26
|
+
sPsv8JUfVT8GmdhU9KKmizK6eUu3rWdj2+rJARmuEaPmHcD5O6oJaGU0qadqQP34
|
27
|
+
H+enwWmpyZXAIbEu/q63DFhV
|
28
|
+
-----END PRIVATE KEY-----
|
@@ -0,0 +1,27 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIIEfTCCAuWgAwIBAgIRAPb7jkLrCuqToG+s3AQYeuUwDQYJKoZIhvcNAQELBQAw
|
3
|
+
gakxHjAcBgNVBAoTFW1rY2VydCBkZXZlbG9wbWVudCBDQTE/MD0GA1UECww2REVT
|
4
|
+
S1RPUC1JMzcxOERPXFphY2ggVm9yaGllc0BERVNLVE9QLUkzNzE4RE8gKG5pdGVy
|
5
|
+
aXMpMUYwRAYDVQQDDD1ta2NlcnQgREVTS1RPUC1JMzcxOERPXFphY2ggVm9yaGll
|
6
|
+
c0BERVNLVE9QLUkzNzE4RE8gKG5pdGVyaXMpMB4XDTI1MDQyODAwMzk1MFoXDTI3
|
7
|
+
MDcyODAwMzk1MFowajEnMCUGA1UEChMebWtjZXJ0IGRldmVsb3BtZW50IGNlcnRp
|
8
|
+
ZmljYXRlMT8wPQYDVQQLDDZERVNLVE9QLUkzNzE4RE9cWmFjaCBWb3JoaWVzQERF
|
9
|
+
U0tUT1AtSTM3MThETyAobml0ZXJpcykwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
|
10
|
+
ggEKAoIBAQDlxbWcpUXPpjqsDJPgFF1FsXPZqq0JPJqssHh4ZLfN0h4yJmj+kRcH
|
11
|
+
S+pkgXnG46g6bUcL/AK5Ba08vwnUUGkPH0v4ShKiAGYwvOcbWaqTmvvJuIoaDBXh
|
12
|
+
2jSCeOTagNoaHLYEugARkkEu0/FEW5P/79wU5vJ5G+SyZ8rBCVdxlU57pL1hKWBU
|
13
|
+
7K+BLWsCiZ308NMpzHF5APZ6YxVjhFosJPr4TjN6yXr+whrsAjSTHamD5690MbXW
|
14
|
+
yyPG0jwPQyjBot/cNtt8GrsNgcjA1E+8VKFvxO8RvZanMZLb0CGEpt7u3oaJ/jpr
|
15
|
+
HEsw+/UhnG6Qhksm8C/DN9kPhselewffAgMBAAGjXjBcMA4GA1UdDwEB/wQEAwIF
|
16
|
+
oDATBgNVHSUEDDAKBggrBgEFBQcDATAfBgNVHSMEGDAWgBSPBydvhr9wI+FsoW/H
|
17
|
+
WK3DbS8IUDAUBgNVHREEDTALgglsb2NhbGhvc3QwDQYJKoZIhvcNAQELBQADggGB
|
18
|
+
AJVrF1yczZaxt+A2AhdeFbJQUR6NzGBTc20YeWF1YzLV5sV3QVumwZLP2M9ggRgd
|
19
|
+
xWV0xfwUHobFQk6RIPTADcLKctiurql0cgF4DPnpWVvto9RM00U3AkQcMj3xtKBV
|
20
|
+
wUqo83TcbqgL+euudFZ09gGTs9u9AENaZPcMh+rW8DDO92t+EwMI/IfopxVOJGUB
|
21
|
+
RSM3yTwV93BMYBuddt8mclzLzPK/1WONfsHU2xEascaHR1tYMOmJN9Vq4o0fzWxo
|
22
|
+
a2vI6K0aJqZV/ztdXq3akwLc6/e9hyptHWa0i/022xVCyNWIlnuEhT7ENMPxh6rX
|
23
|
+
ZCQCZVnhcSWAyFjggLJql3aSID5fPF8rmN7wWsB/I5pl9qwMR1/THMPrm5aWn1Xj
|
24
|
+
xW6PxkSGm73kd57DH7tqm5HTd8eYCbnsFofI9rC7xI6HCfwchKp+YHvIEu/LJ56E
|
25
|
+
FLnCZW/orYkHCzWntzxv1bddrw1BwaNR8Q+mu3imRP8fuyXb2UkFkINVVyOOWHuW
|
26
|
+
Kw==
|
27
|
+
-----END CERTIFICATE-----
|
@@ -0,0 +1,20 @@
|
|
1
|
+
import sys
|
2
|
+
|
3
|
+
from fastled.app import main as app_main
|
4
|
+
|
5
|
+
if __name__ == "__main__":
|
6
|
+
# Note that the entry point for the exe is in cli.py
|
7
|
+
try:
|
8
|
+
import os
|
9
|
+
|
10
|
+
os.chdir("../fastled")
|
11
|
+
# sys.argv.append("--server")
|
12
|
+
# sys.argv.append("--local")
|
13
|
+
sys.argv.append("examples/FxWave2d")
|
14
|
+
sys.exit(app_main())
|
15
|
+
except KeyboardInterrupt:
|
16
|
+
print("\nExiting from main...")
|
17
|
+
sys.exit(1)
|
18
|
+
except Exception as e:
|
19
|
+
print(f"Error: {e}")
|
20
|
+
sys.exit(1)
|
@@ -7,7 +7,7 @@ from pathlib import Path
|
|
7
7
|
|
8
8
|
from fastled.compile_server import CompileServer
|
9
9
|
from fastled.docker_manager import DockerManager
|
10
|
-
from fastled.filewatcher import FileWatcherProcess
|
10
|
+
from fastled.filewatcher import DebouncedFileWatcherProcess, FileWatcherProcess
|
11
11
|
from fastled.keyboard import SpaceBarWatcher
|
12
12
|
from fastled.open_browser import open_browser_process
|
13
13
|
from fastled.parse_args import Args
|
@@ -231,9 +231,8 @@ def run_client(
|
|
231
231
|
return 1
|
232
232
|
|
233
233
|
excluded_patterns = ["fastled_js"]
|
234
|
-
|
235
|
-
|
236
|
-
directory, excluded_patterns=excluded_patterns
|
234
|
+
debounced_sketch_watcher = DebouncedFileWatcherProcess(
|
235
|
+
FileWatcherProcess(directory, excluded_patterns=excluded_patterns),
|
237
236
|
)
|
238
237
|
|
239
238
|
source_code_watcher: FileWatcherProcess | None = None
|
@@ -246,7 +245,7 @@ def run_client(
|
|
246
245
|
def trigger_rebuild_if_sketch_changed(
|
247
246
|
last_compiled_result: CompileResult,
|
248
247
|
) -> tuple[bool, CompileResult]:
|
249
|
-
changed_files =
|
248
|
+
changed_files = debounced_sketch_watcher.get_all_changes()
|
250
249
|
if changed_files:
|
251
250
|
print(f"\nChanges detected in {changed_files}")
|
252
251
|
last_hash_value = last_compiled_result.hash_value
|
@@ -301,7 +300,9 @@ def run_client(
|
|
301
300
|
timeout=1.0
|
302
301
|
)
|
303
302
|
file_changes = source_code_watcher.get_all_changes()
|
304
|
-
sketch_files_changed =
|
303
|
+
sketch_files_changed = (
|
304
|
+
debounced_sketch_watcher.get_all_changes()
|
305
|
+
)
|
305
306
|
|
306
307
|
if file_changes:
|
307
308
|
print(
|
@@ -331,7 +332,7 @@ def run_client(
|
|
331
332
|
print(f"Error: {e}")
|
332
333
|
return 1
|
333
334
|
finally:
|
334
|
-
|
335
|
+
debounced_sketch_watcher.stop()
|
335
336
|
if compile_server:
|
336
337
|
compile_server.stop()
|
337
338
|
if browser_proc:
|
@@ -205,6 +205,7 @@ class DockerManager:
|
|
205
205
|
"""Check if Docker is running by pinging the Docker daemon."""
|
206
206
|
|
207
207
|
if not DockerManager.is_docker_installed():
|
208
|
+
print("Docker is not installed.")
|
208
209
|
return False
|
209
210
|
try:
|
210
211
|
# self.client.ping()
|
@@ -767,7 +768,7 @@ class DockerManager:
|
|
767
768
|
print(f"Error removing images: {e}")
|
768
769
|
|
769
770
|
|
770
|
-
def main():
|
771
|
+
def main() -> None:
|
771
772
|
# Register SIGINT handler
|
772
773
|
# signal.signal(signal.SIGINT, handle_sigint)
|
773
774
|
|