เปลี่ยน Jellyfin เป็นร้านวิดีโอ 90s ด้วย Halcyon
เปลี่ยนคลังสื่อ Jellyfin ให้เป็นร้านเช่าวิดีโอในยุค 90 เดินเลือกชมได้ผ่านเบราว์เซอร์ พร้อมวิธีตั้งค่าผ่าน Docker การทำ Reverse Proxy และข้อควรระวังก่อนใช้งานจริง
สิ่งที่ Halcyon ทำกับคลังสื่อ Jellyfin ของคุณ
Halcyon Video จะจำลองคลังสื่อ Jellyfin ของคุณให้กลายเป็นร้านวิดีโอในยุค 1990 ที่คุณสามารถเดินเลือกชมได้ผ่านเว็บเบราว์เซอร์ ภาพยนตร์ทุกเรื่องที่คุณมีจะถูกเปลี่ยนเป็นตลับวิดีโอวางอยู่บนชั้นวาง คุณสามารถเดินไปตามทางเดินภายใต้แสงไฟนีออน หยิบกล่องวิดีโอลงมา พลิกดูรายละเอียดที่ด้านหลัง แล้วนำไปที่เคาน์เตอร์เพื่อเริ่มเล่นวิดีโอ ระบบจะรายงานสถานะการเริ่มเล่น ความคืบหน้า และการหยุดเล่นกลับไปยัง Jellyfin เพื่อให้จุดที่รับชมค้างไว้และประวัติการรับชมมีความถูกต้องเสมอ
Halcyon จะอ่านข้อมูลจากเซิร์ฟเวอร์ Jellyfin ที่มีอยู่ผ่านทาง Jellyfin API โดยไม่ได้สร้างคลังข้อมูลเป็นของตนเอง คู่มือนี้ตั้งสมมติฐานว่า Jellyfin ของคุณทำงานและสแกนข้อมูลได้อย่างถูกต้องเรียบร้อยแล้ว หากยังไม่เป็นเช่นนั้น ให้ตั้งค่า Jellyfin ในฐานะสื่อบันเทิงบน VPS ให้เรียบร้อยก่อน แล้วจึงกลับมาดำเนินการต่อเมื่อคลังสื่อของคุณแสดงผลในเว็บไคลเอนต์ปกติได้อย่างถูกต้อง นี่คือซอฟต์แวร์ที่คุณควรติดตั้งก็ต่อเมื่อคุณมีคลังสื่อพร้อมใช้งานอยู่แล้ว ไม่ใช่เพราะคุณต้องการเพิ่มบริการอื่นเข้าไปใน รายการบริการที่คุณโฮสต์เอง
โครงการนี้อยู่ภายใต้สัญญาอนุญาต GPL-3.0 และพัฒนาโดยบุคคลเพียงคนเดียว โดยในไฟล์ README ระบุไว้อย่างชัดเจนว่าจะไม่รับ pull request การพัฒนาดำเนินไปอย่างรวดเร็วและไม่มีผู้ดูแลคนอื่นคอยตรวจสอบข้อผิดพลาดที่อาจเกิดขึ้น ดังนั้นควรระบุเวอร์ชันของ image ให้คงที่ (pin) ก่อนที่จะเปิดให้ผู้อื่นเข้าใช้งานร้านวิดีโอของคุณ โดยส่วนสุดท้ายของคู่มือนี้จะอธิบายวิธีการดำเนินการดังกล่าว
การเรนเดอร์เกิดขึ้นที่ไหน?
เกิดขึ้นในเบราว์เซอร์ Halcyon เป็นแอปพลิเคชัน Vite และ TypeScript ที่สร้างขึ้นบน three.js ซึ่งเป็นไลบรารี JavaScript สำหรับวาดกราฟิก 3D ผ่าน WebGL (web graphics library ซึ่งเป็นอินเทอร์เฟซของเบราว์เซอร์ที่เชื่อมต่อกับ GPU) โดยรูปทรงของร้านค้าและภาพหน้าปกกล่องจะถูกนำมาประกอบกันโดยเครื่องที่แสดงผลหน้าจอนั้น
คอนเทนเนอร์ทำหน้าที่เพียงเล็กน้อยเท่านั้น โดยจะรัน npm run serve ซึ่งก็คือ vite preview --port 1420 --strictPort --host และทำหน้าที่ให้บริการไฟล์ที่ build แล้ว รวมถึง route ของ middleware ขนาดเล็กอีกจำนวนหนึ่ง Halcyon ไม่มีการแปลงรหัส (transcoding) และไม่มีการรัน engine ใดๆ บนเซิร์ฟเวอร์
ดังนั้น คำถามเรื่อง GPU จึงขึ้นอยู่กับฝั่งไคลเอนต์ VPS ขนาดเล็กสามารถให้บริการส่วนนี้ได้อย่างราบรื่น เพราะการให้บริการหมายถึงการส่งไฟล์แบบ static ผ่าน HTTP ส่วนแล็ปท็อป แท็บเล็ต หรือโทรทัศน์ที่รันเบราว์เซอร์จะเป็นตัวตัดสินว่าร้านค้าจะแสดงผลได้อย่างลื่นไหลหรือกระตุก
มีฟีเจอร์หนึ่งที่ขัดกับกฎดังกล่าว คือ Remote Play ซึ่งจะสร้าง instance ของ Chromium แบบ headless บนเซิร์ฟเวอร์ และสตรีมร้านค้าที่เรนเดอร์แล้วไปยังโทรศัพท์หรือ set top box ผ่าน WebRTC (web real time communication) เส้นทางนั้นจะเรนเดอร์บนเซิร์ฟเวอร์ โดยจำกัดไว้ที่สอง instance เป็นค่าเริ่มต้นและสามารถปรับเปลี่ยนได้ด้วย REMOTE_PLAY_MAX_INSTANCES หากไม่มีการแมปอุปกรณ์ /dev/dri instance เหล่านั้นจะเรนเดอร์บน CPU ดังนั้น VPS ที่มีสองคอร์จะได้รับผลกระทบทุกครั้งที่มีผู้ชมเพิ่มขึ้น
สิ่งที่ร้านค้าอ่านจากคลังข้อมูลของคุณ
ชั้นวางสินค้ามาจากโครงสร้างของ Jellyfin โดยตรง Halcyon จะจัดวางส่วนต่างๆ ตามคลังข้อมูลและประเภทสื่อของคุณ และจัดกลุ่มภาคต่อจาก BoxSets ของคุณ ข้อมูลจำเพาะที่พิมพ์อยู่ด้านหลังกล่องแต่ละกล่องมาจาก metadata ของ MediaStreams ที่ Jellyfin จัดเก็บไว้อยู่แล้ว ซึ่งหมายความว่าหากข้อมูลใดขาดหายไปใน Jellyfin ข้อมูลนั้นก็จะขาดหายไปบนชั้นวางด้วยเช่นกัน
สิ่งนี้ทำให้ร้านค้าเป็นภาพสะท้อนที่แม่นยำของ metadata ของคุณ คลังข้อมูลที่จัดการผ่าน an arr stack ใน Docker Compose ซึ่งมีการใส่ภาพปกและประเภทสื่อไว้ครบถ้วนแล้ว จะดูดีกว่าโฟลเดอร์ที่มีไฟล์กระจัดกระจายและตั้งชื่อแบบทั่วไปมาก คลังรูปภาพก็มีความขึ้นตรงต่อสิ่งที่ทำดัชนีข้อมูลเหล่านั้นเช่นเดียวกัน ซึ่งเป็นสิ่งที่ควรคำนึงถึงเมื่อคุณเปรียบเทียบ PhotoPrism กับ Immich สำหรับภาพนิ่งที่เก็บอยู่บนเซิร์ฟเวอร์เดียวกัน
ทดลองใช้งานเดโมร้านวิดีโอก่อนทำการติดตั้ง
โปรเจกต์นี้เผยแพร่ตัวอย่างร้านค้าที่ทำงานร่วมกับคลังข้อมูลจำลองไว้ที่ เดโมออนไลน์ คุณสามารถเพิ่ม ?demo=1 ต่อท้าย URL ของ Halcyon เพื่อใช้งานในลักษณะเดียวกันบนการติดตั้งของคุณเองได้
ใช้เดโมนี้เพื่อทดสอบประสิทธิภาพฮาร์ดแวร์ คลังข้อมูลในเดโมมีรายการวิดีโอประมาณ 2,000 รายการ และต้องการหน่วยความจำของเบราว์เซอร์ประมาณ 2 GB ซึ่งถือว่าใช้ทรัพยากรสูงกว่าคลังข้อมูลส่วนตัวทั่วไป หากเดโมทำงานกระตุกบนอุปกรณ์ที่คุณวางแผนจะใช้เข้าถึง คลังข้อมูลของคุณก็จะกระตุกเช่นกัน วิธีแก้ไขคือการใช้โหมด 2.5D ตามที่อธิบายไว้ด้านล่าง แทนการขยายขนาด VPS ให้ใหญ่ขึ้น
เรียกใช้งานด้วย Docker
นี่คือคำสั่งที่เอกสารต้นทางระบุไว้
docker run -d --name halcyon --network host --restart unless-stopped \
ghcr.io/halcyon-video/halcyon-videoจากนั้นตรวจสอบว่าบริการเริ่มทำงานแล้ว
docker logs halcyon
curl -I http://127.0.0.1:1420ใน log ควรแสดงว่า preview server กำลังฟังอยู่ที่พอร์ต 1420 และ curl ควรตอบสนองต่อ HTTP/1.1 200 OK หากคอนเทนเนอร์หยุดทำงานภายในเวลาไม่กี่วินาที สาเหตุเกือบทั้งหมดมาจากพอร์ต --strictPort หมายความว่าเซิร์ฟเวอร์ปฏิเสธที่จะเปลี่ยนไปใช้พอร์ต 1421 เมื่อพอร์ต 1420 ถูกใช้งานอยู่ จึงหยุดทำงานแทน
--network host มีไว้สำหรับ Remote Play ไม่ใช่สำหรับหน้าร้านค้า WebRTC จำเป็นต้องประกาศที่อยู่จริงของเครื่องให้กับอุปกรณ์ที่ต้องการรับสตรีม เมื่ออยู่หลัง Docker bridge เริ่มต้น คอนเทนเนอร์จะรู้จักเพียงที่อยู่ 172.x ของตัวเองเท่านั้น ซึ่งโทรศัพท์ในเครือข่ายของคุณไม่สามารถเข้าถึงได้ ส่งผลให้การสตรีมไม่สามารถเชื่อมต่อได้ หากคุณต้องการเพียงแค่เข้าถึงหน้าร้านค้าผ่านเบราว์เซอร์ ให้ทำการ publish พอร์ตแทน
docker run -d --name halcyon -p 1420:1420 --restart unless-stopped \
ghcr.io/halcyon-video/halcyon-videoนั่นเป็นค่าเริ่มต้นที่ดีกว่าบน VPS เนื่องจาก host networking จะนำคอนเทนเนอร์ไปวางไว้บนทุกอินเทอร์เฟซที่เครื่องมี รวมถึงอินเทอร์เฟซสาธารณะด้วย การรัน Docker บน VPS ครอบคลุมรายละเอียดส่วนที่เหลือของเรื่องนี้ --restart unless-stopped คือสิ่งที่ทำให้หน้าร้านค้ากลับมาทำงานอีกครั้งหลังจากการรีบูต ซึ่งเป็นแนวคิดเดียวกับ การตั้งค่า Compose services ให้เริ่มทำงานตอนบูตเครื่อง
การโคลน repository และรัน docker compose up -d จะเป็นการ build image ในเครื่องแทน ไฟล์ Compose ที่ให้มาจะ build จาก source เป็นค่าเริ่มต้น และมีบรรทัด image: ที่ถูก comment ไว้ ดังนั้นให้เอา comment ออกหากคุณต้องการใช้ image ที่เผยแพร่อยู่แล้วผ่าน Compose
ข้อจำกัดสำคัญ ณ เดือนสิงหาคม 2026: image ที่เผยแพร่นั้นรองรับเฉพาะ linux/amd64 เท่านั้น ส่วนของ arm64 ในการ push แบบ multi-architecture ล้มเหลวภายใต้การจำลอง (emulation) และกำลังรอการทำงานบน native arm runners หากใช้งานบน arm64 VPS การ pull จะล้มเหลวด้วยข้อผิดพลาด no matching manifest for linux/arm64/v8 in the manifest list entries และการ build จากการโคลนคือวิธีแก้ไขปัญหาดังกล่าว
ชี้เป้าไปยังเซิร์ฟเวอร์ Jellyfin ของคุณ
เปิด http://<host>:1420 แล้วเข้าสู่ระบบด้วยที่อยู่เซิร์ฟเวอร์ Jellyfin ชื่อผู้ใช้ และรหัสผ่านของคุณ ไฟล์ .env.local.example ใน repository มีไว้สำหรับการพัฒนาในเครื่องเท่านั้น Vite จะเปิดเผยตัวแปรที่มีคำนำหน้าว่า VITE_ ให้กับโค้ดฝั่งไคลเอ็นต์ ดังนั้นรหัสผ่าน Jellyfin ที่เขียนไว้ในนั้นจะถูกคอมไพล์รวมเข้าไปใน JavaScript bundle ที่ผู้เข้าชมทุกคนดาวน์โหลดไป หากเป็นเซิร์ฟเวอร์ที่ผู้อื่นเข้าถึงได้ ให้เข้าสู่ระบบผ่านอินเทอร์เฟซแทน
เบราว์เซอร์จะสื่อสารกับ Jellyfin โดยตรง คอนเทนเนอร์ของ Halcyon ไม่ได้ทำหน้าที่เป็นพร็อกซีให้กับ Jellyfin API ซึ่งมีผลลัพธ์สองประการที่ควรทราบก่อนเริ่มการดีบั๊ก
ประการแรก Jellyfin ต้องสามารถเข้าถึงได้จากเบราว์เซอร์ ไม่ใช่แค่จาก VPS ที่ให้บริการ Halcyon เท่านั้น การผูก Jellyfin ไว้กับ 127.0.0.1:8096 นั้นใช้ได้สำหรับการทดสอบในเครื่อง แต่จะทำให้ชั้นวางข้อมูลว่างเปล่าสำหรับผู้ใช้คนอื่น
ประการที่สอง การเรียกใช้งานเป็นการข้ามแหล่งที่มา (cross origin) จากที่อยู่ของ Halcyon ไปยังที่อยู่ของ Jellyfin โดยปกติแล้ว Jellyfin จะตอบกลับคำขอ API ด้วย Access-Control-Allow-Origin: * เป็นค่าเริ่มต้น จึงสามารถทำงานได้โดยไม่ต้องตั้งค่าเพิ่มเติม หากคุณจำกัดการตั้งค่านั้นไว้ หรือวาง authentication proxy ไว้หน้า Jellyfin API คอนโซลของเบราว์เซอร์จะรายงาน blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource และหน้าจอร้านค้าจะโหลดขึ้นมาโดยไม่มีข้อมูลแสดงผล
วางไว้หลัง reverse proxy พร้อมการยืนยันตัวตนที่ด้านหน้า
vite preview เป็นเซิร์ฟเวอร์สำหรับดูตัวอย่าง มันไม่ได้ทำ TLS (transport layer security) termination และไม่มีระบบควบคุมการเข้าถึงในตัว ดังนั้นจึงควรวางไว้หลัง nginx หรือ Caddy หากต้องเปิดใช้งานบนเครือข่ายสาธารณะ
server {
listen 443 ssl;
server_name halcyon.example.com;
location / {
proxy_pass http://127.0.0.1:1420;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}ชื่อโดเมนที่อยู่หน้าคอนเทนเนอร์จำเป็นต้องมีการตั้งค่าเพิ่มเติมอีกหนึ่งอย่าง Halcyon จะตอบสนองต่อ localhost, IP address โดยตรง และชื่อของเครื่องที่มันรันอยู่ เพื่อป้องกันการทำ DNS rebinding เมื่ออยู่ในคอนเทนเนอร์ เครื่องที่มันรันอยู่คือตัวคอนเทนเนอร์เอง ดังนั้น hostname ของมันจึงไม่ใช่ของคุณ คำขอที่เข้ามาในชื่อ halcyon.example.com จะถูกปฏิเสธ และการตอบกลับจะระบุชื่อโฮสต์ที่ถูกปฏิเสธ ให้เพิ่มชื่อนั้นเข้าไป
docker run -d --name halcyon -p 127.0.0.1:1420:1420 --restart unless-stopped \
-e HALCYON_ALLOWED_HOSTS=halcyon.example.com \
ghcr.io/halcyon-video/halcyon-videoค่านี้คั่นด้วยเครื่องหมายจุลภาค การใส่จุดนำหน้าเช่น .example.com จะครอบคลุมถึง subdomain ทั้งหมด และ all จะเป็นการปิดการตรวจสอบนี้ ให้เลือกใช้ all เฉพาะบนเครื่องที่ไม่มีใครจากภายนอกเข้าถึงได้เท่านั้น
เมื่อ store ถูกให้บริการผ่าน https:// แล้ว ที่อยู่ของ Jellyfin ที่คุณพิมพ์ตอนล็อกอินจะต้องเป็น https:// ด้วยเช่นกัน เบราว์เซอร์จะบล็อกการเรียกใช้ API แบบ plain http:// ที่มาจากหน้า HTTPS และคอนโซลจะแสดงข้อความ Mixed Content: The page at 'https://halcyon.example.com/' was loaded over HTTPS, but requested an insecure resource การล็อกอินจะล้มเหลวโดยไม่มีคำอธิบายใดๆ ภายใน Halcyon ดังนั้นควรให้บริการทั้งคู่ผ่าน TLS หรือคงไว้เป็น plain HTTP ทั้งคู่ภายในเครือข่ายส่วนตัว
จากนั้นคือเรื่องการยืนยันตัวตน store จะถามหาข้อมูลประจำตัวของ Jellyfin ดังนั้นคนแปลกหน้าที่พบ URL นี้จะพบกับหน้าล็อกอิน แต่มีฟีเจอร์หนึ่งที่เปลี่ยนเรื่องนี้ การเปิดใช้งาน Remote Play ในเมนู Settings แล้วไปที่ Connection จะเป็นการส่งมอบเซสชัน Jellyfin ของคุณให้กับเซิร์ฟเวอร์ เพื่อให้ผู้ที่เข้ามาที่ /remote.html ได้ใช้งาน instance ของคลังสื่อจริงของคุณ นี่คือจุดประสงค์ของฟีเจอร์นี้ ซึ่งหมายความว่าความลับของ URL คือสิ่งที่กั้นระหว่างอินเทอร์เน็ตกับภาพยนตร์ของคุณ หากคุณเปิดใช้งาน Remote Play ให้ติดตั้ง single sign on ไว้หน้าเว็บไซต์ทั้งหมดด้วย Authentik ในฐานะเกตเวย์ SSO แบบ self-hosted หรือเลิกใช้ชื่อโฮสต์สาธารณะแล้วเข้าถึง store ผ่าน WireGuard tunnel ที่จัดการด้วย wg-easy
มีรายละเอียดสองประการที่ต้องทำควบคู่กันไป reverse proxy จะนำพาเฉพาะข้อมูลของ store เท่านั้น: สตรีมของ Remote Play เป็น WebRTC ผ่าน UDP ซึ่งไม่ผ่าน HTTP proxy ดังนั้นจึงต้องเปิดเส้นทางของตัวเองที่พอร์ต 3478/udp และช่วง 49200 ถึง 49260/udp เมื่อมีการใช้งาน TURN relay ที่มาพร้อมกัน และค่า docker run แบบ plain ด้านบนนั้นไม่ได้เก็บ volume ไว้ ดังนั้น seed ของ Remote Play จะไม่คงอยู่หลังจากการทำ docker rm ไฟล์ Compose จึงต้อง mount volume halcyon-data ไว้ที่ /data และตั้งค่า REMOTE_PLAY_SEED เป็น /data/remote-play-seed.json ด้วยเหตุผลนี้โดยเฉพาะ
สิ่งที่ควรทำเมื่อร้านค้าทำงานได้ไม่ดี
Halcyon จะแสดงผลตามความต้องการ ร้านค้าที่ไม่ได้ใช้งานจะไม่มีการรวมเฟรม (composite) และการสูญเสียโฟกัสของหน้าต่างจะหยุดลูปการแสดงผล ซึ่งเป็นเหตุผลว่าทำไมการเปิดแท็บทิ้งไว้จึงไม่ทำให้แบตเตอรี่แล็ปท็อปหมด สิ่งนี้ช่วยเครื่องที่มีประสิทธิภาพจำกัดได้บ้าง แต่ไม่มีผลกับเครื่องที่ไม่สามารถวาดร้านค้าได้เลย
สำหรับไคลเอนต์เหล่านั้นจะมีโหมด 2.5D ซึ่งเป็น HTML และ CSS ธรรมดาที่ไม่มี WebGL ออกแบบมาสำหรับฮาร์ดแวร์ขนาดเล็กอย่าง Raspberry Pi คุณสามารถสลับระหว่าง 3D และ 2.5D ได้จากเมนูการตั้งค่าหรือเมนูพลังงานโดยไม่ต้องโหลดหน้าเว็บใหม่ ดังนั้นการทดสอบทั้งสองโหมดบนอุปกรณ์เดียวกันจึงใช้เวลาเพียงไม่กี่วินาที โปรดมองความเป็นจริงเกี่ยวกับสิ่งที่คุณจะได้รับ: ผู้เขียนอธิบายว่าโหมดแบนราบนี้ยังมีความหยาบและอยู่ในระหว่างการพัฒนา ให้ถือว่าเป็นทางเลือกสำรองสำหรับไคลเอนต์ที่มีประสิทธิภาพต่ำ
เมื่อไคลเอนต์มีประสิทธิภาพต่ำเกินกว่าจะแสดงผลร้านค้าแบบ 3D ความล้มเหลวจะเกิดขึ้นอย่างชัดเจน แท็บจะโหลดตัวเองใหม่ หรือเบราว์เซอร์จะรายงานว่า WebGL context สูญหาย โดยปกติจะเกิดขึ้นในขณะที่ชั้นวางกำลังโหลดข้อมูล ให้เปลี่ยนอุปกรณ์นั้นไปใช้โหมด 2.5D แทนการลดขนาดคลังข้อมูลของคุณ
ตรึงเวอร์ชันอิมเมจและตรวจสอบก่อนดึงข้อมูล
โปรดให้ความสำคัญกับส่วนนี้เป็นพิเศษ แท็ก v0.1.0 ถึง v0.3.1 ถูกปล่อยออกมาในช่วงเวลาไล่เลี่ยกันเพียงไม่กี่วัน และ v0.2.1 มีอยู่ได้ก็เพราะการ push อิมเมจสำหรับ v0.2.0 ล้มเหลว แม้จะยินดีรับรายงานบั๊กจากต้นทาง แต่ไม่รับแพตช์ ดังนั้น release stream จึงเป็นเพียงสถานะการทำงานของบุคคลเพียงคนเดียวเท่านั้น
การรัน latest โดยติดนิสัยการใช้ docker pull หมายความว่าที่เก็บข้อมูลอาจเปลี่ยนแปลงได้ทุกเมื่อในวันธรรมดา ให้ตรึงเวอร์ชันด้วย digest ซึ่งเป็นข้อมูลอ้างอิงเดียวที่ไม่สามารถเปลี่ยนแปลงได้
docker buildx imagetools inspect ghcr.io/halcyon-video/halcyon-video:0.3.1คำสั่งนี้จะแสดงค่า digest ที่อยู่เบื้องหลังแท็ก ให้ใช้ค่านี้แทนการใช้แท็ก
docker run -d --name halcyon -p 1420:1420 --restart unless-stopped \
ghcr.io/halcyon-video/halcyon-video@sha256:747dcc821a3d2fa318b50e76024783c1835609047e84f502e23d021bc1898b20digest ดังกล่าวคือ 0.3.1 ณ วันที่ 10 สิงหาคม 2026 โปรดอ่านค่าปัจจุบันด้วยตนเองแทนการคัดลอก และอ่านบันทึกประจำรุ่น (release notes) ก่อนดำเนินการอัปเดต เนื่องจากแพตช์รุ่นนี้อาจมีการเปลี่ยนแปลงโครงสร้างการจัดเก็บข้อมูลนอกเหนือไปจากการแก้ไขข้อผิดพลาดทั่วไป
FAQ
Halcyon จำเป็นต้องใช้ GPU บน VPS ของฉันหรือไม่?
ไม่จำเป็นสำหรับการใช้งานทั่วไป หน้าร้านถูกเรนเดอร์ด้วย three.js ในเบราว์เซอร์ ดังนั้นเครื่องไคลเอนต์จะเป็นผู้ประมวลผลการแสดงผล ส่วนคอนเทนเนอร์ทำหน้าที่เพียงเสิร์ฟไฟล์สแตติกผ่านพอร์ต 1420 เท่านั้น ข้อยกเว้นคือฟีเจอร์ Remote Play ซึ่งจะรัน headless Chromium บนเซิร์ฟเวอร์และสตรีมผลลัพธ์ออกมา เส้นทางดังกล่าวจะเรนเดอร์ผ่าน CPU เว้นแต่คุณจะแมป /dev/dri เข้าไปในคอนเทนเนอร์เพื่อใช้งานการเร่งความเร็วด้วยฮาร์ดแวร์
ฉันสามารถนำ Halcyon ไปวางบนอินเทอร์เน็ตสาธารณะได้หรือไม่?
ทำได้ต่อเมื่ออยู่หลังระบบยืนยันตัวตนเท่านั้น หน้าร้านจะเรียกขอข้อมูลรับรองของ Jellyfin แต่การเปิดใช้งาน Remote Play จะเป็นการส่งต่อเซสชัน Jellyfin ของคุณไปยังเซิร์ฟเวอร์ ดังนั้นใครก็ตามที่โหลด /remote.html จะสามารถเข้าถึงไลบรารีจริงของคุณได้โดยไม่ต้องล็อกอิน คุณควรติดตั้ง reverse proxy ที่มีระบบ single sign on ไว้ด้านหน้า หรือเก็บชื่อโฮสต์ไว้เป็นความลับไม่ให้ปรากฏบน public DNS และเข้าถึงหน้าร้านผ่าน VPN เท่านั้น
ทำไมชั้นวางสินค้าถึงว่างเปล่าหลังจากที่ฉันล็อกอินแล้ว?
เบราว์เซอร์จะเรียกใช้ Jellyfin API โดยตรง ดังนั้น Jellyfin จะต้องสามารถเข้าถึงได้จากเบราว์เซอร์ ไม่ใช่แค่จาก VPS เท่านั้น ให้เปิดคอนโซลของเบราว์เซอร์ขึ้นมา หากพบ blocked by CORS policy หมายความว่า Jellyfin ไม่ยอมรับคำขอจากที่อยู่ของ Halcyon หากพบข้อความ Mixed Content หมายความว่าหน้าเว็บกำลังทำงานบน HTTPS ในขณะที่ที่อยู่ Jellyfin ที่คุณระบุเป็น HTTP ธรรมดา
ฉันจำเป็นต้องใช้ --network host หรือไม่?
จำเป็นเฉพาะสำหรับการใช้งาน Remote Play เท่านั้น เนื่องจาก WebRTC จำเป็นต้องประกาศที่อยู่จริงของเครื่อง และเมื่ออยู่หลัง Docker bridge คอนเทนเนอร์จะเสนอได้เพียงที่อยู่ 172.x ซึ่งโทรศัพท์ในเครือข่ายของคุณไม่สามารถเข้าถึงได้ สำหรับการเรียกดูหน้าร้านผ่านเบราว์เซอร์ทั่วไป การใช้ -p 1420:1420 ก็เพียงพอแล้วและยังเปิดเผยข้อมูลของโฮสต์น้อยกว่ามาก
ฉันควรใช้ image tag ใด?
ควรระบุเจาะจงที่ digest แทนการใช้ latest ให้ตรวจสอบ digest สำหรับเวอร์ชันที่มี docker buildx imagetools inspect ghcr.io/halcyon-video/halcyon-video:0.3.1 แล้วรัน digest นั้น และค่อยอัปเดตหลังจากอ่านบันทึกประจำรุ่น (release notes) แล้วเท่านั้น ณ เดือนสิงหาคม 2026 อิมเมจที่เผยแพร่รองรับเฉพาะ linux/amd64 ดังนั้นโฮสต์ที่เป็น arm64 จึงต้อง build จาก clone ด้วย docker compose up -d