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 ที่ไม่จำเป็นแล้ว เพราะระบบสร้างฐานข้อมูลจากโค้ดได้เอง
- ลบรหัสผ่านฐานข้อมูลที่ฝังอยู่ในโค้ด — เปลี่ยนไปอ่านจากไฟล์ตั้งค่าแทน
- ลบโค้ดและตัวแปรที่ไม่ได้ใช้แล้ว จำนวนมาก หลังจากงานย้ายเข้าบริการย่อยเสร็จ
บันทึกคลิปตอนแพ็คสินค้า ลดปัญหาการเคลม