สำรวจความสามารถของการคัดลอกส่วนของเฟรมวิดีโอด้วย WebCodecs VideoFrame เพื่อการทำซ้ำบางส่วนของเฟรมอย่างมีประสิทธิภาพ การปรับปรุง และเทคนิคการประมวลผลวิดีโอขั้นสูงในเว็บแอปพลิเคชัน
การคัดลอกส่วนของเฟรมวิดีโอ (Region Copying) ด้วย WebCodecs VideoFrame: การทำซ้ำบางส่วนของเฟรมและการปรับปรุงประสิทธิภาพ
WebCodecs API กำลังปฏิวัติการประมวลผลสื่อบนเว็บ โดยให้การควบคุมการเข้ารหัสและถอดรหัสวิดีโอและเสียงอย่างที่ไม่เคยมีมาก่อน หนึ่งในคุณสมบัติที่ทรงพลังเป็นพิเศษคือความสามารถในการคัดลอกส่วนของอ็อบเจ็กต์ VideoFrame เทคนิคนี้ ซึ่งมักเรียกว่าการทำซ้ำบางส่วนของเฟรม ช่วยให้นักพัฒนาสามารถดึงและนำส่วนเฉพาะของเฟรมวิดีโอกลับมาใช้ใหม่ได้อย่างมีประสิทธิภาพ เปิดประตูสู่การปรับปรุงประสิทธิภาพและสถานการณ์การประมวลผลวิดีโอขั้นสูงต่างๆ บทความนี้จะเจาะลึกถึงความสามารถของการคัดลอกส่วนของเฟรมวิดีโอด้วย WebCodecs สำรวจการใช้งาน ประโยชน์ และรายละเอียดการนำไปใช้สำหรับนักพัฒนาเว็บทั่วโลก
ทำความเข้าใจเกี่ยวกับการคัดลอกส่วนของเฟรมวิดีโอ (VideoFrame Region Copying)
โดยหลักการแล้ว การคัดลอกส่วนของเฟรมวิดีโอคือการสร้างอ็อบเจ็กต์ VideoFrame ใหม่ซึ่งมีเพียงบางส่วนของเฟรมเดิมเท่านั้น ซึ่งทำได้โดยการระบุพื้นที่สี่เหลี่ยม (กำหนดโดยพิกัดมุมซ้ายบน ความกว้าง และความสูง) ที่จะคัดลอกจาก VideoFrame ต้นทาง เฟรมที่ได้คือสำเนาของพื้นที่ที่ระบุ ซึ่งสามารถนำไปใช้ประมวลผลหรือเข้ารหัสต่อไปได้อย่างอิสระ
กระบวนการนี้แตกต่างจากการปรับขนาดหรือการครอบตัดวิดีโอทั่วไป เนื่องจากช่วยให้สามารถทำซ้ำองค์ประกอบเฉพาะภายในเฟรมวิดีโอได้อย่างเลือกสรร ตัวอย่างเช่น คุณอาจต้องการทำซ้ำโลโก้ วัตถุที่กำลังเคลื่อนไหว หรือพื้นที่ที่น่าสนใจเพื่อการวิเคราะห์หรือปรับปรุงเพิ่มเติม
WebCodecs API มีเมธอด copyTo() บนอ็อบเจ็กต์ VideoFrame ซึ่งเป็นกลไกหลักในการคัดลอกส่วนของเฟรม เมธอดนี้ช่วยให้คุณสามารถระบุ VideoFrame ปลายทาง พื้นที่ต้นทางที่จะคัดลอก และตัวเลือกต่างๆ เพื่อควบคุมกระบวนการคัดลอกได้
กรณีการใช้งานและการประยุกต์ใช้
การคัดลอกส่วนของเฟรมวิดีโอมีการประยุกต์ใช้งานมากมายในการประมวลผลสื่อบนเว็บ นี่คือตัวอย่างที่สำคัญบางส่วน:
1. การปรับปรุงประสิทธิภาพการเข้ารหัสวิดีโอ
ในสถานการณ์ที่พื้นที่เฉพาะของเฟรมวิดีโอยังคงค่อนข้างนิ่งหรือมีการเปลี่ยนแปลงที่คาดเดาได้ สามารถใช้การคัดลอกส่วนของเฟรมเพื่อปรับปรุงประสิทธิภาพการเข้ารหัสวิดีโอได้อย่างมาก โดยการแยกส่วนที่เคลื่อนไหวของเฟรมและเข้ารหัสเฉพาะส่วนเหล่านั้น คุณสามารถลดบิตเรตโดยรวมและปรับปรุงประสิทธิภาพการเข้ารหัสได้
ตัวอย่าง: ลองพิจารณาแอปพลิเคชันสตรีมมิ่งสดที่เนื้อหาหลักเป็นสไลด์นำเสนอ ฟีดวิดีโอของผู้บรรยายอาจใช้พื้นที่เพียงส่วนเล็กๆ ของเฟรมเท่านั้น ด้วยการคัดลอกและเข้ารหัสเฉพาะส่วนของผู้บรรยายพร้อมกับเนื้อหาสไลด์ที่เปลี่ยนแปลง คุณสามารถหลีกเลี่ยงการเข้ารหัสพื้นหลังที่นิ่งซ้ำ ซึ่งส่งผลให้สตรีมมีประสิทธิภาพมากขึ้น
2. การสร้างเอฟเฟกต์ภาพ
การคัดลอกส่วนของเฟรมสามารถเป็นเครื่องมือที่ทรงพลังในการสร้างเอฟเฟกต์ภาพต่างๆ เช่น:
- การติดตามและทำซ้ำวัตถุ: ติดตามวัตถุที่กำลังเคลื่อนไหวในวิดีโอและทำซ้ำไปทั่วทั้งเฟรมเพื่อสร้างเอฟเฟกต์ภาพที่น่าสนใจ
- การเบลอหรือเพิ่มความคมชัดเฉพาะส่วน: ใช้เอฟเฟกต์เบลอหรือเพิ่มความคมชัดเฉพาะส่วนของวิดีโอ เช่น ใบหน้าหรือพื้นที่ที่น่าสนใจ
- การสร้างเอฟเฟกต์ภาพซ้อนภาพ (Picture-in-Picture): สร้างเลย์เอาต์แบบภาพซ้อนภาพได้อย่างง่ายดายโดยการคัดลอกส่วนของเฟรมวิดีโอขนาดเล็กไปวางบนเฟรมที่ใหญ่กว่า
- การเน้นพื้นที่เฉพาะ: คัดลอกพื้นที่และใช้ฟิลเตอร์สีหรือการปรับปรุงภาพอื่นๆ เพื่อดึงดูดความสนใจ
ตัวอย่าง: การใช้งานที่เป็นที่นิยมคือการสร้างเอฟเฟกต์ "ซูมดิจิทัล" โดยที่ส่วนหนึ่งของวิดีโอถูกคัดลอกและขยายขนาดขึ้นเพื่อขยายเนื้อหาภายในบริเวณนั้น
3. การเพิ่มข้อมูล (Data Augmentation) สำหรับ Machine Learning
ในการใช้งาน Machine Learning ที่เกี่ยวข้องกับการวิเคราะห์วิดีโอ การคัดลอกส่วนของเฟรมสามารถใช้เป็นเทคนิคการเพิ่มข้อมูล (Data Augmentation) ได้ โดยการคัดลอกและจัดการพื้นที่ที่น่าสนใจภายในเฟรมวิดีโอ คุณสามารถสร้างตัวอย่างการฝึกใหม่ที่ทำให้โมเดลได้พบกับความหลากหลายมากขึ้นและปรับปรุงความสามารถในการสรุปผลของโมเดล
ตัวอย่าง: หากคุณกำลังฝึกโมเดลเพื่อตรวจจับวัตถุในวิดีโอ คุณสามารถคัดลอกส่วนต่างๆ ของเฟรมที่มีวัตถุเหล่านั้นและวางลงในเฟรมใหม่ที่มีพื้นหลังและสภาพแสงที่แตกต่างกัน ซึ่งเป็นการสร้างข้อมูลการฝึกเพิ่มเติมได้อย่างมีประสิทธิภาพ
4. การกลั่นกรองเนื้อหาและการเซ็นเซอร์
แม้จะไม่ใช่จุดประสงค์หลัก แต่การคัดลอกส่วนของเฟรมสามารถนำมาใช้ในการกลั่นกรองเนื้อหาได้ พื้นที่เฉพาะที่มีเนื้อหาที่ละเอียดอ่อนหรือไม่เหมาะสมสามารถถูกระบุและแทนที่ด้วยพื้นที่ที่เบลอหรือทำให้เป็นสีดำซึ่งคัดลอกมาจากส่วนอื่นของเฟรมหรือจากมาสก์ที่กำหนดไว้ล่วงหน้า การดำเนินการนี้ต้องทำอย่างมีความรับผิดชอบและมีจริยธรรม โดยปฏิบัติตามแนวทางทางกฎหมายและจริยธรรม
ตัวอย่าง: ในบางภูมิภาค อาจจำเป็นต้องเซ็นเซอร์โลโก้หรือข้อความบางอย่างเพื่อให้เป็นไปตามกฎหมาย การคัดลอกส่วนของเฟรมช่วยให้สามารถแก้ไของค์ประกอบเหล่านี้ได้โดยอัตโนมัติ
5. การตัดต่อวิดีโอและการซ้อนภาพ
การคัดลอกส่วนของเฟรมสามารถรวมเข้ากับเครื่องมือตัดต่อวิดีโอบนเว็บเพื่อเพิ่มความสามารถในการซ้อนภาพขั้นสูง ผู้ใช้สามารถเลือกและคัดลอกส่วนเฉพาะจากเฟรมวิดีโอต่างๆ และรวมเข้าด้วยกันเพื่อสร้างฉากและเอฟเฟกต์ภาพที่ซับซ้อน
ตัวอย่าง: การสร้างเอฟเฟกต์แบ่งหน้าจอ (split-screen) หรือการซ้อนองค์ประกอบวิดีโอต่างๆ ทับกันจะทำได้ง่ายขึ้นอย่างมากด้วยความสามารถในการคัดลอกและจัดการส่วนของเฟรมวิดีโอ
การใช้งาน VideoFrame Region Copying ด้วย WebCodecs
ในการใช้งานการคัดลอกส่วนของเฟรมวิดีโอ คุณจะต้องใช้เมธอด copyTo() ของอินเทอร์เฟซ VideoFrame นี่คือขั้นตอนโดยสรุป:
1. รับ VideoFrame
ขั้นแรก คุณต้องได้รับอ็อบเจ็กต์ VideoFrame ซึ่งสามารถทำได้หลายวิธี เช่น:
- การถอดรหัสสตรีมวิดีโอ: ใช้
VideoDecoderAPI เพื่อถอดรหัสเฟรมวิดีโอจากสตรีม - การจับภาพวิดีโอจากกล้อง: ใช้
getUserMedia()API เพื่อจับภาพวิดีโอจากกล้องและสร้างอ็อบเจ็กต์VideoFrameจากเฟรมที่จับได้ - การสร้าง VideoFrame จาก ImageBitmap: ใช้ constructor
VideoFrame()กับImageBitmapเป็นแหล่งข้อมูล
2. สร้าง VideoFrame ปลายทาง
ถัดไป คุณต้องสร้างอ็อบเจ็กต์ VideoFrame ปลายทางที่จะเก็บส่วนที่คัดลอก ขนาดและรูปแบบของเฟรมปลายทางควรเหมาะสมกับส่วนที่คุณต้องการคัดลอก รูปแบบต้องเข้ากันได้กับ VideoFrame ต้นทาง ควรพิจารณาใช้รูปแบบเดียวกับต้นทางเพื่อหลีกเลี่ยงปัญหาการแปลงรูปแบบที่อาจเกิดขึ้น
```javascript const sourceFrame = // ... obtain a VideoFrame object const regionWidth = 100; const regionHeight = 50; const destinationFrame = new VideoFrame(sourceFrame, { codedWidth: regionWidth, codedHeight: regionHeight, width: regionWidth, height: regionHeight, }); ```
3. ใช้เมธอด copyTo()
ตอนนี้ คุณสามารถใช้เมธอด copyTo() เพื่อคัดลอกส่วนจากเฟรมต้นทางไปยังเฟรมปลายทางได้ เมธอด copyTo() รับ VideoFrame ปลายทางเป็นอาร์กิวเมนต์ และอ็อบเจ็กต์ตัวเลือก (optional options object) เพื่อกำหนดสี่เหลี่ยมต้นทางและพารามิเตอร์การคัดลอกอื่นๆ
```javascript const sourceFrame = // ... obtain a VideoFrame object const destinationFrame = // ... create a destination VideoFrame object const copyOptions = { x: 50, // X-coordinate of the top-left corner of the source region y: 25, // Y-coordinate of the top-left corner of the source region width: 100, // Width of the source region height: 50, // Height of the source region }; sourceFrame.copyTo(destinationFrame, copyOptions); ```
4. ประมวลผลส่วนที่คัดลอก
หลังจากที่เมธอด copyTo() ทำงานเสร็จสิ้น destinationFrame จะมีส่วนที่คัดลอกมาจากเฟรมต้นทาง จากนั้นคุณสามารถประมวลผลเฟรมนี้ต่อไปได้ เช่น การเข้ารหัส การแสดงผลบน canvas หรือใช้เป็นข้อมูลป้อนเข้าสำหรับโมเดล Machine Learning
ตัวอย่าง: การคัดลอกส่วนของเฟรมอย่างง่าย
นี่คือตัวอย่างที่สมบูรณ์ซึ่งสาธิตการคัดลอกส่วนของเฟรมขั้นพื้นฐาน:
```javascript async function copyRegion(sourceFrame, x, y, width, height) { const destinationFrame = new VideoFrame(sourceFrame, { codedWidth: width, codedHeight: height, width: width, height: height, }); await sourceFrame.copyTo(destinationFrame, { x: x, y: y, width: width, height: height, }); return destinationFrame; } // Example usage: async function processVideo(videoElement) { const videoTrack = videoElement.captureStream().getVideoTracks()[0]; const imageCapture = new ImageCapture(videoTrack); // Get a single frame from the video const bitmap = await imageCapture.grabFrame(); const sourceFrame = new VideoFrame(bitmap); bitmap.close(); // Copy a region from the source frame const copiedFrame = await copyRegion(sourceFrame, 100, 50, 200, 100); // Display the copied frame on a canvas const canvas = document.getElementById('outputCanvas'); canvas.width = copiedFrame.width; canvas.height = copiedFrame.height; const ctx = canvas.getContext('2d'); ctx.drawImage(copiedFrame, 0, 0); sourceFrame.close(); copiedFrame.close(); } ```
ข้อควรพิจารณาด้านประสิทธิภาพ
แม้ว่าการคัดลอกส่วนของเฟรมวิดีโอจะมีข้อดีมากมาย แต่สิ่งสำคัญคือต้องพิจารณาถึงผลกระทบด้านประสิทธิภาพ โดยเฉพาะอย่างยิ่งในแอปพลิเคชันแบบเรียลไทม์:
- การจัดสรรหน่วยความจำ: การสร้างอ็อบเจ็กต์
VideoFrameใหม่เกี่ยวข้องกับการจัดสรรหน่วยความจำ ซึ่งอาจเป็นคอขวดด้านประสิทธิภาพหากทำบ่อยครั้ง ควรพิจารณานำอ็อบเจ็กต์VideoFrameกลับมาใช้ใหม่เมื่อเป็นไปได้เพื่อลดภาระหน่วยความจำ - ภาระในการคัดลอก: เมธอด
copyTo()เองก็เกี่ยวข้องกับการคัดลอกข้อมูลพิกเซล ซึ่งอาจต้องใช้การคำนวณสูง โดยเฉพาะสำหรับพื้นที่ขนาดใหญ่ ควรปรับโค้ดของคุณเพื่อลดปริมาณข้อมูลที่คัดลอก - การแปลงรูปแบบ: หากอ็อบเจ็กต์
VideoFrameต้นทางและปลายทางมีรูปแบบต่างกัน เมธอดcopyTo()อาจต้องทำการแปลงรูปแบบ ซึ่งอาจเพิ่มภาระงานอย่างมาก การใช้รูปแบบที่เข้ากันได้สามารถปรับปรุงประสิทธิภาพได้อย่างมีนัยสำคัญ - การดำเนินการแบบอะซิงโครนัส: การดำเนินการ
copyTo()มักจะเป็นแบบอะซิงโครนัส โดยเฉพาะเมื่อมีการใช้การเร่งความเร็วด้วยฮาร์ดแวร์ ควรจัดการลักษณะการทำงานแบบอะซิงโครนัสอย่างเหมาะสมเพื่อหลีกเลี่ยงการบล็อกเธรดหลัก - การเร่งความเร็วด้วยฮาร์ดแวร์: WebCodecs ใช้ประโยชน์จากการเร่งความเร็วด้วยฮาร์ดแวร์ทุกครั้งที่เป็นไปได้ ตรวจสอบให้แน่ใจว่าการเร่งความเร็วด้วยฮาร์ดแวร์เปิดใช้งานอยู่ในเบราว์เซอร์ของผู้ใช้เพื่อประสิทธิภาพสูงสุด ตรวจสอบการตั้งค่าเบราว์เซอร์และความเข้ากันได้ของไดรเวอร์
แนวปฏิบัติที่ดีที่สุดสำหรับการปรับปรุงประสิทธิภาพ
เพื่อเพิ่มประสิทธิภาพและประสิทธิผลของการคัดลอกส่วนของเฟรมวิดีโอให้สูงสุด ควรพิจารณาแนวปฏิบัติที่ดีที่สุดต่อไปนี้:
- นำอ็อบเจ็กต์ VideoFrame กลับมาใช้ใหม่: แทนที่จะสร้างอ็อบเจ็กต์
VideoFrameใหม่สำหรับการคัดลอกแต่ละครั้ง ให้นำอ็อบเจ็กต์ที่มีอยู่กลับมาใช้ใหม่ทุกครั้งที่เป็นไปได้ ซึ่งจะช่วยลดภาระการจัดสรรหน่วยความจำ - ลดพื้นที่ที่คัดลอก: คัดลอกเฉพาะส่วนที่จำเป็นของเฟรมวิดีโอเท่านั้น หลีกเลี่ยงการคัดลอกพื้นที่ขนาดใหญ่โดยไม่จำเป็น เนื่องจากจะเพิ่มภาระในการคัดลอก
- ใช้รูปแบบที่เข้ากันได้: ตรวจสอบให้แน่ใจว่าอ็อบเจ็กต์
VideoFrameต้นทางและปลายทางมีรูปแบบที่เข้ากันได้เพื่อหลีกเลี่ยงการแปลงรูปแบบ หากการแปลงเป็นสิ่งที่หลีกเลี่ยงไม่ได้ ให้ดำเนินการแปลงอย่างชัดเจนและแคชผลลัพธ์ไว้ใช้ใหม่ - ใช้ประโยชน์จากการเร่งความเร็วด้วยฮาร์ดแวร์: ตรวจสอบให้แน่ใจว่าการเร่งความเร็วด้วยฮาร์ดแวร์เปิดใช้งานอยู่ในเบราว์เซอร์ของผู้ใช้
- ปรับปรุงการดำเนินการแบบอะซิงโครนัส: จัดการลักษณะการทำงานแบบอะซิงโครนัสของเมธอด
copyTo()อย่างเหมาะสมเพื่อหลีกเลี่ยงการบล็อกเธรดหลัก ใช้async/awaitหรือ Promises เพื่อจัดการการดำเนินการแบบอะซิงโครนัสอย่างมีประสิทธิภาพ - วิเคราะห์โปรไฟล์โค้ดของคุณ: ใช้เครื่องมือสำหรับนักพัฒนาในเบราว์เซอร์เพื่อวิเคราะห์โปรไฟล์โค้ดของคุณและระบุคอขวดด้านประสิทธิภาพ ให้ความสนใจเป็นพิเศษกับการใช้หน่วยความจำ การใช้งาน CPU และกิจกรรมของ GPU
- พิจารณาใช้ WebAssembly: สำหรับงานที่ต้องใช้การคำนวณสูง ควรพิจารณาใช้ WebAssembly เพื่อใช้อัลกอริธึมการประมวลผลภาพแบบกำหนดเองที่สามารถทำงานได้ใกล้เคียงกับความเร็วเนทีฟ
ข้อควรพิจารณาด้านความปลอดภัย
แม้ว่า WebCodecs จะมีความสามารถที่ทรงพลัง แต่สิ่งสำคัญคือต้องตระหนักถึงความเสี่ยงด้านความปลอดภัยที่อาจเกิดขึ้น:
- การรั่วไหลของข้อมูล: ตรวจสอบให้แน่ใจว่าคุณไม่ได้เปิดเผยข้อมูลที่ละเอียดอ่อนโดยไม่ได้ตั้งใจผ่านการคัดลอกส่วนของเฟรม ระมัดระวังเมื่อคัดลอกส่วนที่อาจมีข้อมูลที่สามารถระบุตัวบุคคลได้ (PII) หรือข้อมูลที่เป็นความลับอื่นๆ
- การแทรกโค้ดที่เป็นอันตราย: เมื่อประมวลผลวิดีโอจากแหล่งที่ไม่น่าเชื่อถือ ให้ระวังช่องโหว่การแทรกโค้ดที่อาจเกิดขึ้น ควรตรวจสอบและกรองข้อมูลที่ผู้ใช้ป้อนเข้ามาเพื่อป้องกันไม่ให้โค้ดที่เป็นอันตรายถูกฝังอยู่ในสตรีมวิดีโอ
- การโจมตีแบบปฏิเสธการให้บริการ (Denial-of-Service): ผู้ไม่หวังดีอาจใช้ช่องโหว่ในการใช้งาน WebCodecs เพื่อโจมตีแบบปฏิเสธการให้บริการ ควรรักษาเบราว์เซอร์และระบบปฏิบัติการของคุณให้ทันสมัยด้วยแพตช์ความปลอดภัยล่าสุดเพื่อลดความเสี่ยงเหล่านี้
- ปัญหาข้ามต้นทาง (Cross-Origin): โปรดระวังข้อจำกัดข้ามต้นทางเมื่อเข้าถึงสตรีมวิดีโอจากโดเมนที่แตกต่างกัน ตรวจสอบให้แน่ใจว่าได้กำหนดค่าเฮดเดอร์ CORS ที่จำเป็นเพื่ออนุญาตการเข้าถึงข้ามต้นทาง
ความเข้ากันได้กับเบราว์เซอร์
WebCodecs เป็น API ที่ค่อนข้างใหม่ และความเข้ากันได้กับเบราว์เซอร์อาจแตกต่างกันไป ตรวจสอบตารางความเข้ากันได้ของเบราว์เซอร์ล่าสุดเพื่อให้แน่ใจว่า API ได้รับการสนับสนุนในเบราว์เซอร์เป้าหมาย ณ ปลายปี 2024 เบราว์เซอร์หลักๆ เช่น Chrome, Firefox และ Safari มีระดับการสนับสนุนที่แตกต่างกัน ควรทดสอบโค้ดของคุณบนเบราว์เซอร์ต่างๆ เสมอเพื่อให้แน่ใจว่าการทำงานเป็นไปอย่างสอดคล้องกัน
บทสรุป
การคัดลอกส่วนของเฟรมวิดีโอด้วย WebCodecs เป็นคุณสมบัติที่ทรงพลังซึ่งช่วยให้สามารถทำซ้ำบางส่วนของเฟรมได้อย่างมีประสิทธิภาพ และเปิดโอกาสมากมายสำหรับการประมวลผลวิดีโอและการปรับปรุงประสิทธิภาพในเว็บแอปพลิเคชัน ด้วยการทำความเข้าใจความสามารถของเมธอด copyTo() และการพิจารณาถึงผลกระทบด้านประสิทธิภาพและความปลอดภัย นักพัฒนาสามารถใช้ประโยชน์จากคุณสมบัตินี้เพื่อสร้างประสบการณ์สื่อบนเว็บที่เป็นนวัตกรรมและมีประสิทธิภาพสูง ในขณะที่ WebCodecs พัฒนาขึ้นและได้รับการสนับสนุนจากเบราว์เซอร์อย่างกว้างขวางมากขึ้น มันจะกลายเป็นเครื่องมือที่จำเป็นสำหรับนักพัฒนาเว็บที่ทำงานกับวิดีโอและสื่อรูปแบบอื่นๆ อย่างไม่ต้องสงสัย การสำรวจกรณีการใช้งานและกลยุทธ์การปรับปรุงประสิทธิภาพอย่างต่อเนื่องจะมีความสำคัญอย่างยิ่งต่อการปลดล็อกศักยภาพสูงสุดของเทคโนโลยีนี้ ควรติดตามข่าวสารล่าสุดเกี่ยวกับการพัฒนา WebCodecs API และแนวปฏิบัติที่ดีที่สุดสำหรับการใช้งานในบริบทระดับโลกอยู่เสมอ