(เจฒเจ—เจญเจ—) เจฌเฉเจฐเจพเจŠเจœเจผเจฐ เจคเฉ‹เจ‚ เจฌเฉ‡เจ•เจพเจฐ เจตเฉˆเจฌเจ•เฉˆเจฎ เจธเจŸเฉเจฐเฉ€เจฎเจฟเฉฐเจ—เฅค เจฎเฉ€เจกเฉ€เจ† เจธเจŸเฉเจฐเฉ€เจฎ เจ…เจคเฉ‡ เจตเฉˆเจฌเจธเจพเจ•เจŸ

เจ‡เจธ เจฒเฉ‡เจ– เจตเจฟเฉฑเจš เจฎเฉˆเจ‚ เจคเฉ€เจœเฉ€-เจงเจฟเจฐ เจฆเฉ‡ เจฌเฉเจฐเจพเจŠเจœเจผเจฐ เจชเจฒเฉฑเจ—เจ‡เจจ เจœเจฟเจตเฉ‡เจ‚ เจ•เจฟ เจ…เจกเฉ‹เจฌ เจซเจฒเฉˆเจธเจผ เจชเจฒเฉ‡เจ…เจฐ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เฉ€เจคเฉ‡ เจฌเจฟเจจเจพเจ‚ เจตเฉˆเจฌเจธเจพเจ•เฉ‡เจŸ เจฐเจพเจนเฉ€เจ‚ เจตเฉ€เจกเฉ€เจ“ เจธเจŸเฉเจฐเฉ€เจฎ เจ•เจฐเจจ เจฆเฉ€เจ†เจ‚ เจ†เจชเจฃเฉ€เจ†เจ‚ เจ•เฉ‹เจธเจผเจฟเจธเจผเจพเจ‚ เจจเฉ‚เฉฐ เจธเจพเจ‚เจเจพ เจ•เจฐเจจเจพ เจšเจพเจนเฉเฉฐเจฆเจพ เจนเจพเจ‚เฅค เจ‡เจน เจชเจคเจพ เจ•เจฐเจจ เจฒเจˆ เจชเฉœเฉเจนเฉ‹ เจ•เจฟ เจ‡เจธเจฆเจพ เจ•เฉ€ เจจเจฟเจ•เจฒเจฟเจ†เฅค

เจ…เจกเฉ‹เจฌ เจซเจฒเฉˆเจธเจผ, เจชเจนเจฟเจฒเจพเจ‚ เจฎเฉˆเจ•เจฐเฉ‹เจฎเฉ€เจกเฉ€เจ† เจซเจฒเฉˆเจธเจผ, เจ‡เฉฑเจ• เจตเฉˆเฉฑเจฌ เจฌเฉเจฐเจพเจŠเจœเจผเจฐ เจตเจฟเฉฑเจš เจšเฉฑเจฒเจฃ เจตเจพเจฒเฉ€เจ†เจ‚ เจเจชเจฒเฉ€เจ•เฉ‡เจธเจผเจจเจพเจ‚ เจฌเจฃเจพเจ‰เจฃ เจฒเจˆ เจ‡เฉฑเจ• เจชเจฒเฉ‡เจŸเจซเจพเจฐเจฎ เจนเฉˆเฅค เจฎเฉ€เจกเฉ€เจ† เจธเจŸเฉเจฐเฉ€เจฎ API เจฆเฉ€ เจœเจพเจฃ-เจชเจ›เจพเจฃ เจคเฉ‹เจ‚ เจชเจนเจฟเจฒเจพเจ‚, เจ‡เจน เจ‡เฉฑเจ• เจตเฉˆเจฌเจ•เฉˆเจฎ เจคเฉ‹เจ‚ เจตเฉ€เจกเฉ€เจ“ เจ…เจคเฉ‡ เจตเฉŒเจ‡เจธ เจธเจŸเฉเจฐเฉ€เจฎ เจ•เจฐเจจ เจฆเฉ‡ เจจเจพเจฒ-เจจเจพเจฒ เจฌเฉเจฐเจพเจŠเจœเจผเจฐ เจตเจฟเฉฑเจš เจ•เจˆ เจคเจฐเฉเจนเจพเจ‚ เจฆเฉ€เจ†เจ‚ เจ•เจพเจจเจซเจฐเฉฐเจธเจพเจ‚ เจ…เจคเฉ‡ เจšเฉˆเจŸเจพเจ‚ เจฌเจฃเจพเจ‰เจฃ เจฒเจˆ เจ…เจฎเจฒเฉ€ เจคเฉŒเจฐ 'เจคเฉ‡ เจ‡เฉฑเจ•เฉ‹ เจ‡เฉฑเจ• เจชเจฒเฉ‡เจŸเจซเจพเจฐเจฎ เจธเฉ€เฅค เจฎเฉ€เจกเฉ€เจ† เจœเจพเจฃเจ•เจพเจฐเฉ€ เจชเฉเจฐเจธเจพเจฐเจฟเจค เจ•เจฐเจจ เจฒเจˆ เจชเฉเจฐเฉ‹เจŸเฉ‹เจ•เฉ‹เจฒ RTMP (เจฐเฉ€เจ…เจฒ เจŸเจพเจˆเจฎ เจฎเฉˆเจธเฉ‡เจœเจฟเฉฐเจ— เจชเฉเจฐเฉ‹เจŸเฉ‹เจ•เฉ‹เจฒ) เจ…เจธเจฒ เจตเจฟเฉฑเจš เจฒเฉฐเจฌเฉ‡ เจธเจฎเฉ‡เจ‚ เจฒเจˆ เจฌเฉฐเจฆ เจธเฉ€, เจœเจฟเจธเจฆเจพ เจฎเจคเจฒเจฌ เจธเฉ€: เจœเฉ‡เจ•เจฐ เจคเฉเจธเฉ€เจ‚ เจ†เจชเจฃเฉ€ เจธเจŸเฉเจฐเฉ€เจฎเจฟเฉฐเจ— เจธเฉ‡เจตเจพ เจจเฉ‚เฉฐ เจนเฉเจฒเจพเจฐเจพ เจฆเฉ‡เจฃเจพ เจšเจพเจนเฉเฉฐเจฆเฉ‡ เจนเฉ‹, เจคเจพเจ‚ เจ…เจกเฉ‹เจฌ เจคเฉ‹เจ‚ เจธเจพเจซเจŸเจตเฉ‡เจ…เจฐ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจจ เจฒเจˆ เจ•เจพเจซเจผเฉ€ เจฆเจฟเจ†เจฒเฉ‚ เจฌเจฃเฉ‹ - Adobe Media Server (AMS)เฅค

2012 เจตเจฟเฉฑเจš เจ•เฉเจ เจธเจฎเฉ‡เจ‚ เจฌเจพเจ…เจฆ, Adobe เจจเฉ‡ เจฒเฉ‹เจ•เจพเจ‚ เจจเฉ‚เฉฐ "เจ›เฉฑเจก เจฆเจฟเฉฑเจคเจพ เจ…เจคเฉ‡ เจ‡เจธเจจเฉ‚เฉฐ เจฌเจพเจนเจฐ เจ•เฉฑเจข เจฆเจฟเฉฑเจคเจพ"เฅค เจจเจฟเจฐเจงเจพเจฐเจจ RTMP เจชเฉเจฐเฉ‹เจŸเฉ‹เจ•เฉ‹เจฒ, เจœเจฟเจธ เจตเจฟเฉฑเจš เจคเจฐเฉเฉฑเจŸเฉ€เจ†เจ‚ เจธเจจ เจ…เจคเฉ‡ เจœเจผเจฐเฉ‚เจฐเฉ€ เจคเฉŒเจฐ 'เจคเฉ‡ เจ…เจงเฉ‚เจฐเจพ เจธเฉ€เฅค เจ‰เจธ เจธเจฎเฉ‡เจ‚ เจคเฉฑเจ•, เจกเจฟเจตเฉˆเจฒเจชเจฐเจพเจ‚ เจจเฉ‡ เจ‡เจธ เจชเฉเจฐเฉ‹เจŸเฉ‹เจ•เฉ‹เจฒ เจฆเฉ‡ เจ†เจชเจฃเฉ‡ เจ–เฉเจฆ เจฆเฉ‡ เจฒเจพเจ—เฉ‚ เจ•เจฐเจจเฉ‡ เจธเจผเฉเจฐเฉ‚ เจ•เจฐ เจฆเจฟเฉฑเจคเฉ‡, เจ…เจคเฉ‡ Wowza เจธเจฐเจตเจฐ เจชเฉเจฐเจ—เจŸ เจนเฉ‹เจ‡เจ†. 2011 เจตเจฟเฉฑเจš, Adobe เจจเฉ‡ RTMP-เจธเจฌเฉฐเจงเจค เจชเฉ‡เจŸเฉˆเจ‚เจŸเจพเจ‚ เจฆเฉ€ เจ—เฉˆเจฐ-เจ•เจพเจจเฉ‚เฉฐเจจเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจฒเจˆ Wowza เจฆเฉ‡ เจ–เจฟเจฒเจพเจซ เจ‡เฉฑเจ• เจฎเฉเจ•เฉฑเจฆเจฎเจพ เจฆเจพเจ‡เจฐ เจ•เฉ€เจคเจพ; 4 เจธเจพเจฒเจพเจ‚ เจฌเจพเจ…เจฆ, เจตเจฟเจตเจพเจฆ เจจเฉ‚เฉฐ เจธเฉเจฒเจเจพเจ‡เจ† เจ—เจฟเจ† เจธเฉ€เฅค

เจ…เจกเฉ‹เจฌ เจซเจฒเฉˆเจธเจผ เจชเจฒเฉ‡เจŸเจซเจพเจฐเจฎ 20 เจธเจพเจฒ เจคเฉ‹เจ‚ เจตเฉฑเจง เจชเฉเจฐเจพเจฃเจพ เจนเฉˆ, เจœเจฟเจธ เจฆเฉŒเจฐเจพเจจ เจ•เจˆ เจ—เฉฐเจญเฉ€เจฐ เจ•เจฎเจœเจผเฉ‹เจฐเฉ€เจ†เจ‚ เจ–เฉ‹เจœเฉ€เจ†เจ‚ เจ—เจˆเจ†เจ‚ เจนเจจ, เจธเจฎเจฐเจฅเจจ เจตเจพเจ…เจฆเจพ เจ•เฉ€เจคเจพ 2020 เจคเฉฑเจ• เจ–เจคเจฎ เจนเฉ‹เจฃ เจฒเจˆ, เจธเจŸเฉเจฐเฉ€เจฎเจฟเฉฐเจ— เจธเฉ‡เจตเจพ เจฒเจˆ เจ•เฉเจ เจตเจฟเจ•เจฒเจช เจ›เฉฑเจก เจ•เฉ‡เฅค

เจฎเฉ‡เจฐเฉ‡ เจชเฉเจฐเฉ‹เจœเฉˆเจ•เจŸ เจฒเจˆ, เจฎเฉˆเจ‚ เจคเฉเจฐเฉฐเจค เจฌเฉเจฐเจพเจŠเจœเจผเจฐ เจตเจฟเฉฑเจš เจซเจฒเฉˆเจธเจผ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจจเฉ‚เฉฐ เจชเฉ‚เจฐเฉ€ เจคเจฐเฉเจนเจพเจ‚ เจ›เฉฑเจกเจฃ เจฆเจพ เจซเฉˆเจธเจฒเจพ เจ•เฉ€เจคเจพ. เจฎเฉˆเจ‚ เจ‰เจชเจฐเฉ‹เจ•เจค เจฎเฉเฉฑเจ– เจ•เจพเจฐเจจ เจฆเจพ เจธเฉฐเจ•เฉ‡เจค เจฆเจฟเฉฑเจคเจพ เจนเฉˆ; เจซเจฒเฉˆเจธเจผ เจตเฉ€ เจฎเฉ‹เจฌเจพเจˆเจฒ เจชเจฒเฉ‡เจŸเจซเจพเจฐเจฎเจพเจ‚ 'เจคเฉ‡ เจฌเจฟเจฒเจ•เฉเจฒ เจตเฉ€ เจธเจฎเจฐเจฅเจฟเจค เจจเจนเฉ€เจ‚ เจนเฉˆ, เจ…เจคเฉ‡ เจฎเฉˆเจ‚ เจ…เจธเจฒ เจตเจฟเฉฑเจš เจตเจฟเฉฐเจกเฉ‹เจœเจผ (เจตเจพเจˆเจจ เจ‡เจฎเฉ‚เจฒเฉ‡เจŸเจฐ) 'เจคเฉ‡ เจตเจฟเจ•เจพเจธ เจฒเจˆ เจ…เจกเฉ‹เจฌ เจซเจฒเฉˆเจธเจผ เจจเฉ‚เฉฐ เจคเฉˆเจจเจพเจค เจจเจนเฉ€เจ‚ เจ•เจฐเจจเจพ เจšเจพเจนเฉเฉฐเจฆเจพ เจธเฉ€เฅค เจ‡เจธ เจฒเจˆ เจฎเฉˆเจ‚ JavaScript เจตเจฟเฉฑเจš เจ‡เฉฑเจ• เจ•เจฒเจพเจ‡เฉฐเจŸ เจฒเจฟเจ–เจฃ เจฒเจˆ เจคเจฟเจ†เจฐ เจนเจพเจ‚. เจ‡เจน เจธเจฟเจฐเจซ เจ‡เฉฑเจ• เจชเฉเจฐเฉ‹เจŸเฉ‹เจŸเจพเจˆเจช เจนเฉ‹เจตเฉ‡เจ—เจพ, เจ•เจฟเจ‰เจ‚เจ•เจฟ เจฌเจพเจ…เจฆ เจตเจฟเฉฑเจš เจฎเฉˆเจ‚ เจธเจฟเฉฑเจ–เจฟเจ† เจ•เจฟ เจธเจŸเฉเจฐเฉ€เจฎเจฟเฉฐเจ— เจจเฉ‚เฉฐ p2p เจฆเฉ‡ เจ…เจงเจพเจฐ เจคเฉ‡ เจฌเจนเฉเจค เจœเจผเจฟเจ†เจฆเจพ เจ•เฉเจธเจผเจฒเจคเจพ เจจเจพเจฒ เจ•เฉ€เจคเจพ เจœเจพ เจธเจ•เจฆเจพ เจนเฉˆ, เจธเจฟเจฐเจซ เจฎเฉ‡เจฐเฉ‡ เจฒเจˆ เจ‡เจน เจชเฉ€เจ…เจฐ - เจธเจฐเจตเจฐ - เจชเฉ€เจ…เจฐ เจนเฉ‹เจตเฉ‡เจ—เจพ, เจชเจฐ เจ‡เจธ เจคเฉ‹เจ‚ เจ‡เจฒเจพเจตเจพ เจนเฉ‹เจฐ เจ•เจฟเจธเฉ‡ เจนเฉ‹เจฐ เจธเจฎเฉ‡เจ‚, เจ•เจฟเจ‰เจ‚เจ•เจฟ เจ‡เจน เจ…เจœเฉ‡ เจคเจฟเจ†เจฐ เจจเจนเฉ€เจ‚ เจนเฉˆ.

เจธเจผเฉเจฐเฉ‚ เจ•เจฐเจจ เจฒเจˆ, เจธเจพเจจเฉ‚เฉฐ เจ…เจธเจฒ เจตเฉˆเจฌเจธเจพเจ•เฉ‡เจŸ เจธเจฐเจตเจฐ เจฆเฉ€ เจฒเฉ‹เฉœ เจนเฉˆเฅค เจฎเฉˆเจฒเฉ‹เจกเฉ€ เจ—เฉ‹ เจชเฉˆเจ•เฉ‡เจœ เจฆเฉ‡ เจ…เจงเจพเจฐ เจคเฉ‡ เจฎเฉˆเจ‚ เจธเจญ เจคเฉ‹เจ‚ เจธเจฐเจฒ เจฌเจฃเจพเจ‡เจ† เจนเฉˆ:

เจธเจฐเจตเจฐ เจ•เฉ‹เจก

package main

import (
	"errors"
	"github.com/go-chi/chi"
	"gopkg.in/olahol/melody.v1"
	"log"
	"net/http"
	"time"
)

func main() {
	r := chi.NewRouter()
	m := melody.New()

	m.Config.MaxMessageSize = 204800

	r.Get("/", func(w http.ResponseWriter, r *http.Request) {
		http.ServeFile(w, r, "public/index.html")
	})
	r.Get("/ws", func(w http.ResponseWriter, r *http.Request) {
		m.HandleRequest(w, r)
	})

         // ะ‘ั€ะพะดะบะฐัั‚ะธะผ ะฒะธะดะตะพ ะฟะพั‚ะพะบ 
	m.HandleMessageBinary(func(s *melody.Session, msg []byte) {
		m.BroadcastBinary(msg)
	})

	log.Println("Starting server...")

	http.ListenAndServe(":3000", r)
}

เจ•เจฒเจพเจ‡เฉฐเจŸ (เจธเจŸเฉเจฐเฉ€เจฎเจฟเฉฐเจ— เจธเจพเจˆเจก) 'เจคเฉ‡, เจคเฉเจนเจพเจจเฉ‚เฉฐ เจชเจนเจฟเจฒเจพเจ‚ เจ•เฉˆเจฎเจฐเฉ‡ เจคเฉฑเจ• เจชเจนเฉเฉฐเจš เจ•เจฐเจจ เจฆเฉ€ เจฒเฉ‹เฉœ เจนเฉˆเฅค เจฐเจพเจนเฉ€เจ‚ เจ•เฉ€เจคเจพ เจœเจพเจ‚เจฆเจพ เจนเฉˆ MediaStream API.

เจ…เจธเฉ€เจ‚ เจ•เฉˆเจฎเจฐเฉ‡/เจฎเจพเจˆเจ•เฉเจฐเฉ‹เจซเฉ‹เจจ เจคเฉฑเจ• เจชเจนเฉเฉฐเจš (เจ‡เจœเจพเจœเจผเจค) เจชเฉเจฐเจพเจชเจค เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚ เจฎเฉ€เจกเฉ€เจ† เจกเจฟเจตเจพเจˆเจธ API. เจ‡เจน API เจ‡เฉฑเจ• เจขเฉฐเจ— เจชเฉเจฐเจฆเจพเจจ เจ•เจฐเจฆเจพ เจนเฉˆ MediaDevices.getUserMedia(), เจœเฉ‹ เจชเฉŒเจชเจ…เฉฑเจช เจฆเจฟเจ–เจพเจ‰เจ‚เจฆเจพ เจนเฉˆเฅค เจ‡เฉฑเจ• เจตเจฟเฉฐเจกเฉ‹ เจœเฉ‹ เจ‰เจชเจญเฉ‹เจ—เจคเจพ เจคเฉ‹เจ‚ เจ•เฉˆเจฎเจฐเฉ‡ เจ…เจคเฉ‡/เจœเจพเจ‚ เจฎเจพเจˆเจ•เฉเจฐเฉ‹เจซเฉ‹เจจ เจคเฉฑเจ• เจชเจนเฉเฉฐเจš เจ•เจฐเจจ เจฆเฉ€ เจ‡เจœเจพเจœเจผเจค เจฎเฉฐเจ—เจฆเฉ€ เจนเฉˆเฅค เจฎเฉˆเจ‚ เจจเฉ‹เจŸ เจ•เจฐเจจเจพ เจšเจพเจนเจพเจ‚เจ—เจพ เจ•เจฟ เจฎเฉˆเจ‚ เจ—เฉ‚เจ—เจฒ เจ•เจฐเฉ‹เจฎ เจตเจฟเฉฑเจš เจธเจพเจฐเฉ‡ เจชเฉเจฐเจฏเฉ‹เจ— เจ•เฉ€เจคเฉ‡ เจนเจจ, เจชเจฐ เจฎเฉˆเจจเฉ‚เฉฐ เจฒเจ—เจฆเจพ เจนเฉˆ เจ•เจฟ เจซเจพเจ‡เจฐเจซเจพเจ•เจธ เจตเจฟเฉฑเจš เจธเจญ เจ•เฉเจ เจ‰เจธเฉ‡ เจคเจฐเฉเจนเจพเจ‚ เจ•เฉฐเจฎ เจ•เจฐเฉ‡เจ—เจพเฅค

เจ…เฉฑเจ—เฉ‡, getUserMedia() เจ‡เฉฑเจ• เจตเจพเจ…เจฆเจพ เจตเจพเจชเจธ เจ•เจฐเจฆเจพ เจนเฉˆ, เจœเจฟเจธ เจตเจฟเฉฑเจš เจ‡เจน เจ‡เฉฑเจ• เจฎเฉ€เจกเฉ€เจ†เจธเจŸเฉเจฐเฉ€เจฎ เจ†เจฌเจœเฉˆเจ•เจŸ เจชเจพเจธ เจ•เจฐเจฆเจพ เจนเฉˆ - เจตเฉ€เจกเฉ€เจ“-เจ†เจกเฉ€เจ“ เจกเฉ‡เจŸเจพ เจฆเฉ€ เจ‡เฉฑเจ• เจธเจŸเฉเจฐเฉ€เจฎเฅค เจ…เจธเฉ€เจ‚ เจ‡เจธ เจ†เจฌเจœเฉˆเจ•เจŸ เจจเฉ‚เฉฐ เจตเฉ€เจกเฉ€เจ“ เจเจฒเฉ€เจฎเฉˆเจ‚เจŸ เจฆเฉ€ src เจตเจฟเจธเจผเฉ‡เจธเจผเจคเจพ เจฒเจˆ เจจเจฟเจฐเจงเจพเจฐเจค เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚เฅค เจ•เฉ‹เจก:

เจชเฉเจฐเจธเจพเจฐเจฃ เจชเจพเจธเฉ‡

<style>
  #videoObjectHtml5ApiServer { width: 320px; height: 240px; background: #666; }
</style>
</head>
<body>
<!-- ะ—ะดะตััŒ ะฒ ัั‚ะพะผ "ะพะบะพัˆะตั‡ะบะต" ะบะปะธะตะฝั‚ ะฑัƒะดะตั‚ ะฒะธะดะตั‚ัŒ ัะตะฑั -->
<video autoplay id="videoObjectHtml5ApiServer"></video>

<script type="application/javascript">
  var
        video = document.getElementById('videoObjectHtml5ApiServer');

// ะตัะปะธ ะดะพัั‚ัƒะฟะตะฝ MediaDevices API, ะฟั‹ั‚ะฐะตะผัั ะฟะพะปัƒั‡ะธั‚ัŒ ะดะพัั‚ัƒะฟ ะบ ะบะฐะผะตั€ะต (ะผะพะถะฝะพ ะตั‰ะต ะธ ะบ ะผะธะบั€ะพั„ะพะฝัƒ)
// getUserMedia ะฒะตั€ะฝะตั‚ ะพะฑะตั‰ะฐะฝะธะต, ะฝะฐ ะบะพั‚ะพั€ะพะต ะฟะพะดะฟะธัั‹ะฒะฐะตะผัั ะธ ะฟะพะปัƒั‡ะตะฝะฝั‹ะน ะฒะธะดะตะพะฟะพั‚ะพะบ ะฒ ะบะพะปะฑะตะบะต ะฝะฐะฟั€ะฐะฒะปัะตะผ ะฒ video ะพะฑัŠะตะบั‚ ะฝะฐ ัั‚ั€ะฐะฝะธั†ะต

if (navigator.mediaDevices.getUserMedia) {
        navigator.mediaDevices.getUserMedia({video: true}).then(function (stream) {
          // ะฒะธะดะตะพ ะฟะพั‚ะพะบ ะฟั€ะธะฒัะทั‹ะฒะฐะตะผ ะบ video ั‚ะตะณัƒ, ั‡ั‚ะพะฑั‹ ะบะปะธะตะฝั‚ ะผะพะณ ะฒะธะดะตั‚ัŒ ัะตะฑั ะธ ะบะพะฝั‚ั€ะพะปะธั€ะพะฒะฐั‚ัŒ 
          video.srcObject = stream;
        });
}
</script>

เจธเจพเจ•เจŸเจพเจ‚ เจ‰เฉฑเจคเฉ‡ เจ‡เฉฑเจ• เจตเฉ€เจกเฉ€เจ“ เจธเจŸเฉเจฐเฉ€เจฎ เจจเฉ‚เฉฐ เจชเฉเจฐเจธเจพเจฐเจฟเจค เจ•เจฐเจจ เจฒเจˆ, เจคเฉเจนเจพเจจเฉ‚เฉฐ เจ‡เจธเจจเฉ‚เฉฐ เจ•เจฟเจคเฉ‡ เจเจจเจ•เฉ‹เจก เจ•เจฐเจจ, เจ‡เจธเจจเฉ‚เฉฐ เจฌเจซเจฐ เจ•เจฐเจจ, เจ…เจคเฉ‡ เจ‡เจธเจจเฉ‚เฉฐ เจนเจฟเฉฑเจธเจฟเจ†เจ‚ เจตเจฟเฉฑเจš เจชเฉเจฐเจธเจพเจฐเจฟเจค เจ•เจฐเจจ เจฆเฉ€ เจฒเฉ‹เฉœ เจนเฉˆเฅค เจ•เฉฑเจšเฉ€ เจตเฉ€เจกเฉ€เจ“ เจธเจŸเฉเจฐเฉ€เจฎ เจจเฉ‚เฉฐ เจตเฉˆเจฌเจธเจพเจ•เจŸเจพเจ‚ เจฐเจพเจนเฉ€เจ‚ เจชเฉเจฐเจธเจพเจฐเจฟเจค เจจเจนเฉ€เจ‚ เจ•เฉ€เจคเจพ เจœเจพ เจธเจ•เจฆเจพ เจนเฉˆเฅค เจ‡เจน เจ‰เจน เจฅเจพเจ‚ เจนเฉˆ เจœเจฟเฉฑเจฅเฉ‡ เจ‡เจน เจธเจพเจกเฉ€ เจธเจนเจพเจ‡เจคเจพ เจฒเจˆ เจ†เจ‰เจ‚เจฆเจพ เจนเฉˆ MediaRecorder API. เจ‡เจน API เจคเฉเจนเจพเจจเฉ‚เฉฐ เจธเจŸเฉเจฐเฉ€เจฎ เจจเฉ‚เฉฐ เจเจจเจ•เฉ‹เจก เจ•เจฐเจจ เจ…เจคเฉ‡ เจŸเฉเจ•เฉœเจฟเจ†เจ‚ เจตเจฟเฉฑเจš เจคเฉ‹เฉœเจจ เจฆเฉ€ เจ‡เจœเจพเจœเจผเจค เจฆเจฟเฉฐเจฆเจพ เจนเฉˆเฅค เจฎเฉˆเจ‚ เจจเฉˆเฉฑเจŸเจตเจฐเจ• 'เจคเฉ‡ เจ˜เฉฑเจŸ เจฌเจพเจˆเจŸ เจญเฉ‡เจœเจฃ เจฒเจˆ เจตเฉ€เจกเฉ€เจ“ เจธเจŸเฉเจฐเฉ€เจฎ เจจเฉ‚เฉฐ เจธเฉฐเจ•เฉเจšเจฟเจค เจ•เจฐเจจ เจฒเจˆ เจเจจเจ•เฉ‹เจกเจฟเฉฐเจ— เจ•เจฐเจฆเจพ เจนเจพเจ‚เฅค เจ‡เจธ เจจเฉ‚เฉฐ เจŸเฉเจ•เฉœเจฟเจ†เจ‚ เจตเจฟเฉฑเจš เจคเฉ‹เฉœ เจ•เฉ‡, เจคเฉเจธเฉ€เจ‚ เจนเจฐเฉ‡เจ• เจŸเฉเจ•เฉœเฉ‡ เจจเฉ‚เฉฐ เจ‡เฉฑเจ• เจตเฉˆเจฌเจธเจพเจ•เฉ‡เจŸ เจตเจฟเฉฑเจš เจญเฉ‡เจœ เจธเจ•เจฆเฉ‡ เจนเฉ‹เฅค เจ•เฉ‹เจก:

เจ…เจธเฉ€เจ‚ เจตเฉ€เจกเฉ€เจ“ เจธเจŸเฉเจฐเฉ€เจฎ เจจเฉ‚เฉฐ เจเจจเจ•เฉ‹เจก เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚, เจ‡เจธเจจเฉ‚เฉฐ เจนเจฟเฉฑเจธเจฟเจ†เจ‚ เจตเจฟเฉฑเจš เจตเฉฐเจกเจฆเฉ‡ เจนเจพเจ‚

<style>
  #videoObjectHtml5ApiServer { width: 320px; height: 240px; background: #666; }
</style>
</head>
<body>
<!-- ะ—ะดะตััŒ ะฒ ัั‚ะพะผ "ะพะบะพัˆะตั‡ะบะต" ะบะปะธะตะฝั‚ ะฑัƒะดะตั‚ ะฒะธะดะตั‚ัŒ ัะตะฑั -->
<video autoplay id="videoObjectHtml5ApiServer"></video>

<script type="application/javascript">
  var
        video = document.getElementById('videoObjectHtml5ApiServer');

// ะตัะปะธ ะดะพัั‚ัƒะฟะตะฝ MediaDevices API, ะฟั‹ั‚ะฐะตะผัั ะฟะพะปัƒั‡ะธั‚ัŒ ะดะพัั‚ัƒะฟ ะบ ะบะฐะผะตั€ะต (ะผะพะถะฝะพ ะตั‰ะต ะธ ะบ ะผะธะบั€ะพั„ะพะฝัƒ)
// getUserMedia ะฒะตั€ะฝะตั‚ ะพะฑะตั‰ะฐะฝะธะต, ะฝะฐ ะบะพั‚ะพั€ะพะต ะฟะพะดะฟะธัั‹ะฒะฐะตะผัั ะธ ะฟะพะปัƒั‡ะตะฝะฝั‹ะน ะฒะธะดะตะพะฟะพั‚ะพะบ ะฒ ะบะพะปะฑะตะบะต ะฝะฐะฟั€ะฐะฒะปัะตะผ ะฒ video ะพะฑัŠะตะบั‚ ะฝะฐ ัั‚ั€ะฐะฝะธั†ะต

if (navigator.mediaDevices.getUserMedia) {
        navigator.mediaDevices.getUserMedia({video: true}).then(function (stream) {
          // ะฒะธะดะตะพ ะฟะพั‚ะพะบ ะฟั€ะธะฒัะทั‹ะฒะฐะตะผ ะบ video ั‚ะตะณัƒ, ั‡ั‚ะพะฑั‹ ะบะปะธะตะฝั‚ ะผะพะณ ะฒะธะดะตั‚ัŒ ัะตะฑั ะธ ะบะพะฝั‚ั€ะพะปะธั€ะพะฒะฐั‚ัŒ 
          video.srcObject = s;
          var
            recorderOptions = {
                mimeType: 'video/webm; codecs=vp8' // ะฑัƒะดะตะผ ะบะพะดะธั€ะพะฒะฐั‚ัŒ ะฒะธะดะตะพะฟะพั‚ะพะบ ะฒ ั„ะพั€ะผะฐั‚ webm ะบะพะดะตะบะพะผ vp8
              },
              mediaRecorder = new MediaRecorder(s, recorderOptions ); // ะพะฑัŠะตะบั‚ MediaRecorder

               mediaRecorder.ondataavailable = function(e) {
                if (e.data && e.data.size > 0) {
                  // ะฟะพะปัƒั‡ะฐะตะผ ะบัƒัะพั‡ะตะบ ะฒะธะดะตะพะฟะพั‚ะพะบะฐ ะฒ e.data
                }
            }

            mediaRecorder.start(100); // ะดะตะปะธั‚ ะฟะพั‚ะพะบ ะฝะฐ ะบัƒัะพั‡ะบะธ ะฟะพ 100 ะผั ะบะฐะถะดั‹ะน

        });
}
</script>

เจ†เจ‰ เจนเฉเจฃ เจตเฉˆเจฌเจธเจพเจ•เฉ‡เจŸ เจฐเจพเจนเฉ€เจ‚ เจชเฉเจฐเจธเจพเจฐเจฃ เจœเฉ‹เฉœเฉ€เจเฅค เจนเฉˆเจฐเจพเจจเฉ€ เจฆเฉ€ เจ—เฉฑเจฒ เจนเฉˆ เจ•เจฟ เจ‡เจธ เจฒเจˆ เจคเฉเจนเจพเจจเฉ‚เฉฐ เจธเจฟเจฐเจซเจผ เจ‡เฉฑเจ• เจตเจธเจคเฉ‚ เจฆเฉ€ เจฒเฉ‹เฉœ เจนเฉˆ เจตเฉˆเจฌเจธเฉ‹เจ•เฉ‡เจŸ. เจ‡เจธ เจตเจฟเฉฑเจš เจญเฉ‡เจœเจฃ เจ…เจคเฉ‡ เจฌเฉฐเจฆ เจ•เจฐเจจ เจฆเฉ‡ เจฆเฉ‹ เจนเฉ€ เจคเจฐเฉ€เจ•เฉ‡ เจนเจจเฅค เจจเจพเจฎ เจ†เจชเจฃเฉ‡ เจฒเจˆ เจฌเฉ‹เจฒเจฆเฉ‡ เจนเจจ. เจ•เฉ‹เจก เจœเฉ‹เฉœเจฟเจ† เจ—เจฟเจ†:

เจ…เจธเฉ€เจ‚ เจตเฉ€เจกเฉ€เจ“ เจธเจŸเฉเจฐเฉ€เจฎ เจจเฉ‚เฉฐ เจธเจฐเจตเจฐ 'เจคเฉ‡ เจชเฉเจฐเจธเจพเจฐเจฟเจค เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚

<style>
  #videoObjectHtml5ApiServer { width: 320px; height: 240px; background: #666; }
</style>
</head>
<body>
<!-- ะ—ะดะตััŒ ะฒ ัั‚ะพะผ "ะพะบะพัˆะตั‡ะบะต" ะบะปะธะตะฝั‚ ะฑัƒะดะตั‚ ะฒะธะดะตั‚ัŒ ัะตะฑั -->
<video autoplay id="videoObjectHtml5ApiServer"></video>

<script type="application/javascript">
  var
        video = document.getElementById('videoObjectHtml5ApiServer');

// ะตัะปะธ ะดะพัั‚ัƒะฟะตะฝ MediaDevices API, ะฟั‹ั‚ะฐะตะผัั ะฟะพะปัƒั‡ะธั‚ัŒ ะดะพัั‚ัƒะฟ ะบ ะบะฐะผะตั€ะต (ะผะพะถะฝะพ ะตั‰ะต ะธ ะบ ะผะธะบั€ะพั„ะพะฝัƒ)
// getUserMedia ะฒะตั€ะฝะตั‚ ะพะฑะตั‰ะฐะฝะธะต, ะฝะฐ ะบะพั‚ะพั€ะพะต ะฟะพะดะฟะธัั‹ะฒะฐะตะผัั ะธ ะฟะพะปัƒั‡ะตะฝะฝั‹ะน ะฒะธะดะตะพะฟะพั‚ะพะบ ะฒ ะบะพะปะฑะตะบะต ะฝะฐะฟั€ะฐะฒะปัะตะผ ะฒ video ะพะฑัŠะตะบั‚ ะฝะฐ ัั‚ั€ะฐะฝะธั†ะต

if (navigator.mediaDevices.getUserMedia) {
        navigator.mediaDevices.getUserMedia({video: true}).then(function (stream) {
          // ะฒะธะดะตะพ ะฟะพั‚ะพะบ ะฟั€ะธะฒัะทั‹ะฒะฐะตะผ ะบ video ั‚ะตะณัƒ, ั‡ั‚ะพะฑั‹ ะบะปะธะตะฝั‚ ะผะพะณ ะฒะธะดะตั‚ัŒ ัะตะฑั ะธ ะบะพะฝั‚ั€ะพะปะธั€ะพะฒะฐั‚ัŒ 
          video.srcObject = s;
          var
            recorderOptions = {
                mimeType: 'video/webm; codecs=vp8' // ะฑัƒะดะตะผ ะบะพะดะธั€ะพะฒะฐั‚ัŒ ะฒะธะดะตะพะฟะพั‚ะพะบ ะฒ ั„ะพั€ะผะฐั‚ webm ะบะพะดะตะบะพะผ vp8
              },
              mediaRecorder = new MediaRecorder(s, recorderOptions ), // ะพะฑัŠะตะบั‚ MediaRecorder
              socket = new WebSocket('ws://127.0.0.1:3000/ws');

               mediaRecorder.ondataavailable = function(e) {
                if (e.data && e.data.size > 0) {
                  // ะฟะพะปัƒั‡ะฐะตะผ ะบัƒัะพั‡ะตะบ ะฒะธะดะตะพะฟะพั‚ะพะบะฐ ะฒ e.data
                 socket.send(e.data);
                }
            }

            mediaRecorder.start(100); // ะดะตะปะธั‚ ะฟะพั‚ะพะบ ะฝะฐ ะบัƒัะพั‡ะบะธ ะฟะพ 100 ะผั ะบะฐะถะดั‹ะน

        }).catch(function (err) { console.log(err); });
}
</script>

เจชเฉเจฐเจธเจพเจฐเจฃ เจชเฉฑเจ– เจคเจฟเจ†เจฐ เจนเฉˆ! เจนเฉเจฃ เจ†เจ‰ เจ‡เฉฑเจ• เจตเฉ€เจกเฉ€เจ“ เจธเจŸเฉเจฐเฉ€เจฎ เจชเฉเจฐเจพเจชเจค เจ•เจฐเจจ เจฆเฉ€ เจ•เฉ‹เจธเจผเจฟเจธเจผ เจ•เจฐเฉ€เจ เจ…เจคเฉ‡ เจ‡เจธเจจเฉ‚เฉฐ เจ•เจฒเจพเจ‡เฉฐเจŸ 'เจคเฉ‡ เจชเฉเจฐเจฆเจฐเจธเจผเจฟเจค เจ•เจฐเฉ€เจเฅค เจธเจพเจจเฉ‚เฉฐ เจ‡เจธ เจฒเจˆ เจ•เฉ€ เจšเจพเจนเฉ€เจฆเจพ เจนเฉˆ? เจชเจนเจฟเจฒเจพเจ‚, เจฌเฉ‡เจธเจผเจ•, เจธเจพเจ•เจŸ เจ•เฉเจจเฉˆเจ•เจธเจผเจจ. เจ…เจธเฉ€เจ‚ WebSocket เจ†เจฌเจœเฉˆเจ•เจŸ เจจเจพเจฒ เจ‡เฉฑเจ• "เจธเฉเจฃเจจ เจตเจพเจฒเฉ‡" เจจเฉ‚เฉฐ เจœเฉ‹เฉœเจฆเฉ‡ เจนเจพเจ‚ เจ…เจคเฉ‡ 'เจธเฉเจจเฉ‡เจนเจพ' เจ‡เจตเฉˆเจ‚เจŸ เจฒเจˆ เจ—เจพเจนเจ• เจฌเจฃเจฆเฉ‡ เจนเจพเจ‚เฅค เจฌเจพเจˆเจจเจฐเฉ€ เจกเฉ‡เจŸเจพ เจฆเจพ เจ‡เฉฑเจ• เจŸเฉเจ•เฉœเจพ เจชเฉเจฐเจพเจชเจค เจ•เจฐเจจ เจคเฉ‹เจ‚ เจฌเจพเจ…เจฆ, เจธเจพเจกเจพ เจธเจฐเจตเจฐ เจ‡เจธเจจเฉ‚เฉฐ เจ—เจพเจนเจ•เจพเจ‚, เจฏเจพเจจเฉ€ เจ—เจพเจนเจ•เจพเจ‚ เจจเฉ‚เฉฐ เจชเฉเจฐเจธเจพเจฐเจฟเจค เจ•เจฐเจฆเจพ เจนเฉˆเฅค เจ‡เจธ เจธเจฅเจฟเจคเฉ€ เจตเจฟเฉฑเจš, 'เจธเฉเจจเฉ‡เจนเจพ' เจ‡เจตเฉˆเจ‚เจŸ เจฆเฉ‡ "เจธเฉเจฃเจจ เจตเจพเจฒเฉ‡" เจจเจพเจฒ เจธเฉฐเจฌเฉฐเจงเจฟเจค เจ•เจพเจฒเจฌเฉˆเจ• เจซเฉฐเจ•เจธเจผเจจ เจ•เจฒเจพเจ‡เฉฐเจŸ 'เจคเฉ‡ เจธเจผเฉเจฐเฉ‚ เจนเฉ‹ เจœเจพเจ‚เจฆเจพ เจนเฉˆ; เจ†เจฌเจœเฉˆเจ•เจŸ เจจเฉ‚เฉฐ เจ–เฉเจฆ เจซเฉฐเจ•เจธเจผเจจ เจ†เจฐเจ—เฉ‚เจฎเฉˆเจ‚เจŸ เจตเจฟเฉฑเจš เจชเจพเจธ เจ•เฉ€เจคเจพ เจœเจพเจ‚เจฆเจพ เจนเฉˆ - vp8 เจฆเฉเจ†เจฐเจพ เจเจจเจ•เฉ‹เจก เจ•เฉ€เจคเฉ‡ เจตเฉ€เจกเฉ€เจ“ เจธเจŸเฉเจฐเฉ€เจฎ เจฆเจพ เจ‡เฉฑเจ• เจŸเฉเจ•เฉœเจพเฅค

เจ…เจธเฉ€เจ‚ เจตเฉ€เจกเฉ€เจ“ เจธเจŸเฉเจฐเฉ€เจฎ เจจเฉ‚เฉฐ เจธเจตเฉ€เจ•เจพเจฐ เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚

<style>
  #videoObjectHtml5ApiServer { width: 320px; height: 240px; background: #666; }
</style>
</head>
<body>
<!-- ะ—ะดะตััŒ ะฒ ัั‚ะพะผ "ะพะบะพัˆะตั‡ะบะต" ะบะปะธะตะฝั‚ ะฑัƒะดะตั‚ ะฒะธะดะตั‚ัŒ ั‚ะตะฑั -->
<video autoplay id="videoObjectHtml5ApiServer"></video>

<script type="application/javascript">
  var
        video = document.getElementById('videoObjectHtml5ApiServer'),
         socket = new WebSocket('ws://127.0.0.1:3000/ws'), 
         arrayOfBlobs = [];

         socket.addEventListener('message', function (event) {
                // "ะบะปะฐะดะตะผ" ะฟะพะปัƒั‡ะตะฝะฝั‹ะน ะบัƒัะพั‡ะตะบ ะฒ ะผะฐััะธะฒ 
                arrayOfBlobs.push(event.data);
                // ะทะดะตััŒ ะฑัƒะดะตะผ ั‡ะธั‚ะฐั‚ัŒ ะบัƒัะพั‡ะบะธ
                readChunk();
            });
</script>

เจฒเฉฐเจฌเฉ‡ เจธเจฎเฉ‡เจ‚ เจฒเจˆ เจฎเฉˆเจ‚ เจ‡เจน เจธเจฎเจเจฃ เจฆเฉ€ เจ•เฉ‹เจธเจผเจฟเจธเจผ เจ•เฉ€เจคเฉ€ เจ•เจฟ เจชเฉเจฐเจพเจชเจค เจ•เฉ€เจคเฉ‡ เจŸเฉเจ•เฉœเจฟเจ†เจ‚ เจจเฉ‚เฉฐ เจคเฉเจฐเฉฐเจค เจชเจฒเฉ‡เจฌเฉˆเจ• เจฒเจˆ เจตเฉ€เจกเฉ€เจ“ เจคเฉฑเจค เจจเฉ‚เฉฐ เจญเฉ‡เจœเจฃเจพ เจ…เจธเฉฐเจญเจต เจ•เจฟเจ‰เจ‚ เจนเฉˆ, เจชเจฐ เจ‡เจน เจชเจคเจพ เจšเจฒเจฟเจ† เจ•เจฟ เจ‡เจน เจจเจนเฉ€เจ‚ เจ•เฉ€เจคเจพ เจœเจพ เจธเจ•เจฆเจพ, เจฌเฉ‡เจธเจผเจ•, เจคเฉเจนเจพเจจเฉ‚เฉฐ เจชเจนเจฟเจฒเจพเจ‚ เจŸเฉเจ•เฉœเฉ‡ เจจเฉ‚เฉฐ เจ‡เฉฑเจ• เจตเจฟเจธเจผเฉ‡เจธเจผ เจฌเจซเจฐ เจตเจฟเฉฑเจš เจฌเฉฐเจจเฉเจนเจฃเจพ เจšเจพเจนเฉ€เจฆเจพ เจนเฉˆ. เจตเฉ€เจกเฉ€เจ“ เจคเฉฑเจค, เจ…เจคเฉ‡ เจ•เฉ‡เจตเจฒ เจคเจฆ เจนเฉ€ เจ‡เจน เจตเฉ€เจกเฉ€เจ“ เจธเจŸเฉเจฐเฉ€เจฎ เจจเฉ‚เฉฐ เจšเจฒเจพเจ‰เจฃเจพ เจธเจผเฉเจฐเฉ‚ เจ•เจฐเฉ‡เจ—เจพเฅค เจ‡เจธ เจฆเฉ‡ เจฒเจˆ เจคเฉเจนเจพเจจเฉ‚เฉฐ เจฒเฉ‹เฉœ เจนเฉ‹เจตเฉ‡เจ—เฉ€ เจฎเฉ€เจกเฉ€เจ† เจธเจฐเฉ‹เจค API ะธ FileReader API.

MediaSource เจฎเฉ€เจกเฉ€เจ† เจชเจฒเฉ‡เจฌเฉˆเจ• เจ†เจฌเจœเฉˆเจ•เจŸ เจ…เจคเฉ‡ เจ‡เจธ เจฎเฉ€เจกเฉ€เจ† เจธเจŸเฉเจฐเฉ€เจฎ เจฆเฉ‡ เจธเจฐเฉ‹เจค เจฆเฉ‡ เจตเจฟเจšเจ•เจพเจฐ เจ‡เฉฑเจ• เจ•เจฟเจธเจฎ เจฆเฉ‡ เจตเจฟเจšเฉ‹เจฒเฉ‡ เจตเจœเฉ‹เจ‚ เจ•เฉฐเจฎ เจ•เจฐเจฆเจพ เจนเฉˆเฅค MediaSource เจ†เจฌเจœเฉˆเจ•เจŸ เจตเจฟเฉฑเจš เจตเฉ€เจกเฉ€เจ“/เจ†เจกเฉ€เจ“ เจธเจŸเฉเจฐเฉ€เจฎ เจฆเฉ‡ เจธเจฐเฉ‹เจค เจฒเจˆ เจ‡เฉฑเจ• เจชเจฒเฉฑเจ— เจ•เจฐเจจ เจฏเฉ‹เจ— เจฌเจซเจฐ เจนเฉเฉฐเจฆเจพ เจนเฉˆเฅค เจ‡เฉฑเจ• เจตเจฟเจธเจผเฉ‡เจธเจผเจคเจพ เจ‡เจน เจนเฉˆ เจ•เจฟ เจฌเจซเจฐ เจธเจฟเจฐเจซ Uint8 เจกเจพเจŸเจพ เจฐเฉฑเจ– เจธเจ•เจฆเจพ เจนเฉˆ, เจ‡เจธเจฒเจˆ เจคเฉเจนเจพเจจเฉ‚เฉฐ เจ…เจœเจฟเจนเจพ เจฌเจซเจฐ เจฌเจฃเจพเจ‰เจฃ เจฒเจˆ เจ‡เฉฑเจ• FileReader เจฆเฉ€ เจฒเฉ‹เฉœ เจชเจตเฉ‡เจ—เฉ€เฅค เจ•เฉ‹เจก เจจเฉ‚เฉฐ เจฆเฉ‡เจ–เฉ‹ เจ…เจคเฉ‡ เจ‡เจน เจนเฉ‹เจฐ เจธเจชเฉฑเจธเจผเจŸ เจนเฉ‹ เจœเจพเจตเฉ‡เจ—เจพ:

เจตเฉ€เจกเฉ€เจ“ เจธเจŸเฉเจฐเฉ€เจฎ เจšเจฒเจพเจ‡เจ† เจœเจพ เจฐเจฟเจนเจพ เจนเฉˆ

<style>
  #videoObjectHtml5ApiServer { width: 320px; height: 240px; background: #666; }
</style>
</head>
<body>
<!-- ะ—ะดะตััŒ ะฒ ัั‚ะพะผ "ะพะบะพัˆะตั‡ะบะต" ะบะปะธะตะฝั‚ ะฑัƒะดะตั‚ ะฒะธะดะตั‚ัŒ ั‚ะตะฑั -->
<video autoplay id="videoObjectHtml5ApiServer"></video>

<script type="application/javascript">
  var
        video = document.getElementById('videoObjectHtml5ApiServer'),
         socket = new WebSocket('ws://127.0.0.1:3000/ws'),
        mediaSource = new MediaSource(), // ะพะฑัŠะตะบั‚ MediaSource
        vid2url = URL.createObjectURL(mediaSource), // ัะพะทะดะฐะตะผ ะพะฑัŠะตะบั‚ URL ะดะปั ัะฒัะทั‹ะฒะฐะฝะธั ะฒะธะดะตะพะฟะพั‚ะพะบะฐ ั ะฟั€ะพะธะณั€ั‹ะฒะฐั‚ะตะปะตะผ
        arrayOfBlobs = [],
        sourceBuffer = null; // ะฑัƒั„ะตั€, ะฟะพะบะฐ ะฝัƒะปัŒ-ะพะฑัŠะตะบั‚

         socket.addEventListener('message', function (event) {
                // "ะบะปะฐะดะตะผ" ะฟะพะปัƒั‡ะตะฝะฝั‹ะน ะบัƒัะพั‡ะตะบ ะฒ ะผะฐััะธะฒ 
                arrayOfBlobs.push(event.data);
                // ะทะดะตััŒ ะฑัƒะดะตะผ ั‡ะธั‚ะฐั‚ัŒ ะบัƒัะพั‡ะบะธ
                readChunk();
            });

         // ะบะฐะบ ั‚ะพะปัŒะบะพ MediaSource ะฑัƒะดะตั‚ ะพะฟะพะฒะตั‰ะตะฝ , ั‡ั‚ะพ ะธัั‚ะพั‡ะฝะธะบ ะณะพั‚ะพะฒ ะพั‚ะดะฐะฒะฐั‚ัŒ ะบัƒัะพั‡ะบะธ 
        // ะฒะธะดะตะพ/ะฐัƒะดะธะพ ะฟะพั‚ะพะบะฐ
        // ัะพะทะดะฐะตะผ ะฑัƒั„ะตั€ , ัะปะตะดัƒะตั‚ ะพะฑั€ะฐั‚ะธั‚ัŒ ะฒะฝะธะผะฐะฝะธะต, ั‡ั‚ะพ ะฑัƒั„ะตั€ ะดะพะปะถะตะฝ ะทะฝะฐั‚ัŒ ะฒ ะบะฐะบะพะผ ั„ะพั€ะผะฐั‚ะต 
        // ะบะฐะบะธะผ ะบะพะดะตะบะพะผ ะฑั‹ะป ะทะฐะบะพะดะธั€ะพะฒะฐะฝ ะฟะพั‚ะพะบ, ั‡ั‚ะพะฑั‹ ั‚ะตะผ ะถะต ัะฟะพัะพะฑะพะผ ะฟั€ะพั‡ะธั‚ะฐั‚ัŒ ะฒะธะดะตะพะฟะพั‚ะพะบ
         mediaSource.addEventListener('sourceopen', function() {
            var mediaSource = this;
            sourceBuffer = mediaSource.addSourceBuffer("video/webm; codecs="vp8"");
        });

      function readChunk() {
        var reader = new FileReader();
        reader.onload = function(e) { 
          // ะบะฐะบ ั‚ะพะปัŒะบะพ FileReader ะฑัƒะดะตั‚ ะณะพั‚ะพะฒ, ะธ ะทะฐะณั€ัƒะทะธั‚ ัะตะฑะต ะบัƒัะพั‡ะตะบ ะฒะธะดะตะพะฟะพั‚ะพะบะฐ
          // ะผั‹ "ะฟั€ะธั†ะตะฟะปัะตะผ" ะฟะตั€ะตะบะพะดะธั€ะพะฒะฐะฝะฝั‹ะน ะฒ Uint8Array (ะฑั‹ะป Blob) ะบัƒัะพั‡ะตะบ ะฒ ะฑัƒั„ะตั€, ัะฒัะทะฐะฝะฝั‹ะน
          // ั ะฟั€ะพะธะณั€ั‹ะฒะฐั‚ะตะปะตะผ, ะธ ะฟั€ะพะธะณั€ั‹ะฒะฐั‚ะตะปัŒ ะฝะฐั‡ะธะฝะฐะตั‚ ะฒะพัะฟั€ะพะธะทะฒะพะดะธั‚ัŒ ะฟะพะปัƒั‡ะตะฝะฝั‹ะน ะบัƒัะพั‡ะตะบ ะฒะธะดะตะพ/ะฐัƒะดะธะพ
          sourceBuffer.appendBuffer(new Uint8Array(e.target.result));

          reader.onload = null;
        }
        reader.readAsArrayBuffer(arrayOfBlobs.shift());
      }
</script>

เจธเจŸเฉเจฐเฉ€เจฎเจฟเฉฐเจ— เจธเฉ‡เจตเจพ เจฆเจพ เจชเฉเจฐเฉ‹เจŸเฉ‹เจŸเจพเจˆเจช เจคเจฟเจ†เจฐ เจนเฉˆเฅค เจฎเฉเฉฑเจ– เจจเฉเจ•เจธเจพเจจ เจ‡เจน เจนเฉˆ เจ•เจฟ เจตเฉ€เจกเฉ€เจ“ เจชเจฒเฉ‡เจฌเฉˆเจ• 100 ms เจฆเฉเจ†เจฐเจพ เจชเฉเจฐเจธเจพเจฐเจฃ เจตเจพเจฒเฉ‡ เจชเจพเจธเฉ‡ เจคเฉ‹เจ‚ เจชเจฟเฉฑเจ›เฉ‡ เจฐเจนเจฟ เจœเจพเจตเฉ‡เจ—เจพ; เจ…เจธเฉ€เจ‚ เจ‡เจธเจจเฉ‚เฉฐ เจธเจฐเจตเจฐ 'เจคเฉ‡ เจชเฉเจฐเจธเจพเจฐเจฟเจค เจ•เจฐเจจ เจคเฉ‹เจ‚ เจชเจนเจฟเจฒเจพเจ‚ เจตเฉ€เจกเฉ€เจ“ เจธเจŸเฉเจฐเฉ€เจฎ เจจเฉ‚เฉฐ เจตเฉฐเจกเจฃ เจตเฉ‡เจฒเฉ‡ เจ†เจชเจฃเฉ‡ เจ†เจช เจธเฉˆเฉฑเจŸ เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚เฅค เจ‡เจธ เจคเฉ‹เจ‚ เจ‡เจฒเจพเจตเจพ, เจœเจฆเฉ‹เจ‚ เจฎเฉˆเจ‚ เจ†เจชเจฃเฉ‡ เจฒเฉˆเจชเจŸเจพเจช 'เจคเฉ‡ เจœเจพเจ‚เจš เจ•เฉ€เจคเฉ€, เจธเฉฐเจšเจพเจฐ เจ•เจฐเจจ เจ…เจคเฉ‡ เจชเฉเจฐเจพเจชเจค เจ•เจฐเจจ เจตเจพเจฒเฉ‡ เจชเจพเจธเจฟเจ†เจ‚ เจฆเฉ‡ เจตเจฟเจšเจ•เจพเจฐ เจฆเฉ€ เจชเจ›เฉœเจพเจˆ เจนเฉŒเจฒเฉ€-เจนเฉŒเจฒเฉ€ เจ‡เจ•เฉฑเจ เฉ€ เจนเฉ‹ เจ—เจˆ, เจ‡เจน เจธเจชเฉฑเจธเจผเจŸ เจคเฉŒเจฐ 'เจคเฉ‡ เจฆเจฟเจ–เจพเจˆ เจฆเฉ‡ เจฐเจฟเจนเจพ เจธเฉ€เฅค เจฎเฉˆเจ‚ เจ‡เจธ เจจเฉเจ•เจธเจพเจจ เจจเฉ‚เฉฐ เจฆเฉ‚เจฐ เจ•เจฐเจจ เจฆเฉ‡ เจคเจฐเฉ€เจ•เฉ‡ เจฒเฉฑเจญเจฃเฉ‡ เจธเจผเฉเจฐเฉ‚ เจ•เจฐ เจฆเจฟเฉฑเจคเฉ‡, เจ…เจคเฉ‡... RTCPeerConnection API, เจœเฉ‹ เจคเฉเจนเจพเจจเฉ‚เฉฐ เจธเจŸเฉเจฐเฉ€เจฎ เจจเฉ‚เฉฐ เจŸเฉเจ•เฉœเจฟเจ†เจ‚ เจตเจฟเฉฑเจš เจตเฉฐเจกเจฃ เจตเจฐเจ—เฉ€เจ†เจ‚ เจšเจพเจฒเจพเจ‚ เจคเฉ‹เจ‚ เจฌเจฟเจจเจพเจ‚ เจตเฉ€เจกเฉ€เจ“ เจธเจŸเฉเจฐเฉ€เจฎ เจจเฉ‚เฉฐ เจชเฉเจฐเจธเจพเจฐเจฟเจค เจ•เจฐเจจ เจฆเฉ€ เจ‡เจœเจพเจœเจผเจค เจฆเจฟเฉฐเจฆเจพ เจนเฉˆเฅค เจ‡เจ•เฉฑเจ เจพ เจนเฉ‹เจฃ เจตเจพเจฒเจพ เจชเจ›เฉœ, เจฎเฉ‡เจฐเฉ‡ เจ–เจฟเจ†เจฒ เจตเจฟเฉฑเจš, เจ‡เจธ เจคเฉฑเจฅ เจฆเฉ‡ เจ•เจพเจฐเจจ เจนเฉˆ เจ•เจฟ เจฌเฉเจฐเจพเจŠเจœเจผเจฐ เจชเฉเจฐเจธเจพเจฐเจฃ เจคเฉ‹เจ‚ เจชเจนเจฟเจฒเจพเจ‚ เจนเจฐเฉ‡เจ• เจŸเฉเจ•เฉœเฉ‡ เจจเฉ‚เฉฐ เจตเฉˆเจฌเจฎ เจซเจพเจฐเจฎเฉˆเจŸ เจตเจฟเฉฑเจš เจฎเฉเฉœ-เจเจจเจ•เฉ‹เจก เจ•เจฐเจฆเจพ เจนเฉˆ. เจฎเฉˆเจ‚ เจนเฉ‹เจฐ เจ–เฉ‹เจฆเจพเจˆ เจจเจนเฉ€เจ‚ เจ•เฉ€เจคเฉ€, เจชเจฐ WebRTC เจฆเจพ เจ…เจงเจฟเจเจจ เจ•เจฐเจจเจพ เจธเจผเฉเจฐเฉ‚ เจ•เฉ€เจคเจพเฅค เจฎเฉˆเจจเฉ‚เฉฐ เจฒเฉฑเจ—เจฆเจพ เจนเฉˆ เจ•เจฟ เจœเฉ‡เจ•เจฐ เจฎเฉˆเจจเฉ‚เฉฐ เจ‡เจน เจ•เจฎเจฟเจŠเจจเจฟเจŸเฉ€ เจฒเจˆ เจฆเจฟเจฒเจšเจธเจช เจฒเฉฑเจ—เฉ‡ เจคเจพเจ‚ เจฎเฉˆเจ‚ เจ†เจชเจฃเฉ€ เจ–เฉ‹เจœ เจฆเฉ‡ เจจเจคเฉ€เจœเจฟเจ†เจ‚ เจฌเจพเจฐเฉ‡ เจ‡เฉฑเจ• เจตเฉฑเจ–เจฐเจพ เจฒเฉ‡เจ– เจฒเจฟเจ–เจพเจ‚เจ—เจพเฅค

เจธเจฐเฉ‹เจค: www.habr.com

เจ‡เฉฑเจ• เจŸเจฟเฉฑเจชเจฃเฉ€ เจœเฉ‹เฉœเฉ‹