diff --git a/tools/device/start.sh b/tools/device/start.sh new file mode 100644 index 0000000..bff12d4 --- /dev/null +++ b/tools/device/start.sh @@ -0,0 +1,20 @@ +#!/bin/sh +mkdir -p /tmp/venc/c0/; +mkdir -p /tmp/aenc/c0/; +mkdir -p /tmp/playback/c0/; +mkdir -p /tmp/twoway/c0/; +mkdir -p /tmp/sr/c0/; +mkdir -p /tmp/sdcard; +mkdir -p /tmp/canbus/c0/; +mount /dev/mmcblk0p1 /tmp/sdcard 2>/dev/null || true +export LD_LIBRARY_PATH=$(pwd)/lib; +cd ../plus/kp_firmware/kp_firmware_0/kp_firmware/bin +./rtsps -c stream_server_config.ini & +./kp_firmware_host_stream & +#./rtsps -c stream_server_config.ini > /dev/null 2>&1 & +#./kp_firmware_host_stream > /tmp/fw.log 2>&1 & +### Notice : Codec type AAC4, sample rate 8000, bit rate 32000, raw format, stereo, mic_in ### +#./tinyaenc_mmap -d "hw:0,0" -r 8000 -C 0 -b 32000 -t 0 -S 0 -i 0 & +#sleep 2; +#./volume_ctrl -i 0 -M 0 -v 96; +#./playback_example_mmap -d "hw:0,0" -r 8000 -c 2 -C 0 & diff --git a/web_serve.py b/web_serve.py index 7833b3e..0ae4b55 100644 --- a/web_serve.py +++ b/web_serve.py @@ -46,6 +46,7 @@ DEPLOY_SRC = SCRIPT_DIR / "tools" / "device" / "deploy.sh" DEMO_RTSP_SRC = SCRIPT_DIR / "tools" / "device" / "demo_rtsp.sh" DEMO_HDMI_SRC = SCRIPT_DIR / "tools" / "device" / "demo_hdmi.sh" DEMO_RTSP_HDMI_SRC = SCRIPT_DIR / "tools" / "device" / "demo_rtsp_hdmi.sh" +START_SH_SRC = SCRIPT_DIR / "tools" / "device" / "start.sh" NEF_DIR = SCRIPT_DIR / "nef" KCURL_SRC = Path("/home/user/Documents/GOFACE/奧創雲/kCurl-1.1.1-release/kCurl-linux-armv7") CONFIG_FILE = SCRIPT_DIR / ".web_config.json" @@ -93,6 +94,7 @@ def prepare_build_dir(): (DEMO_RTSP_SRC, "demo_rtsp.sh"), (DEMO_HDMI_SRC, "demo_hdmi.sh"), (DEMO_RTSP_HDMI_SRC, "demo_rtsp_hdmi.sh"), + (START_SH_SRC, "start.sh"), ]: if Path(src).exists(): shutil.copy2(src, BUILD_DIR / name) @@ -521,6 +523,9 @@ def api_deploy_run(): ("Pushing deploy.sh to device...", f"wget -q {base}/deploy.sh -O /tmp/deploy.sh && chmod +x /tmp/deploy.sh && echo 'deploy.sh OK'", False, 30), + ("Updating start.sh...", + f"wget -q {base}/start.sh -O /mnt/flash/vienna/start.sh && chmod +x /mnt/flash/vienna/start.sh && echo 'start.sh OK'", + False, 30), ("Downloading kCurl (event upload tool)...", f"wget -q {base}/kCurl -O {bd}/kCurl && chmod +x {bd}/kCurl && echo 'kCurl OK'", False, 30), @@ -562,6 +567,89 @@ def api_deploy_run(): return Response(generate(), mimetype="text/event-stream", headers={"Cache-Control": "no-cache", "X-Accel-Buffering": "no"}) +# ── API: deploy binary only (SSE) ──────────────────────────────────────────── +@app.route("/api/deploy/binary") +def api_deploy_binary(): + cfg = load_config() + kl_ip = request.args.get("ip", cfg["kl630_ip"]) + h_ip = request.args.get("host_ip", cfg["host_ip"]) + port = int(request.args.get("port", cfg["port"])) + base = f"http://{h_ip}:{port}" + fw = FW_PATH_DEVICE + bd = BIN_DIR_DEVICE + out_rtsp = request.args.get("out_rtsp", "1") == "1" + out_hdmi = request.args.get("out_hdmi", "0") == "1" + + if out_hdmi and not out_rtsp: + start_cmd = f"cd {bd} && nohup sh ./ini/demo_hdmi.sh > /tmp/fw.log 2>&1 &" + elif out_rtsp and out_hdmi: + start_cmd = f"cd {bd} && nohup sh ./ini/demo_rtsp_hdmi.sh > /tmp/fw.log 2>&1 &" + else: + start_cmd = f"cd {bd} && nohup sh ./ini/demo_rtsp.sh > /tmp/fw.log 2>&1 &" + + def generate(): + yield sse(f"Connecting to {kl_ip}:23...") + try: + tn = _telnet_connect(kl_ip) + _drain_shell(tn) + yield sse("Connected.", "ok") + + yield sse("Stopping firmware...") + for ln in _telnet_run(tn, "killall -9 kp_firmware_host_stream 2>/dev/null; killall -9 rtsps 2>/dev/null; sleep 1; rm -f /dev/shm/*", timeout=15): + yield sse(ln) + + yield sse("Downloading binary...") + for ln in _telnet_run(tn, f"wget -q {base}/kp_firmware_host_stream -O {fw} && chmod +x {fw} && ls -lh {fw}", timeout=60): + yield sse(ln, "ok") + + yield sse("Restarting firmware...") + for ln in _telnet_run_bg(tn, start_cmd): + if ln.strip(): yield sse(ln.strip()) + + ok, lines = _verify_firmware_running(tn) + for ln in lines: + yield sse(ln, "ok" if ok else "warn") + if ok: + yield sse("Binary updated and firmware running.", "ok") + else: + yield sse("Firmware may not have started — check /tmp/fw.log", "warn") + tn.close() + except Exception as e: + yield sse(f"Telnet error: {e}", "error") + yield sse_done() + + return Response(generate(), mimetype="text/event-stream", + headers={"Cache-Control": "no-cache", "X-Accel-Buffering": "no"}) + +# ── API: deploy start.sh only (SSE) ────────────────────────────────────────── +@app.route("/api/deploy/startsh") +def api_deploy_startsh(): + cfg = load_config() + kl_ip = request.args.get("ip", cfg["kl630_ip"]) + h_ip = request.args.get("host_ip", cfg["host_ip"]) + port = int(request.args.get("port", cfg["port"])) + base = f"http://{h_ip}:{port}" + + def generate(): + yield sse(f"Connecting to {kl_ip}:23...") + try: + tn = _telnet_connect(kl_ip) + _drain_shell(tn) + yield sse("Connected.", "ok") + + yield sse("Updating start.sh...") + for ln in _telnet_run(tn, f"wget -q {base}/start.sh -O /mnt/flash/vienna/start.sh && chmod +x /mnt/flash/vienna/start.sh && echo 'start.sh OK'", timeout=30): + yield sse(ln, "ok") + + tn.close() + yield sse("start.sh updated. Takes effect on next reboot.", "ok") + except Exception as e: + yield sse(f"Telnet error: {e}", "error") + yield sse_done() + + return Response(generate(), mimetype="text/event-stream", + headers={"Cache-Control": "no-cache", "X-Accel-Buffering": "no"}) + # ── API: SPI setup via Telnet (SSE) ───────────────────────────────────────── @app.route("/api/spi_setup/run") def api_spi_setup_run(): @@ -1693,6 +1781,14 @@ input:checked+.slider:before{transform:translateX(16px);background:#fff} Deploy to KL630 + +