Cara Ubah Jellyfin Jadi Kedai Video 90-an dengan Halcyon
Tukar pustaka Jellyfin anda kepada kedai video 90-an yang interaktif menggunakan Halcyon. Panduan ini merangkumi arahan Docker, konfigurasi proksi terbalik, dan batasan teknikal.
Apa yang dilakukan oleh Halcyon terhadap pustaka Jellyfin anda
Halcyon Video memaparkan semula pustaka Jellyfin anda sebagai kedai video era 1990-an yang boleh diterokai di dalam pelayar web. Setiap filem yang anda miliki menjadi kotak di atas rak. Anda boleh berjalan di lorong di bawah lampu pendarfluor, mengambil kotak, memusingkannya untuk membaca spesifikasi di belakang, dan membawanya ke kaunter untuk memulakan main balik. Main balik melaporkan status mula, progres, dan henti kembali ke Jellyfin, supaya titik sambung semula dan sejarah tontonan kekal tepat.
Halcyon membaca pelayan Jellyfin sedia ada melalui API Jellyfin dan tidak menyimpan pustaka sendiri. Panduan ini mengandaikan Jellyfin sudah berjalan dan mengimbas dengan lancar. Jika belum, sediakan Jellyfin sebagai pelayan media pada VPS terlebih dahulu dan kembali semula setelah pustaka anda kelihatan betul dalam klien web biasa. Ini adalah jenis perisian yang anda pasang kerana pustaka sudah tersedia, bukan kerana anda memerlukan servis lain dalam senarai self-hosting anda.
Projek ini dilesenkan di bawah GPL-3.0 dan ditulis oleh seorang individu, dan README menyatakan dengan jelas bahawa ia tidak menerima pull request. Pembangunan bergerak pantas dan tiada penyelenggara kedua untuk mengesan regresi, jadi tetapkan (pin) versi imej sebelum anda menunjukkan kedai tersebut kepada orang lain. Bahagian terakhir merangkumi cara untuk melakukannya.
Di manakah proses rendering berlaku?
Di dalam pelayar web. Halcyon ialah aplikasi Vite dan TypeScript yang dibina menggunakan three.js, iaitu pustaka JavaScript yang melukis grafik 3D melalui WebGL (web graphics library, antara muka pelayar ke GPU). Geometri stor dan seni kotak digabungkan oleh mesin yang memaparkan skrin tersebut.
Kontena tersebut melakukan kerja yang sangat sedikit. Ia menjalankan npm run serve, iaitu vite preview --port 1420 --strictPort --host, serta menghidangkan fail yang telah dibina berserta beberapa laluan middleware yang kecil. Halcyon tidak menambah sebarang transkod dan tidak menjalankan sebarang enjin pada pelayan.
Oleh itu, persoalan mengenai GPU terletak pada klien. VPS yang kecil mampu menghidangkan aplikasi ini dengan lancar, kerana proses menghidangkannya hanyalah melibatkan fail statik melalui HTTP. Komputer riba, tablet atau televisyen yang menjalankan pelayar web itulah yang menentukan sama ada paparan stor bergerak dengan lancar atau perlahan.
Satu ciri melanggar peraturan tersebut. Remote Play menjana instans Chromium tanpa kepala (headless) pada pelayan dan menstrim stor yang telah dirender ke telefon atau set top box melalui WebRTC (web real time communication). Laluan tersebut dirender pada pelayan, dihadkan kepada dua instans secara lalai dan boleh dilaraskan dengan REMOTE_PLAY_MAX_INSTANCES. Tanpa peranti /dev/dri yang dipetakan, instans tersebut dirender pada CPU, jadi VPS dengan dua teras akan terasa beban bagi setiap penonton tambahan.
Apa yang dibaca oleh stor daripada pustaka anda
Lorong-lorong tersebut datang daripada struktur Jellyfin sendiri. Halcyon menyusun bahagian daripada pustaka dan genre anda, serta mengumpulkan sekuel daripada BoxSets anda. Spesifikasi yang dicetak pada belakang setiap bekas datang daripada metadata MediaStreams yang sudah disimpan oleh Jellyfin, yang bermaksud apa-apa yang tiada dalam Jellyfin juga tiada pada rak tersebut.
Ini menjadikan stor tersebut cerminan yang tepat bagi metadata anda. Pustaka yang diisi oleh an arr stack in Docker Compose dengan karya seni dan genre yang sudah lengkap kelihatan jauh lebih baik di sini berbanding folder fail yang bertaburan dengan nama generik. Pustaka foto mempunyai kebergantungan yang sama terhadap apa sahaja yang mengindeksnya, perkara yang perlu diingat apabila anda menimbang PhotoPrism against Immich untuk gambar pegun yang disimpan pada pelayan yang sama.
Cuba demo kedai video sebelum anda memasang apa-apa
Projek ini menerbitkan keseluruhan kedai yang berjalan menggunakan pustaka sintetik di demo yang dihoskan. Menambah ?demo=1 pada mana-mana URL Halcyon akan melakukan perkara yang sama pada penempatan anda sendiri.
Gunakan ia sebagai ujian perkakasan. Pustaka demo mengandungi kira-kira 2,000 tajuk dan memerlukan sekitar 2 GB memori pelayar, yang lebih berat daripada kebanyakan pustaka peribadi. Jika demo tersebut tersekat-sekat pada peranti yang anda rancang untuk gunakan, pustaka anda sendiri juga akan mengalami masalah yang sama. Penyelesaiannya ialah mod 2.5D yang diterangkan di bawah, bukannya menggunakan VPS yang lebih besar.
Jalankan dengan Docker
Ini ialah arahan yang didokumentasikan oleh pihak hulu.
docker run -d --name halcyon --network host --restart unless-stopped \
ghcr.io/halcyon-video/halcyon-videoKemudian, semak sama ada ia telah berjaya dimulakan.
docker logs halcyon
curl -I http://127.0.0.1:1420Log tersebut sepatutnya menunjukkan pelayan pratonton sedang mendengar pada port 1420, dan curl sepatutnya menjawab HTTP/1.1 200 OK. Kontena yang terhenti dalam masa beberapa saat hampir selalu disebabkan oleh isu port. --strictPort bermaksud pelayan enggan beralih ke 1421 apabila 1420 telah digunakan, lalu ia berhenti sebagai gantinya.
--network host disediakan untuk Remote Play, bukan untuk stor. WebRTC perlu mengiklankan alamat sebenar mesin kepada peranti yang mahukan strim tersebut. Di sebalik jambatan Docker lalai, kontena hanya mengetahui alamat 172.x miliknya sendiri, yang tidak boleh dicapai oleh mana-mana telefon dalam rangkaian anda, jadi strim tersebut tidak akan bersambung. Jika anda hanya mahukan stor dalam pelayar, terbitkan port tersebut sebagai gantinya.
docker run -d --name halcyon -p 1420:1420 --restart unless-stopped \
ghcr.io/halcyon-video/halcyon-videoItu adalah tetapan lalai yang lebih baik pada VPS, kerana rangkaian hos meletakkan kontena pada setiap antara muka yang dimiliki oleh mesin tersebut, termasuk antara muka awam. Menjalankan Docker pada VPS merangkumi baki pertimbangan tersebut. --restart unless-stopped ialah perkara yang mengembalikan stor selepas but semula, konsep yang sama seperti Servis Compose yang bermula semasa but.
Mengklon repositori dan menjalankan docker compose up -d akan membina imej secara setempat. Fail Compose yang disertakan membina daripada sumber secara lalai dan membawa baris image: yang dipra-bina dalam keadaan dikomen, jadi nyahkomen baris tersebut jika anda mahukan imej yang diterbitkan di bawah Compose.
Satu had keras setakat Ogos 2026: imej yang diterbitkan adalah linux/amd64 sahaja. Bahagian arm64 bagi tolak berbilang seni bina gagal di bawah emulasi dan sedang menunggu pelari arm asli. Pada VPS arm64, penarikan gagal dengan no matching manifest for linux/arm64/v8 in the manifest list entries, dan membina daripada klon adalah jalan penyelesaiannya.
Halakan ia ke pelayan Jellyfin anda
Buka http://<host>:1420 dan log masuk menggunakan alamat pelayan, nama pengguna dan kata laluan Jellyfin anda. Fail .env.local.example dalam repositori adalah untuk pembangunan setempat sahaja. Vite mendedahkan pemboleh ubah yang diawali dengan VITE_ kepada kod bahagian klien, jadi kata laluan Jellyfin yang ditulis di situ akan dikompilasi ke dalam bundle JavaScript yang dimuat turun oleh setiap pelawat. Pada pelayan yang boleh dicapai oleh orang lain, log masuk melalui antara muka tersebut.
Pelayar berkomunikasi dengan Jellyfin secara terus. Kontena Halcyon tidak memproksi API Jellyfin, dan ini membawa dua kesan yang perlu diketahui sebelum anda mula melakukan penyahpepijatan.
Pertama, Jellyfin mestilah boleh dicapai daripada pelayar, bukan sekadar daripada VPS yang menghoskan Halcyon. Jellyfin yang diikat pada 127.0.0.1:8096 adalah memadai untuk ujian setempat tetapi akan menyebabkan rak kosong bagi pengguna lain.
Kedua, panggilan tersebut adalah rentas asal (cross-origin), daripada alamat Halcyon ke alamat Jellyfin. Jellyfin menjawab permintaan API dengan Access-Control-Allow-Origin: * secara lalai, jadi ia berfungsi tanpa konfigurasi tambahan. Jika anda telah mengehadkan tetapan tersebut, atau meletakkan proksi pengesahan di hadapan API Jellyfin, konsol pelayar akan melaporkan blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource dan stor akan dimuatkan dengan rak yang kosong.
Letakkan di sebalik reverse proxy, dengan pengesahan di hadapan
vite preview ialah pelayan pratonton. Ia tidak menamatkan TLS (transport layer security) dan tidak mempunyai kawalan akses sendiri, jadi ia perlu diletakkan di sebalik nginx atau Caddy jika diakses secara awam.
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;
}
}Nama domain di hadapan container memerlukan satu lagi tetapan. Halcyon bertindak balas kepada localhost, alamat IP mentah dan nama mesin tempat ia dijalankan, sebagai langkah perlindungan terhadap DNS rebinding. Di dalam container, mesin tempat ia dijalankan ialah container itu sendiri, jadi hostname-nya bukan hostname anda. Permintaan yang tiba sebagai halcyon.example.com akan ditolak, dan respons akan menamakan hos yang ditolaknya. Tambahkan nama tersebut.
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-videoNilai tersebut dipisahkan dengan koma, titik di hadapan seperti .example.com memadankan subdomain, dan all mematikan semakan tersebut. Gunakan all hanya pada mesin yang tidak boleh dicapai oleh sesiapa di luar.
Apabila stor dihidangkan melalui https://, alamat Jellyfin yang anda taip semasa log masuk mestilah https:// juga. Pelayar akan menyekat panggilan API http:// biasa yang dibuat daripada halaman HTTPS, dan konsol akan memaparkan Mixed Content: The page at 'https://halcyon.example.com/' was loaded over HTTPS, but requested an insecure resource. Log masuk akan gagal begitu sahaja, tanpa penjelasan di dalam Halcyon. Hidangkan kedua-duanya melalui TLS, atau kekalkan kedua-duanya pada HTTP biasa di dalam rangkaian peribadi.
Seterusnya, pengesahan. Stor tersebut meminta kelayakan Jellyfin, jadi orang asing yang menemui URL tersebut akan berdepan dengan skrin log masuk. Satu ciri mengubah perkara ini. Menghidupkan Remote Play, di bawah Settings dan kemudian Connection, akan memberikan sesi Jellyfin anda kepada pelayan supaya pelawat ke /remote.html mendapat instans pustaka sebenar anda sendiri. Itulah tujuan ciri tersebut, dan ini bermakna kerahsiaan URL adalah satu-satunya penghalang antara internet dan filem anda. Jika anda mendayakan Remote Play, letakkan single sign on di hadapan keseluruhan tapak dengan Authentik sebagai gateway SSO yang dihoskan sendiri, atau buang hostname awam dan capai stor tersebut melalui tunnel WireGuard yang diuruskan dengan wg-easy.
Dua perincian perlu diambil perhatian. Reverse proxy hanya membawa stor tersebut: strim Remote Play ialah WebRTC melalui UDP dan tidak melalui HTTP proxy, jadi ia memerlukan laluan sendiri pada 3478/udp dan 49200 hingga 49260/udp apabila relay TURN yang disertakan digunakan. Dan docker run biasa di atas tidak menyimpan volume, jadi seed Remote Play tidak akan bertahan selepas docker rm. Fail Compose melekapkan volume halcyon-data pada /data dan menetapkan REMOTE_PLAY_SEED kepada /data/remote-play-seed.json atas sebab tersebut.
Apa yang perlu dilakukan apabila stor berfungsi dengan teruk
Halcyon melakukan render atas permintaan. Stor yang melahu tidak mengkompositkan sebarang bingkai, dan kehilangan fokus tetingkap akan menghentikan gelung animasi, itulah sebabnya tab yang dibiarkan terbuka tidak menghabiskan bateri komputer riba. Ini membantu mesin yang berada pada tahap prestasi minimum. Ia tidak membantu mesin yang tidak mampu melukis stor tersebut sama sekali.
Bagi klien tersebut, terdapat mod 2.5D, iaitu HTML dan CSS biasa tanpa WebGL, yang dikhususkan untuk perkakasan sekecil Raspberry Pi. Anda boleh bertukar antara 3D dan 2.5D daripada tetapan atau menu kuasa tanpa memuat semula halaman, jadi menguji kedua-duanya pada peranti yang sama hanya mengambil masa beberapa saat. Bersikap realistik tentang apa yang anda perolehi: penulis menyifatkan mod rata ini sebagai kasar dan masih dalam pembangunan. Anggap ia sebagai pilihan sandaran untuk klien yang lemah.
Apabila klien terlalu kecil untuk stor 3D, kegagalannya adalah ketara. Tab akan memuat semula dengan sendiri, atau pelayar melaporkan kehilangan konteks WebGL, biasanya semasa rak masih dalam proses pengisian. Tukarkan peranti tersebut kepada mod 2.5D daripada mengurangkan pustaka anda.
Sematkan imej dan semak sebelum anda melakukan pull
Ambil perkara ini dengan serius. Tag v0.1.0 hingga v0.3.1 kesemuanya dilancarkan dalam tempoh beberapa hari antara satu sama lain, dan v0.2.1 wujud hanya kerana proses push imej untuk v0.2.0 gagal. Laporan pepijat dialu-alukan di bahagian upstream, namun patch tidak diterima, jadi aliran keluaran (release stream) hanyalah keadaan kerja seorang individu sahaja.
Menjalankan latest dengan tabiat menggunakan docker pull bermakna storan boleh berubah tanpa pengetahuan anda pada bila-bila masa. Sematkan (pin) menggunakan digest, iaitu satu-satunya rujukan yang tidak boleh berubah.
docker buildx imagetools inspect ghcr.io/halcyon-video/halcyon-video:0.3.1Perintah tersebut memaparkan digest di sebalik tag berkenaan. Gunakannya sebagai ganti kepada tag tersebut.
docker run -d --name halcyon -p 1420:1420 --restart unless-stopped \
ghcr.io/halcyon-video/halcyon-video@sha256:747dcc821a3d2fa318b50e76024783c1835609047e84f502e23d021bc1898b20Digest tersebut adalah 0.3.1 pada 10 Ogos 2026. Baca sendiri digest semasa dan jangan hanya menyalinnya, serta baca nota keluaran sebelum anda beralih, kerana keluaran patch di sini boleh membawa perubahan pada susun atur storan selain daripada pembaikan pepijat.
FAQ
Adakah Halcyon memerlukan GPU pada VPS saya?
Tidak untuk kegunaan biasa. Kedai dipaparkan oleh three.js dalam pelayar, jadi mesin klien yang melakukan rendering dan kontena hanya menghidangkan fail statik pada port 1420. Pengecualiannya ialah Remote Play, yang menjalankan Chromium tanpa kepala (headless) pada pelayan dan menstrim hasilnya. Laluan itu melakukan rendering pada CPU kecuali anda memetakan /dev/dri ke dalam kontena untuk pecutan perkakasan.
Bolehkah saya meletakkan Halcyon pada internet awam?
Hanya jika di sebalik pengesahan. Kedai meminta kelayakan Jellyfin, tetapi menghidupkan Remote Play akan memberikan sesi Jellyfin anda kepada pelayan, jadi sesiapa sahaja yang memuatkan /remote.html akan mendapat instans pustaka sebenar anda tanpa perlu log masuk. Letakkan reverse proxy dengan single sign on di hadapannya, atau pastikan hostname tidak berada pada DNS awam dan akses kedai melalui VPN.
Mengapa rak kelihatan kosong selepas saya log masuk?
Pelayar memanggil API Jellyfin secara terus, jadi Jellyfin mestilah boleh dicapai daripada pelayar dan bukan hanya daripada VPS. Buka konsol pelayar. blocked by CORS policy bermaksud Jellyfin tidak menerima permintaan daripada alamat Halcyon. Mesej Mixed Content bermaksud halaman tersebut menggunakan HTTPS manakala alamat Jellyfin yang anda masukkan adalah HTTP biasa.
Adakah saya memerlukan --network host?
Hanya untuk Remote Play. WebRTC perlu mengiklankan alamat sebenar mesin, dan di sebalik Docker bridge, kontena hanya boleh menawarkan alamat 172.x yang tidak boleh dicapai oleh mana-mana telefon dalam rangkaian anda. Untuk melayari kedai dalam pelayar, -p 1420:1420 berfungsi dan mendedahkan jauh lebih sedikit bahagian hos.
Tag imej yang manakah perlu saya gunakan?
Gunakan digest (pin) dan bukannya latest. Baca digest untuk versi dengan docker buildx imagetools inspect ghcr.io/halcyon-video/halcyon-video:0.3.1, jalankan digest tersebut, dan beralih hanya selepas membaca nota keluaran. Sehingga Ogos 2026, imej yang diterbitkan adalah linux/amd64 sahaja, jadi hos arm64 perlu membina daripada klon dengan docker compose up -d.