เคยอยากดูตัวอย่างเส้นทางปั่นจักรยานก่อนที่จะปั่นไหม? เราสร้างระบบอัตโนมัติที่สร้างวิดีโอ flyover สวยงามสำหรับทุกเส้นทาง Party Onbici ให้นักปั่นได้ดูตัวอย่างแบบภาพยนตร์ว่าจะเจออะไรในการเดินทาง

ความท้าทาย

เมื่อจัดหรือเข้าร่วมกิจกรรมปั่นจักรยาน การเข้าใจเส้นทางเป็นสิ่งสำคัญ แผนที่แบบคงที่มีประโยชน์ แต่ไม่สามารถถ่ายทอดประสบการณ์การปั่นเส้นทางจริงได้ เราต้องการให้ผู้ใช้มีวิธี “บินผ่าน” เส้นทางเสมือนจริงก่อนตัดสินใจเข้าร่วม

โซลูชันของเรา: Headless Video Rendering

เราสร้างบริการ Node.js ที่รัน headless Chrome browser โดยใช้ Puppeteer แสดงผลเส้นทางบนแผนที่ MapLibre GL แบบโต้ตอบ และจับเฟรมขณะที่กล้องเสมือนบินไปตามเส้นทาง นี่คือวิธีการทำงาน:

1. การ Interpolate เส้นทาง

เส้นทางปั่นจักรยานอาจมีพิกัดนับพันจุด เพื่อสร้างวิดีโอที่ลื่นไหลที่ 30 FPS เป็นเวลา 15 วินาที เราต้องการ 450 เฟรมพอดี เราใช้การ interpolate ตามระยะทางเพื่อสุ่มตัวอย่างเส้นทางอย่างสม่ำเสมอ:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
// คำนวณระยะทางสะสมโดยใช้สูตร Haversine
const distances = [0];
for (let i = 1; i < coordinates.length; i++) {
  const dist = haversineDistance(coordinates[i-1], coordinates[i]);
  totalDistance += dist;
  distances.push(totalDistance);
}

// สุ่มตัวอย่างที่ totalFrames จุดพอดี
for (let frame = 0; frame < totalFrames; frame++) {
  const targetDist = (frame / (totalFrames - 1)) * totalDistance;
  // Interpolate ตำแหน่งที่ระยะทางนี้...
}

2. Animation กล้องด้วย Bearing ที่ลื่นไหล

การชี้กล้องไปในทิศทางการเดินทางเฉยๆ จะสร้างการเคลื่อนไหวกระตุกบนเส้นทางคดเคี้ยว เราทำให้ bearing ของกล้องลื่นไหลโดยใช้ค่าเฉลี่ยเคลื่อนที่ 12 เฟรม พร้อมการจัดการพิเศษสำหรับการข้าม 360°/0°:

1
2
3
4
5
6
7
// ใช้ส่วนประกอบ sin/cos สำหรับการหาค่าเฉลี่ยแบบวงกลม
for (let j = i - smoothWindow; j <= i + smoothWindow; j++) {
  const rad = rawBearings[j] * Math.PI / 180;
  sinSum += Math.sin(rad);
  cosSum += Math.cos(rad);
}
const avgBearing = Math.atan2(sinSum/count, cosSum/count) * 180 / Math.PI;

3. MapLibre GL Rendering

เส้นทางถูกแสดงผลบน base layer สวยงามของ Stadia Maps พร้อมกับ:

  • เส้นเส้นทางที่ไฮไลต์พร้อมขอบสีขาวเพื่อความชัดเจน
  • ตัวบ่งชี้ตำแหน่งกล้องแบบ animation
  • เครื่องหมายจุดเริ่มต้น (สีเขียว) และจุดสิ้นสุด (สีแดง)
  • อาคาร 3D แบบ extrusion เสริมสำหรับพื้นที่ในเมือง

4. การจับเฟรมและการเข้ารหัสวิดีโอ

Puppeteer จับแต่ละเฟรมเป็นภาพหน้าจอ PNG จากนั้นเราใช้ ffmpeg เพื่อเข้ารหัสเป็นวิดีโอ WebM ด้วย codec VP9:

1
2
3
ffmpeg -framerate 30 -i frame_%05d.png \
  -c:v libvpx-vp9 -crf 20 -b:v 0 \
  route.webm

สถาปัตยกรรมทางเทคนิค

1
Django App → Celery Task → Node.js Renderer → S3 Storage
  1. Django เรียกการสร้างวิดีโอ เมื่อ party ถูกสร้างหรืออัปเดต
  2. Celery จัดคิวงาน สำหรับการประมวลผลแบบ async
  3. Node.js renderer รัน Puppeteer กับ MapLibre GL
  4. ffmpeg เข้ารหัส เฟรมที่จับได้
  5. วิดีโอถูกอัปโหลด ไปยัง S3 และบันทึก party ถูกอัปเดต

ข้อพิจารณาด้านประสิทธิภาพ

ความละเอียดระยะเวลาเวลา Renderขนาดไฟล์
1280x72015s60-90s2-4 MB
1920x108015s90-120s4-8 MB

สำหรับ production เราใช้ Docker containers กับ software rendering (SwiftShader) เพื่อหลีกเลี่ยงการพึ่งพา GPU:

1
2
--use-angle=swiftshader
--enable-unsafe-swiftshader

ฟีเจอร์ที่เราเพิ่ม

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

การรวม Django

จากโค้ดแอปพลิเคชัน การสร้างวิดีโอง่ายมาก:

1
2
party = Party.objects.get(uid="...")
party.generate_video(width=1080, height=1080, duration=10)

URL วิดีโอจะถูกอัปเดตโดยอัตโนมัติเมื่อ rendering เสร็จสิ้น:

1
2
3
4
5
{% if party.video_url %}
<video controls>
  <source src="{{ party.video_full_url }}" type="video/webm">
</video>
{% endif %}

อะไรต่อไป

เรากำลังสำรวจการปรับปรุงหลายอย่าง:

  • ตัวอย่างแบบเรียลไทม์ - rendering สดขณะที่ผู้ใช้วาดเส้นทาง
  • มุมกล้องหลายมุม - มุมมองด้านข้าง ภาพมุมสูง
  • overlay สภาพอากาศ - แสดงสภาพอากาศที่คาดการณ์ตลอดเส้นทาง
  • โปรไฟล์ความสูง - แสดงภาพการปีนและลงเนินในวิดีโอ

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


อยากลองไหม? สร้าง party แล้ววิดีโอเส้นทางของคุณจะถูกสร้างโดยอัตโนมัติ!