Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions data/locales/pages.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,25 @@ en:
credits_title: Standing on open shoulders
cta_chat: Join the FPV chat
cta_guide: Read the build guide
flight_copy: H.264 copy
flight_credit_html: 'Flight by <a href="https://github.com/gilankpam">gilankpam</a> on <a href="https://github.com/gilankpam/mabur">mabur</a> · SSC338Q + RTL8812EU'
flight_error: This browser cannot play the stream
flight_failed: 'The flight did not load. Try again'
flight_frame_back: Previous frame
flight_frame_forward: Next frame
flight_fullscreen: Full screen
flight_gs: On the pilot's screen
flight_handle: Divider between the two recordings
flight_loading: Loading…
flight_onboard: On the drone
flight_open_rnd: Open in R&D Player
flight_original: Original quality
flight_pause: Pause
flight_play: Play
flight_reduced: reduced
flight_seek: Position in the flight
flight_text: 'The drone''s own recording and what reached the pilot''s screen over the link, frame by frame. Drag the divider to compare; the link''s latency is in the telemetry along the bottom.'
flight_title: 'See it on a real flight'
fpv_text: 'A fully open digital FPV system: no locked ecosystem, no paired hardware, no firmware ceiling. Build the air unit from a supported camera, pick your ground station, and tune every stage of the pipeline.'
fpv_title: 'FPV: from lens to goggles'
hardware_text_html: Air units are built from supported cameras and AIO boards — start from the <a href="/supported-hardware">supported hardware list</a>. RunCam and other vendors ship OpenIPC-based FPV hardware out of the box.
Expand Down
19 changes: 19 additions & 0 deletions data/locales/pages.ru.yml
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,25 @@ ru:
credits_title: Стоим на открытых плечах
cta_chat: FPV-чат
cta_guide: Гайд по сборке
flight_copy: копия H.264
flight_credit_html: 'Полёт — <a href="https://github.com/gilankpam">gilankpam</a> на <a href="https://github.com/gilankpam/mabur">mabur</a> · SSC338Q + RTL8812EU'
flight_error: Этот браузер не может воспроизвести поток
flight_failed: 'Полёт не загрузился. Попробуйте ещё раз'
flight_frame_back: Предыдущий кадр
flight_frame_forward: Следующий кадр
flight_fullscreen: Во весь экран
flight_gs: На экране пилота
flight_handle: Граница между двумя записями
flight_loading: Загрузка…
flight_onboard: На борту дрона
flight_open_rnd: Открыть в R&D Player
flight_original: Исходное качество
flight_pause: Пауза
flight_play: Смотреть
flight_reduced: снижено
flight_seek: Позиция в полёте
flight_text: 'Запись с борта дрона и то, что дошло по линку до экрана пилота, кадр в кадр. Двигайте границу, чтобы сравнить; задержка линка — в телеметрии внизу.'
flight_title: 'Посмотрите на настоящем полёте'
fpv_text: 'Полностью открытая цифровая FPV-система: никакой закрытой экосистемы, никакого спаренного железа, никакого потолка прошивки. Соберите борт из поддерживаемой камеры, выберите наземную станцию и настройте каждый этап конвейера.'
fpv_title: 'FPV: от объектива до очков'
hardware_text_html: Борт собирается из поддерживаемых камер и AIO-плат — начните со <a href="/supported-hardware">списка поддерживаемого оборудования</a>. RunCam и другие вендоры выпускают FPV-железо на OpenIPC из коробки.
Expand Down
19 changes: 19 additions & 0 deletions data/locales/pages.zh.yml
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,25 @@ zh:
credits_title: 站在开放的肩膀上
cta_chat: 加入 FPV 聊天群
cta_guide: 阅读搭建指南
flight_copy: H.264 副本
flight_credit_html: '飞行:<a href="https://github.com/gilankpam">gilankpam</a>,使用 <a href="https://github.com/gilankpam/mabur">mabur</a> · SSC338Q + RTL8812EU'
flight_error: 此浏览器无法播放该视频流
flight_failed: '飞行视频未能加载,请重试'
flight_frame_back: 上一帧
flight_frame_forward: 下一帧
flight_fullscreen: 全屏
flight_gs: 飞手屏幕上
flight_handle: 两段录像之间的分隔线
flight_loading: 加载中…
flight_onboard: 无人机机载
flight_open_rnd: 在 R&D Player 中打开
flight_original: 原始画质
flight_pause: 暂停
flight_play: 播放
flight_reduced: 已降低
flight_seek: 飞行中的位置
flight_text: '无人机机载录像与经链路到达飞手屏幕的画面,逐帧对照。拖动分隔线进行比较;链路延迟显示在底部的遥测中。'
flight_title: '在真实飞行中看看'
fpv_text: '一套完全开放的数字 FPV 系统:没有封闭生态,没有配对绑定的硬件,也没有固件上限。用受支持的摄像机搭建天空端,挑选你的地面站,并可调节管线的每一个环节。'
fpv_title: 'FPV:从镜头到眼镜'
hardware_text_html: 天空端由受支持的摄像机和 AIO 板搭建——请从<a href="/supported-hardware">支持硬件列表</a>开始。RunCam 等厂商出厂即提供基于 OpenIPC 的 FPV 硬件。
Expand Down
6 changes: 6 additions & 0 deletions deploy/RESTORE.md
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,12 @@ Only needed on a rebuilt host:
- `/srv/www/shared/wall` — the wall's images. **Not** in the backup; the Open
Wall is empty until cameras re-upload, so an empty directory owned by uid
1000 is a complete restore.
- `/srv/www/shared/media` — the recorded flight the A/B player on
`/low-latency` streams. **Not** in the backup: about 2.5 GB, rebuilt from the
two source recordings by `tools/flight-ab/run.sh` and uploaded as its README
says. The sources are on this host too (`/srv/www/flight-sources/`, not in
S3), so a rebuilt host needs them from wherever else they were kept. Until then the page shows its poster and the player says it cannot
Comment thread
openipc-ai marked this conversation as resolved.
play.
- **analytics**, via `deploy/install-analytics.sh` (#181). It installs
GoatCounter, its account and its systemd unit, and creates the site on first
run from `ANALYTICS_EMAIL` and `ANALYTICS_PASSWORD`. The SQLite database is
Expand Down
28 changes: 28 additions & 0 deletions deploy/nginx/check-config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,10 @@ ln -s site-test /srv/www/static/prod/current
printf 'TOKEN-OK\n' > /var/lib/dehydrated/acme-challenges/probe-token
install -d -m 0755 /srv/www/shared/images
printf 'PNG\n' > /srv/www/shared/images/logo_openipc.png
# A recorded flight for the A/B player on /low-latency (tools/flight-ab).
install -d -m 0755 /srv/www/shared/media/flights/test/v1/gs/original
printf '<MPD/>\n' > /srv/www/shared/media/flights/test/v1/gs.mpd
printf '0123456789' > /srv/www/shared/media/flights/test/v1/gs/original/1.m4s

# A second loopback address stands in for a datacentre client, so the block
# and CI's way through it are measured rather than read off the map.
Expand Down Expand Up @@ -440,6 +444,30 @@ expect_cache /no-such-page-at-all "no-cache"
expect /fonts/ibm-plex-sans-latin-400-normal.woff2 200 static hsts
expect_cache /fonts/ibm-plex-sans-latin-400-normal.woff2 "public, max-age=31536000, immutable"
expect /assets/application.css 410 - no-hsts

# Recorded flights (tools/flight-ab): versioned directories never rewritten, so
# a year of cache; the types DASH players insist on; ranges, which a player
# may ask for; and CORS for the R&D Player's origin and nobody else's.
expect /media/flights/test/v1/gs.mpd 200 - hsts
expect_cache /media/flights/test/v1/gs.mpd "public, max-age=31536000, immutable"
media_header() {
path=$1; header=$2; want=$3; shift 3
curl -sS -o /dev/null -D /tmp/hm -k --max-time 5 "$@" \
--resolve "openipc.org:443:127.0.0.1" "https://openipc.org$path" >/dev/null 2>&1
if [ "$header" = status ]; then got=$(awk 'NR==1{print $2}' /tmp/hm)
else got=$(grep -i "^$header:" /tmp/hm | tr -d '\r' | cut -d' ' -f2- | head -1); fi
if [ "$got" = "$want" ]; then
printf ' %-32s %s: %s\n' "$path" "$header" "$got"
else
printf ' %-32s MISMATCH: %s is %s (want %s)\n' "$path" "$header" "${got:-<none>}" "$want"
fail=1
fi
}
media_header /media/flights/test/v1/gs.mpd content-type application/dash+xml
media_header /media/flights/test/v1/gs/original/1.m4s content-type video/iso.segment
media_header /media/flights/test/v1/gs/original/1.m4s status 206 -H 'Range: bytes=2-5'
media_header /media/flights/test/v1/gs.mpd access-control-allow-origin https://openipc.github.io
expect /media/flights/test/v1/none.mpd 404 - no-hsts
# The home page keeps its address when its content changes, like every other
# page in the bundle, so it may be cached and must always be revalidated.
expect_cache / "public, max-age=0, must-revalidate"
Expand Down
26 changes: 26 additions & 0 deletions deploy/nginx/sites-available/org.openipc
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,32 @@ server {
alias /srv/www/shared/images/;
}

# Recorded flights, streamed as DASH by the A/B player on /low-latency
# (tools/flight-ab). Each flight is one versioned directory that is never
# rewritten -- a new cut is a new v<N>/ -- so a year of immutable cache is
# safe. Host-only and in no backup: the tree is regenerated from the two
# source recordings by tools/flight-ab/run.sh.
#
# The CORS header is for one origin only, the R&D Player's, which the page
# offers as "open in R&D Player" and which fetches the manifests and
# segments cross-origin. Both players fetch a segment per stream at a
# time, well inside the http-level per_subnet twenty.
location ^~ /media/ {
alias /srv/www/shared/media/;
types {
application/dash+xml mpd;
video/iso.segment m4s;
video/mp4 mp4;
application/json json;
image/jpeg jpg;
}
add_header Strict-Transport-Security max-age=15768000;
add_header X-Content-Type-Options nosniff always;
add_header Access-Control-Allow-Origin https://openipc.github.io always;
# Not `always`: a 404 cached for a year would outlive the upload.
add_header Cache-Control "public, max-age=31536000, immutable";
}

# Analytics beacon (#181). GoatCounter runs on the loopback and these are
# the only two paths of it the public site exposes.
#
Expand Down
27 changes: 27 additions & 0 deletions deploy/nginx/sites-available/org.openipc.dev
Original file line number Diff line number Diff line change
Expand Up @@ -772,6 +772,33 @@ server {
}


# Recorded flights, streamed as DASH by the A/B player on /low-latency
# (tools/flight-ab). Each flight is one versioned directory that is never
# rewritten -- a new cut is a new v<N>/ -- so a year of immutable cache is
# safe. Host-only and in no backup: the tree is regenerated from the two
# source recordings by tools/flight-ab/run.sh.
#
# The CORS header is for one origin only, the R&D Player's, which the page
# offers as "open in R&D Player" and which fetches the manifests and
# segments cross-origin. Both players fetch a segment per stream at a
# time, well inside the http-level per_subnet twenty.
location ^~ /media/ {
alias /srv/www/shared/media/;
types {
application/dash+xml mpd;
video/iso.segment m4s;
video/mp4 mp4;
application/json json;
image/jpeg jpg;
}
add_header Strict-Transport-Security max-age=15768000;
add_header X-Content-Type-Options nosniff always;
add_header Access-Control-Allow-Origin https://openipc.github.io always;
# Not `always`: a 404 cached for a year would outlive the upload.
add_header Cache-Control "public, max-age=31536000, immutable";
add_header X-Robots-Tag "noindex, nofollow, noarchive" always;
}

# The Go firmware process's image cache (#299): one version of each image,
# built on first request. Reachable only through its X-Accel-Redirect.
location /firmware-cache/ {
Expand Down
2 changes: 2 additions & 0 deletions deploy/static/reserved-paths
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@
/board-files/
# Owner reports' files, internal: reached only through the web role's X-Accel-Redirect for a published report.
/report-files/
# Recorded flights for the A/B player on /low-latency (tools/flight-ab), host-only.
/media/

# --- the expensive leaf ------------------------------------------------------
# /cameras/ is deliberately NOT reserved: the catalogue is exactly what #162
Expand Down
3 changes: 2 additions & 1 deletion frontend/apps/site/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
"dependencies": {
"@openipc/ui": "*",
"d3-hierarchy": "^3.1.2",
"preact": "10.27.2"
"preact": "10.27.2",
"shaka-player": "^4.16.51"
},
"devDependencies": {
"@astrojs/check": "^0.9.4",
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading