เอกสาร / สรุปงาน · 2026-10-26 · /opt/data/docs/2026-10-26-media-server.md
| อย่าง | ค่า |
|---|---|
| ซอฟต์แวร์ | Jellyfin 12.3.0 (docker, jellyfin/jellyfin:latest, 751 MB) |
| URL | https://media.thisaan.com (Caddy → 127.0.0.1:8096) |
| storage | /srv/media/{movies,shows} (เมาท์เข้า container แบบ read-only) |
| config/cache | /opt/jellyfin/{config,cache} (ไม่หายเมื่อ container สร้างใหม่) |
| admin | สร้างผ่าน API — รหัสอยู่ใน /root/jellyfin-admin.txt (โหมด 600) ไม่พิมพ์ในแชท |
| library | Movies + Shows · สแกนแล้ว 3 รายการ (h264 1080p, h264 720p, hevc 10-bit 1080p) |
| การทดสอบ | ผล |
|---|---|
| Direct play | HTTP 206 Partial Content · video/mp4 · 1 MB ใน 0.06 วิ = 16.6 MB/s |
| ffmpeg transcode เดี่ยว (1080p→720p 3 Mbps, 2 threads) | 17.5 วิ สำหรับคลิป 120 วิ = 6.9× realtime |
| 3 สตรีมพร้อมกัน (ffmpeg ล้วน) | 49 วิ/สตรีม = 2.45× realtime ยังทัน |
| Jellyfin transcode จริง (HLS) | TranscodeReasons = ContainerBitrateExceedsLimit · playlist 40 segment · ดึง 3 segment = 1.97 MB |
| CPU ระหว่าง Jellyfin transcode 1 สตรีม | 92% โดยเฉลี่ย (78.9 → 97.5%) |
+faststart (สคริปต์ ffmpeg ใช้ได้เลย) → direct play 100%media.thisaan.com ผ่าน Caddy — มี TLS อยู่แล้ว ไม่ต้องเปิดพอร์ต 32400/dev/nvidia* ไม่มี, ไม่มี nvidia-smi)/opt/data/tools/media_optimize.py (รันบน host: python3 /opt/jellyfin/media_optimize.py /srv/media/movies)
| ความสามารถ | รายละเอียด |
|---|---|
| ตรวจก่อนแปลง | ffprobe: h264? + aac? + moov อยู่หัวไฟล์ (faststart)? |
| แปลง | libx264 -crf 22 -pix_fmt yuv420p + aac 160k + +faststart |
| สำรองต้นฉบับ | ย้ายไป /srv/media/.originals/<path> — ไม่ลบ |
| ตรวจหลังแปลง | ถ้าไม่ผ่าน h264/aac/faststart → ลบไฟล์ชั่วคราว ไม่แตะต้นฉบับ |
| โหมดดูเฉยๆ | --dry |
```
OK Test 1080p H264.mp4 · h264/yuv420p aac faststart=True (ไม่ต้องแตะ)
CONV Test 1080p HEVC10.mp4 · hevc/yuv420p10le → h264/yuv420p faststart=True
CONV Test 720p H264.mp4 · h264 ไม่มี faststart → ใส่ faststart
{"already": 1, "converted": 2, "failed": 0}
```
หลังแปลง + Library/Refresh → Jellyfin รายงาน directplay=True ทั้ง 3 เรื่อง (ก่อนหน้านี้ HEVC จะถูกบังคับ transcode)
#!/bin/sh บน Ubuntu = dash → read -d '' ใช้ไม่ได้ (Illegal option -d) ทำให้ loop ข้ามไฟล์→ เขียนเป็น Python แทน shell เมื่อต้องวนไฟล์ที่มีช่องว่างในชื่อ
os.path.getsize() ก่อน แปลง ไม่งั้นได้เลขเท่ากันทั้งสองฝั่ง