← Blog

CamBooth 3.0.0 — รื้อใหญ่ทั้งระบบ

หลังสาย 1.x ทำงานมาเกือบสองปีจนโค้ดกระจุกเป็นก้อนเดียวยาว 3,000 บรรทัด เวอร์ชัน 3 คือการรื้อใหญ่เพื่อให้พัฒนาต่อได้อีกหลายปี นี่คือรีลีสที่ใหญ่ที่สุดในประวัติของ CamBooth

เปลี่ยนระบบกล้องใหม่

ย้ายไปใช้ระบบกล้องรุ่นใหม่ของ Windows โดยตรง แทนการต่อผ่านชั้นเก่าที่ซ้อนกันหลายชั้น ผลที่ตามมามีมากกว่าแค่ “ใหม่กว่า”

เห็น fps ที่ได้จริง ไม่ใช่ค่าที่ตั้งไว้

เพิ่มตัวนับอัตราเฟรมที่ได้จริงแสดงข้างข้อมูลกล้อง ปัญหาเดิมคือตั้ง 30 fps ไว้แล้วเข้าใจว่าได้ 30 แต่กล้องหรือเครื่องอาจให้ได้จริงแค่ 15 โดยไม่มีใครรู้ จนกระทั่งเปิดคลิปย้อนหลังแล้วพบว่าภาพกระตุก

ตอนนี้ระบบตรวจจับความไม่ตรงกันนี้ที่สามจุด และถ้าพบจะขึ้นข้อความเตือนภาษาไทยต่อท้ายข้อมูลกล้องทันที เช่น “ตั้ง 30 fps แต่กล้องได้ ~15 fps” พร้อมบันทึกลงไฟล์บันทึกเหตุการณ์

จำกัดอัตราเฟรมได้จริง สองชั้น

  • ชั้นฮาร์ดแวร์ — เลือกรูปแบบภาพจากกล้องที่ให้ fps สูงสุดเท่าที่ไม่เกินค่าที่ตั้งไว้ ตัดภาระตั้งแต่ต้นทาง
  • ชั้นซอฟต์แวร์ — เฟรมที่มาถี่เกินกว่าที่ต้องการจะถูกทิ้ง ไม่เอาไปเขียนลงไฟล์

ตัวคุมจังหวะการอัดให้ fps คงที่

ปัญหาคลาสสิกของการอัดวิดีโอคือ กล้องส่งภาพมาไม่สม่ำเสมอ แต่ไฟล์วิดีโอต้องการเฟรมที่ระยะเท่ากัน ถ้าเขียนตามที่ได้มาตรง ๆ คลิปจะเร็วบ้างช้าบ้าง และความยาวคลิปไม่ตรงกับเวลาจริง

ตัวคุมจังหวะใหม่ทำงานแบบนี้

  • ทุกช่วงเวลาที่ถึงกำหนด จะหยิบเฟรมล่าสุดที่ได้รับมาเขียนลงไฟล์
  • ถ้าช่วงนั้นไม่มีเฟรมใหม่เข้ามาเลย จะเขียนเฟรมเดิมซ้ำ เพื่อให้เวลาในคลิปเดินตรงกับเวลาจริง
  • ถ้าตามหลังเกิน 5 ช่วงเวลา (เช่นดิสก์สะดุด) จะข้ามไปจุดปัจจุบันแทนที่จะไล่เขียนย้อนหลังจนคลิปเพี้ยน

ตัวเลือก fps แบบเลือกง่าย พร้อมประมาณพื้นที่

เปลี่ยนจากให้กรอกตัวเลขเอง มาเป็นตัวเลือกที่บอกว่าเหมาะกับงานแบบไหน พร้อมประมาณการพื้นที่จัดเก็บให้เห็นทันทีตอนเลือก

  • Smooth (30 fps) — เหมาะกับแพ็คของเร็ว
  • Normal (15 fps) — เหมาะกับงานทั่วไป
  • Storage saver (10 fps) — เหมาะกับฮาร์ดดิสก์เล็ก

แตกโค้ดก้อนเดียวออกเป็นบริการย่อย

ไฟล์ยาว 3,000 บรรทัดถูกแยกออกเป็นบริการที่รับผิดชอบเรื่องเดียวชัดเจน 5 ตัว

  • บริการอ่านค่าตาชั่ง — จัดการพอร์ตอนุกรม ตรวจจับว่าค่านิ่งแล้วหรือยัง และเชื่อมต่อกลับอัตโนมัติเมื่อหลุด
  • บริการรายงานสถานะและรับงาน — ส่งสัญญาณบอกเซิร์ฟเวอร์ว่าเครื่องยังทำงานอยู่ และรับงานที่เซิร์ฟเวอร์สั่งมา
  • บริการอัปเดตข้อมูลคลิป — ส่งข้อมูลของคลิปขึ้นเซิร์ฟเวอร์และจับคู่รหัสคลิปฝั่งเซิร์ฟเวอร์กลับมา
  • บริการเฝ้าดูสถานะเครื่อง — ตรวจพื้นที่ดิสก์ นับจำนวนข้อมูล และกวาดลบคลิปเก่าตามนโยบายที่ตั้งไว้
  • บริการอัปโหลดไฟล์ — ส่งไฟล์คลิปขึ้นเซิร์ฟเวอร์แล้วแจ้งกลับเมื่อเสร็จ

อัปโหลดใหม่อัตโนมัติเมื่อล้มเหลว

บริการอัปโหลดได้ตัวจัดการรอบใหม่ที่

  • ลองใหม่ได้สูงสุด 3 ครั้งต่อคลิป
  • ข้ามคลิปที่อัปโหลดไปแล้ว ไม่ให้เกิดไฟล์ซ้ำบนเซิร์ฟเวอร์
  • คลิปหนึ่งล้มเหลวไม่ทำให้ทั้งชุดหยุด — ตัวที่เหลือยังส่งต่อได้
  • รักษาลำดับของคลิปในชุดไว้
  • บันทึกเหตุการณ์ทุกครั้ง ทั้งตอนสำเร็จและตอนล้มเหลว

รื้อการทำงานเบื้องหลังใหม่ทั้งหมด

ส่วนนี้คือที่มาของอาการค้างและภาพกระตุกในเวอร์ชันเก่า ซึ่งไล่แก้ทีละอาการมาหลายปีแต่ไม่หายขาด รอบนี้รื้อทั้งระบบ

  • แยกงานอ่านภาพออกจากงานวาดหน้าจอ — เดิมสองอย่างนี้ผูกกันอยู่ ทำให้พอวาดหน้าจอช้า การอ่านภาพก็ช้าตาม
  • ใช้คิวรับภาพระหว่างกลาง — รองรับภาพได้ 60 เฟรม ทำให้ฝั่งอ่านกับฝั่งเขียนไม่ต้องรอกัน
  • เปลี่ยนการอ่านค่าตาชั่งจากแบบรอค้างเป็นแบบไม่บล็อก — ปัญหาเดิมคือถ้าตาชั่งเงียบไปเกิน 5 วินาที เธรดที่อ่านค่าจะตายไปเลย แล้วต้องปิดเปิดโปรแกรมใหม่
  • รวมการอัปเดตหน้าจอเป็นชุดเดียว แทนที่จะสั่งวาดทีละจุด
  • ปิดโปรแกรมได้สะอาด — ตอนปิดจะรอให้งานเบื้องหลังจบภายใน 2 วินาที แล้วหยุดตัวจับเวลาทุกตัวให้เรียบร้อย ไม่ทิ้งงานค้าง

แก้บั๊กที่สะสมมานาน

รอบนี้ไล่เก็บบั๊กที่ค้างมาจากสายเก่ากว่าสิบรายการ ที่สำคัญได้แก่

  • การแย่งกันเขียนไฟล์วิดีโอ — เธรดอ่านภาพกับเธรดเขียนไฟล์เข้าถึงตัวเขียนพร้อมกันได้ ทำให้ไฟล์เสียเป็นครั้งคราว
  • ภาพฉีกกลางจอ — เกิดจากการส่งภาพให้หน้าจอในจังหวะที่ภาพยังเขียนไม่เสร็จ
  • เธรดอ่านตาชั่งตายเมื่อเงียบครั้งเดียว — ตาชั่งไม่ส่งค่ามา 5 วินาทีก็พอให้ระบบอ่านน้ำหนักตายทั้งรอบ
  • การอ่านค่าน้ำหนักที่อ่านได้ครึ่ง ๆ — สองเธรดอ่านเขียนค่าเดียวกันพร้อมกันจนได้ตัวเลขที่ไม่ใช่ทั้งค่าเก่าและค่าใหม่
  • โปรแกรมพังเมื่อไม่มีไฟล์ลิขสิทธิ์ — เส้นทางสำรองไม่ได้เตรียมไว้
  • จอตั้งค่าพังเมื่อรายการว่าง — หลายจุดในหน้าตั้งค่าที่อ่านค่าจากรายการโดยไม่เช็กว่ามีข้อมูลหรือไม่
  • รายการความละเอียดของกล้องอ่านไม่ครบ
  • นโยบายลบคลิปเก่าแบบนับจำนวนโฟลเดอร์ไม่เคยทำงาน — ตั้งไว้ว่าให้เก็บกี่วันย้อนหลังนั้นใช้ได้ แต่โหมด “เก็บกี่โฟลเดอร์ล่าสุด” ไม่เคยทำงานเลย รอบนี้เขียนใหม่ทั้งส่วน แยกการตัดสินใจว่าจะลบอะไรออกมาเป็นส่วนที่ทดสอบได้ รองรับทั้งสองโหมด และเผื่อกรณีชื่อโฟลเดอร์ผิดรูปแบบ

บันทึกเหตุการณ์ลงไฟล์

ก่อนหน้านี้เวลาเครื่องหน้างานมีปัญหา แทบไม่มีอะไรให้ดูย้อนหลังเลย รอบนี้เพิ่มระบบบันทึกเหตุการณ์ลงไฟล์ แยกไฟล์ตามวัน เก็บไว้ในโฟลเดอร์ของตัวเอง และเริ่มทำงานตั้งแต่วินาทีแรกที่โปรแกรมเปิด — ก่อนที่ส่วนอื่นจะเริ่มด้วยซ้ำ เพื่อให้จับปัญหาตั้งแต่ตอนโหลดค่าตั้งต้นได้

พร้อมกันนั้นดักจับข้อผิดพลาดที่เกิดในงานเบื้องหลังซึ่งเดิมหายเงียบไปโดยไม่มีใครรู้

ทดสอบอัตโนมัติได้แล้ว

เพิ่มชุดทดสอบอัตโนมัติเป็นครั้งแรกในประวัติของโปรเจกต์ ครอบคลุมส่วนที่พังแล้วเจ็บที่สุด

  • กฎการตรวจสอบค่าตั้งค่า — ทุกกฎที่ตัวตรวจสอบบังคับไว้
  • รูปแบบไฟล์ตั้งค่า — ตรึงไว้ไม่ให้เปลี่ยนโดยไม่ตั้งใจ ซึ่งจะทำให้เครื่องหน้างานอ่านค่าเดิมไม่ได้
  • การเข้ารหัสและถอดรหัสลิขสิทธิ์ — ทดสอบวนรอบว่าเข้าแล้วถอดได้ค่าเดิม

พร้อมเช็กลิสต์การทดสอบด้วยมือก่อนปล่อยรุ่น สำหรับส่วนที่ทดสอบอัตโนมัติไม่ได้ (กล้อง ตาชั่ง เครื่องสแกนของจริง)

ตัวติดตั้งและระบบออกรุ่นอัตโนมัติ

  • ตัวติดตั้งสำหรับ Windows อย่างเป็นทางการ — แทนการแจกไฟล์ zip
  • ระบบสร้างและเซ็นรับรองไฟล์ติดตั้งอัตโนมัติ เมื่อออกรุ่นใหม่ — การเซ็นรับรองสำคัญเพราะ Windows จะเตือนว่าโปรแกรมไม่น่าเชื่อถือถ้าไม่ได้เซ็น ซึ่งทำให้ลูกค้าลังเลตอนติดตั้ง
  • คู่มือสำหรับผู้ดูแล — ตั้งแต่ขอใบรับรองจนถึงปล่อยรุ่น
  • รวมการกำหนดเวอร์ชันไลบรารีไว้ที่เดียว — เดิมแต่ละโปรเจกต์ระบุเวอร์ชันของตัวเอง ทำให้เกิดกรณีที่โปรเจกต์คนละตัวใช้ไลบรารีคนละรุ่นแล้วชนกัน
  • ตรึงรุ่นของชุดพัฒนา — เครื่องของทุกคนและเครื่องที่สร้างรุ่นจริงใช้รุ่นเดียวกัน

อัปเกรดพื้นฐานและจัดบ้าน

  • ย้ายทั้งระบบไปที่ .NET 10 ทุกโปรเจกต์ พร้อมอัปเดตไลบรารีทุกตัวเป็นรุ่นล่าสุด
  • เปลี่ยนชื่อโปรเจกต์ให้สื่อความหมาย — ชื่อเดิมอ่านแล้วไม่รู้ว่าคืออะไร เปลี่ยนเป็นชื่อที่บอกหน้าที่ตรง ๆ
  • เอาไฟล์ติดตั้งเก่าออกจากเว็บ — เดิมเว็บพกไฟล์ติดตั้งขนาดรวมกว่า 120 MB ไปด้วยทุกครั้งที่ deploy เปลี่ยนเป็นลิงก์ไปหน้าดาวน์โหลดของ GitHub แทน
  • เอาไฟล์ฐานข้อมูลตั้งต้นออก — ราว 3 MB ที่ไม่จำเป็นแล้ว เพราะระบบสร้างฐานข้อมูลจากโค้ดได้เอง
  • ลบรหัสผ่านฐานข้อมูลที่ฝังอยู่ในโค้ด — เปลี่ยนไปอ่านจากไฟล์ตั้งค่าแทน
  • ลบโค้ดและตัวแปรที่ไม่ได้ใช้แล้ว จำนวนมาก หลังจากงานย้ายเข้าบริการย่อยเสร็จ
CamBooth

บันทึกคลิปตอนแพ็คสินค้า ลดปัญหาการเคลม

ดูรายละเอียด →

อ่านต่อ

CamBooth

คลิปที่ระบบบอกว่ามี แต่เปิดไม่เจอ — บั๊กที่อันตรายที่สุดของระบบเก็บหลักฐาน

ตั้งโฟลเดอร์เก็บวิดีโอเป็นชื่อภาษาไทย แล้วระบบบันทึกว่ามีคลิปทั้งที่ไฟล์ไม่เคยถูกเขียนลงไป — บทความว่าด้วยความล้มเหลวแบบเงียบ และทำไมมันร้ายแรงกว่าโปรแกรมพัง

CamBooth

CamBooth — ยกฝั่งเว็บขึ้น Docker และย้ายฐานข้อมูลไป PostgreSQL

งานฝั่งเซิร์ฟเวอร์ — ติดตั้งเว็บด้วย Docker Compose ซ้อมย้ายฐานข้อมูลไป PostgreSQL จนผ่านจริงไม่ใช่แค่เขียนสคริปต์ทิ้งไว้ และเพิ่มเครื่องมือตรวจว่าโครงสร้างฐานข้อมูลบนเครื่องจริงตรงกับที่โค้ดคาดหวังหรือไม่

CamBooth

CamBooth — อัดคลิปตอนแพ็คสินค้า ลดข้อพิพาทเรื่องของไม่ครบ

บันทึกคลิปขณะแพ็คสินค้าเก็บเป็นหลักฐานทุกออเดอร์ มีทั้งโหมดมาตรฐาน (อัดคลิป + เสียง + ซับไตเติล) และโหมดเชื่อมต่อ Zort API