(แƒ—แƒ˜แƒ—แƒฅแƒ›แƒ˜แƒก) แƒฃแƒกแƒแƒ แƒ’แƒ”แƒ‘แƒšแƒ แƒ•แƒ”แƒ‘แƒ™แƒแƒ›แƒ”แƒ แƒ˜แƒก แƒœแƒแƒ™แƒแƒ“แƒ˜ แƒ‘แƒ แƒแƒฃแƒ–แƒ”แƒ แƒ˜แƒ“แƒแƒœ. แƒ›แƒ”แƒ“แƒ˜แƒ แƒœแƒแƒ™แƒแƒ“แƒ˜ แƒ“แƒ แƒ•แƒ”แƒ‘แƒกแƒแƒ™แƒ”แƒขแƒ”แƒ‘แƒ˜

แƒแƒ› แƒกแƒขแƒแƒขแƒ˜แƒแƒจแƒ˜ แƒ›แƒกแƒฃแƒ แƒก แƒ’แƒแƒ’แƒ˜แƒ–แƒ˜แƒแƒ แƒแƒ— แƒฉแƒ”แƒ›แƒ˜ แƒ›แƒชแƒ“แƒ”แƒšแƒแƒ‘แƒ”แƒ‘แƒ˜ แƒ•แƒ˜แƒ“แƒ”แƒแƒก แƒกแƒขแƒ แƒ˜แƒ›แƒ˜แƒœแƒ’แƒ˜ แƒ•แƒ”แƒ‘แƒกแƒแƒ™แƒ”แƒขแƒ”แƒ‘แƒ˜แƒก แƒกแƒแƒจแƒฃแƒแƒšแƒ”แƒ‘แƒ˜แƒ— แƒ›แƒ”แƒกแƒแƒ›แƒ” แƒ›แƒฎแƒแƒ แƒ˜แƒก แƒ‘แƒ แƒแƒฃแƒ–แƒ”แƒ แƒ˜แƒก แƒ“แƒแƒœแƒแƒ›แƒแƒขแƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ แƒ”แƒจแƒ”, แƒ แƒแƒ’แƒแƒ แƒ˜แƒชแƒแƒ Adobe Flash Player. แƒฌแƒแƒ˜แƒ™แƒ˜แƒ—แƒฎแƒ”แƒ—, แƒ แƒแƒ› แƒ’แƒแƒ˜แƒ’แƒแƒ—, แƒ แƒ แƒ’แƒแƒ›แƒแƒ•แƒ˜แƒ“แƒ.

Adobe Flash, แƒแƒ“แƒ แƒ” Macromedia Flash, แƒแƒ แƒ˜แƒก แƒžแƒšแƒแƒขแƒคแƒแƒ แƒ›แƒ แƒแƒžแƒšแƒ˜แƒ™แƒแƒชแƒ˜แƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒกแƒแƒฅแƒ›แƒœแƒ”แƒšแƒแƒ“, แƒ แƒแƒ›แƒšแƒ”แƒ‘แƒ˜แƒช แƒ›แƒฃแƒจแƒแƒแƒ‘แƒ”แƒœ แƒ•แƒ”แƒ‘ แƒ‘แƒ แƒแƒฃแƒ–แƒ”แƒ แƒจแƒ˜. Media Stream API-แƒ˜แƒก แƒ“แƒแƒœแƒ”แƒ แƒ’แƒ•แƒแƒ›แƒ“แƒ” แƒ˜แƒก แƒžแƒ แƒแƒฅแƒขแƒ˜แƒ™แƒฃแƒšแƒแƒ“ แƒ”แƒ แƒ—แƒแƒ“แƒ”แƒ แƒ—แƒ˜ แƒžแƒšแƒแƒขแƒคแƒแƒ แƒ›แƒ แƒ˜แƒงแƒ แƒ•แƒ”แƒ‘แƒ™แƒแƒ›แƒ”แƒ แƒ˜แƒ“แƒแƒœ แƒ•แƒ˜แƒ“แƒ”แƒแƒกแƒ แƒ“แƒ แƒฎแƒ›แƒ˜แƒก แƒ’แƒแƒ“แƒแƒกแƒแƒชแƒ”แƒ›แƒแƒ“, แƒแƒกแƒ”แƒ•แƒ” แƒ‘แƒ แƒแƒฃแƒ–แƒ”แƒ แƒจแƒ˜ แƒกแƒฎแƒ•แƒแƒ“แƒแƒกแƒฎแƒ•แƒ แƒกแƒแƒฎแƒ˜แƒก แƒ™แƒแƒœแƒคแƒ”แƒ แƒ”แƒœแƒชแƒ˜แƒ”แƒ‘แƒ˜แƒกแƒ แƒ“แƒ แƒฉแƒแƒขแƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒกแƒแƒฅแƒ›แƒœแƒ”แƒšแƒแƒ“. แƒ›แƒ”แƒ“แƒ˜แƒ แƒ˜แƒœแƒคแƒแƒ แƒ›แƒแƒชแƒ˜แƒ˜แƒก แƒ’แƒแƒ“แƒแƒชแƒ”แƒ›แƒ˜แƒก แƒžแƒ แƒแƒขแƒแƒ™แƒแƒšแƒ˜ RTMP (Real Time Messaging Protocol) แƒคแƒแƒฅแƒขแƒแƒ‘แƒ แƒ˜แƒ•แƒแƒ“ แƒ“แƒ˜แƒ“แƒ˜ แƒฎแƒœแƒ˜แƒ— แƒ“แƒแƒ˜แƒฎแƒฃแƒ แƒ, แƒ แƒแƒช แƒœแƒ˜แƒจแƒœแƒแƒ•แƒก: แƒ—แƒฃ แƒ’แƒกแƒฃแƒ แƒ— แƒ—แƒฅแƒ•แƒ”แƒœแƒ˜ แƒœแƒแƒ™แƒแƒ“แƒ˜แƒก แƒกแƒ”แƒ แƒ•แƒ˜แƒกแƒ˜แƒก แƒ’แƒแƒซแƒšแƒ˜แƒ”แƒ แƒ”แƒ‘แƒ, แƒ˜แƒงแƒแƒ•แƒ˜แƒ— แƒกแƒแƒ™แƒ›แƒแƒ แƒ˜แƒกแƒแƒ“ แƒ™แƒ”แƒ—แƒ˜แƒšแƒ˜, แƒ’แƒแƒ›แƒแƒ˜แƒงแƒ”แƒœแƒแƒ— แƒ—แƒแƒ•แƒแƒ“ Adobe-แƒก แƒžแƒ แƒแƒ’แƒ แƒแƒ›แƒฃแƒšแƒ˜ แƒฃแƒ–แƒ แƒฃแƒœแƒ•แƒ”แƒšแƒงแƒแƒคแƒ - Adobe Media Server (AMS).

แƒ’แƒแƒ แƒ™แƒ•แƒ”แƒฃแƒšแƒ˜ แƒžแƒ”แƒ แƒ˜แƒแƒ“แƒ˜แƒก แƒจแƒ”แƒ›แƒ“แƒ”แƒ’, 2012 แƒฌแƒ”แƒšแƒก, Adobe-แƒ›แƒ โ€žแƒ“แƒแƒแƒขแƒแƒ•แƒ แƒ“แƒ แƒ’แƒแƒแƒคแƒฃแƒ แƒ—แƒฎแƒโ€œ แƒกแƒแƒ–แƒแƒ’แƒแƒ“แƒแƒ”แƒ‘แƒแƒก. แƒกแƒžแƒ”แƒชแƒ˜แƒคแƒ˜แƒ™แƒแƒชแƒ˜แƒ RTMP แƒžแƒ แƒแƒขแƒแƒ™แƒแƒšแƒ˜, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒจแƒ”แƒ˜แƒชแƒแƒ•แƒ“แƒ แƒจแƒ”แƒชแƒ“แƒแƒ›แƒ”แƒ‘แƒก แƒ“แƒ แƒแƒ แƒกแƒ”แƒ‘แƒ˜แƒ—แƒแƒ“ แƒแƒ แƒแƒกแƒ แƒฃแƒšแƒ˜ แƒ˜แƒงแƒ. แƒ˜แƒ› แƒ“แƒ แƒแƒ˜แƒกแƒ—แƒ•แƒ˜แƒก, แƒ“แƒ”แƒ•แƒ”แƒšแƒแƒžแƒ”แƒ แƒ”แƒ‘แƒ›แƒ แƒ“แƒแƒ˜แƒฌแƒงแƒ”แƒก แƒแƒ› แƒžแƒ แƒแƒขแƒแƒ™แƒแƒšแƒ˜แƒก แƒกแƒแƒ™แƒฃแƒ—แƒแƒ แƒ˜ แƒ’แƒแƒœแƒฎแƒแƒ แƒชแƒ˜แƒ”แƒšแƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ™แƒ”แƒ—แƒ”แƒ‘แƒ แƒ“แƒ แƒ’แƒแƒ›แƒแƒฉแƒœแƒ“แƒ Wowza แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜. 2011 แƒฌแƒ”แƒšแƒก Adobe-แƒ› แƒจแƒ”แƒ˜แƒขแƒแƒœแƒ แƒกแƒแƒ แƒฉแƒ”แƒšแƒ˜ Wowza-แƒก แƒฌแƒ˜แƒœแƒแƒแƒฆแƒ›แƒ“แƒ”แƒ’ RTMP-แƒ—แƒแƒœ แƒ“แƒแƒ™แƒแƒ•แƒจแƒ˜แƒ แƒ”แƒ‘แƒฃแƒšแƒ˜ แƒžแƒแƒขแƒ”แƒœแƒขแƒ”แƒ‘แƒ˜แƒก แƒฃแƒ™แƒแƒœแƒแƒœแƒ แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ›แƒ; 4 แƒฌแƒšแƒ˜แƒก แƒจแƒ”แƒ›แƒ“แƒ”แƒ’ แƒ™แƒแƒœแƒคแƒšแƒ˜แƒฅแƒขแƒ˜ แƒ›แƒแƒ’แƒ•แƒแƒ แƒ“แƒ แƒ›แƒจแƒ•แƒ˜แƒ“แƒแƒ‘แƒ˜แƒแƒœแƒ˜ แƒ’แƒ–แƒ˜แƒ—.

Adobe Flash แƒžแƒšแƒแƒขแƒคแƒแƒ แƒ›แƒ 20 แƒฌแƒ”แƒšแƒ–แƒ” แƒ›แƒ”แƒขแƒ˜ แƒฎแƒœแƒ˜แƒกแƒแƒ, แƒแƒ› แƒ“แƒ แƒแƒ˜แƒก แƒ’แƒแƒœแƒ›แƒแƒ•แƒšแƒแƒ‘แƒแƒจแƒ˜ แƒแƒฆแƒ›แƒแƒฉแƒ”แƒœแƒ˜แƒšแƒ˜แƒ แƒ›แƒ แƒแƒ•แƒแƒšแƒ˜ แƒ™แƒ แƒ˜แƒขแƒ˜แƒ™แƒฃแƒšแƒ˜ แƒ“แƒแƒฃแƒชแƒ•แƒ”แƒšแƒแƒ‘แƒ, แƒ›แƒฎแƒแƒ แƒ“แƒแƒญแƒ”แƒ แƒ แƒ“แƒแƒฐแƒžแƒ˜แƒ แƒ“แƒ แƒ“แƒแƒกแƒ แƒฃแƒšแƒ“แƒ”แƒ‘แƒ 2020 แƒฌแƒšแƒ˜แƒกแƒ—แƒ•แƒ˜แƒก, แƒ แƒ˜แƒก แƒ’แƒแƒ›แƒแƒช แƒกแƒขแƒ แƒ˜แƒ›แƒ˜แƒœแƒ’แƒ˜แƒก แƒกแƒ”แƒ แƒ•แƒ˜แƒกแƒ˜แƒกแƒ—แƒ•แƒ˜แƒก แƒ แƒแƒ›แƒ“แƒ”แƒœแƒ˜แƒ›แƒ” แƒแƒšแƒขแƒ”แƒ แƒœแƒแƒขแƒ˜แƒ•แƒ แƒ แƒฉแƒ”แƒ‘แƒ.

แƒฉแƒ”แƒ›แƒ˜ แƒžแƒ แƒแƒ”แƒฅแƒขแƒ˜แƒกแƒ—แƒ•แƒ˜แƒก, แƒ›แƒ” แƒ›แƒแƒจแƒ˜แƒœแƒ•แƒ” แƒ’แƒแƒ“แƒแƒ•แƒฌแƒงแƒ•แƒ˜แƒขแƒ” แƒ›แƒ—แƒšแƒ˜แƒแƒœแƒแƒ“ แƒ›แƒ˜แƒ›แƒ”แƒขแƒแƒ•แƒ”แƒ‘แƒ˜แƒœแƒ Flash-แƒ˜แƒก แƒ’แƒแƒ›แƒแƒงแƒ”แƒœแƒ”แƒ‘แƒ แƒ‘แƒ แƒแƒฃแƒ–แƒ”แƒ แƒจแƒ˜. แƒ›แƒ” แƒ–แƒ”แƒ›แƒแƒ— แƒแƒฆแƒ•แƒœแƒ˜แƒจแƒœแƒ” แƒ›แƒ—แƒแƒ•แƒแƒ แƒ˜ แƒ›แƒ˜แƒ–แƒ”แƒ–แƒ˜; Flash แƒแƒกแƒ”แƒ•แƒ” แƒกแƒแƒ”แƒ แƒ—แƒแƒ“ แƒแƒ  แƒแƒ แƒ˜แƒก แƒ›แƒฎแƒแƒ แƒ“แƒแƒญแƒ”แƒ แƒ˜แƒšแƒ˜ แƒ›แƒแƒ‘แƒ˜แƒšแƒฃแƒ  แƒžแƒšแƒแƒขแƒคแƒแƒ แƒ›แƒ”แƒ‘แƒ–แƒ” แƒ“แƒ แƒ›แƒ” แƒœแƒแƒ›แƒ“แƒ•แƒ˜แƒšแƒแƒ“ แƒแƒ  แƒ›แƒ˜แƒœแƒ“แƒแƒ“แƒ Adobe Flash-แƒ˜แƒก แƒ’แƒแƒœแƒ—แƒแƒ•แƒกแƒ”แƒ‘แƒ Windows-แƒ–แƒ” (แƒฆแƒ•แƒ˜แƒœแƒ˜แƒก แƒ”แƒ›แƒฃแƒšแƒแƒขแƒแƒ แƒ˜) แƒ’แƒแƒœแƒ•แƒ˜แƒ—แƒแƒ แƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก. แƒแƒ›แƒ˜แƒขแƒแƒ› แƒ“แƒแƒ•แƒ˜แƒฌแƒงแƒ” แƒ™แƒšแƒ˜แƒ”แƒœแƒขแƒ˜แƒก แƒ“แƒแƒฌแƒ”แƒ แƒ JavaScript-แƒจแƒ˜. แƒ”แƒก แƒ˜แƒฅแƒœแƒ”แƒ‘แƒ แƒ›แƒฎแƒแƒšแƒแƒ“ แƒžแƒ แƒแƒขแƒแƒขแƒ˜แƒžแƒ˜, แƒ แƒแƒ“แƒ’แƒแƒœ แƒ›แƒแƒ’แƒ•แƒ˜แƒแƒœแƒ”แƒ‘แƒ˜แƒ— แƒ’แƒแƒ•แƒ˜แƒ’แƒ”, แƒ แƒแƒ› แƒกแƒขแƒ แƒ˜แƒ›แƒ˜แƒœแƒ’แƒ˜แƒก แƒ’แƒแƒ™แƒ”แƒ—แƒ”แƒ‘แƒ แƒ‘แƒ”แƒ•แƒ แƒแƒ“ แƒฃแƒคแƒ แƒ แƒ”แƒคแƒ”แƒฅแƒขแƒฃแƒ แƒแƒ“ แƒจแƒ”แƒ˜แƒซแƒšแƒ”แƒ‘แƒ p2p-แƒ–แƒ” แƒ“แƒแƒงแƒ แƒ“แƒœแƒแƒ‘แƒ˜แƒ—, แƒ›แƒฎแƒแƒšแƒแƒ“ แƒฉแƒ”แƒ›แƒ—แƒ•แƒ˜แƒก แƒ”แƒก แƒ˜แƒฅแƒœแƒ”แƒ‘แƒ peer - server - peers, แƒ›แƒแƒ’แƒ แƒแƒ› แƒฃแƒคแƒ แƒ แƒแƒ›แƒ˜แƒก แƒจแƒ”แƒกแƒแƒฎแƒ”แƒ‘ แƒกแƒฎแƒ•แƒ แƒ“แƒ แƒแƒก, แƒ แƒแƒ“แƒ’แƒแƒœ แƒ˜แƒก แƒฏแƒ”แƒ  แƒแƒ  แƒแƒ แƒ˜แƒก แƒ›แƒ–แƒแƒ“.

แƒ“แƒแƒกแƒแƒฌแƒงแƒ”แƒ‘แƒแƒ“, แƒฉแƒ•แƒ”แƒœ แƒ’แƒ•แƒญแƒ˜แƒ แƒ“แƒ”แƒ‘แƒ แƒ แƒ”แƒแƒšแƒฃแƒ แƒ˜ websockets แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜. แƒ›แƒ” แƒจแƒ”แƒ•แƒฅแƒ›แƒ”แƒœแƒ˜ แƒฃแƒ›แƒแƒ แƒขแƒ˜แƒ•แƒ”แƒกแƒ˜ แƒ›แƒ”แƒšแƒแƒ“แƒ˜แƒ go แƒžแƒแƒ™แƒ”แƒขแƒ˜แƒก แƒกแƒแƒคแƒฃแƒซแƒ•แƒ”แƒšแƒ–แƒ”:

แƒกแƒ”แƒ แƒ•แƒ”แƒ แƒ˜แƒก แƒ™แƒแƒ“แƒ˜

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(), แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒแƒฉแƒ•แƒ”แƒœแƒ”แƒ‘แƒก แƒแƒ›แƒแƒ›แƒฎแƒขแƒแƒ  แƒคแƒแƒœแƒฏแƒแƒ แƒแƒก. แƒคแƒแƒœแƒฏแƒแƒ แƒ, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒกแƒ—แƒฎแƒแƒ•แƒก แƒ›แƒแƒ›แƒฎแƒ›แƒแƒ แƒ”แƒ‘แƒ”แƒšแƒก แƒ™แƒแƒ›แƒ”แƒ แƒแƒ–แƒ” แƒ“แƒ/แƒแƒœ แƒ›แƒ˜แƒ™แƒ แƒแƒคแƒแƒœแƒ–แƒ” แƒฌแƒ•แƒ“แƒแƒ›แƒ˜แƒก แƒœแƒ”แƒ‘แƒแƒ แƒ—แƒ•แƒแƒก. แƒ›แƒ˜แƒœแƒ“แƒ แƒแƒฆแƒ•แƒœแƒ˜แƒจแƒœแƒ, แƒ แƒแƒ› แƒ›แƒ” แƒฉแƒแƒ•แƒแƒขแƒแƒ แƒ” แƒงแƒ•แƒ”แƒšแƒ แƒ”แƒฅแƒกแƒžแƒ”แƒ แƒ˜แƒ›แƒ”แƒœแƒขแƒ˜ Google Chrome-แƒจแƒ˜, แƒ›แƒแƒ’แƒ แƒแƒ› แƒ•แƒคแƒ˜แƒฅแƒ แƒแƒ‘, แƒงแƒ•แƒ”แƒšแƒแƒคแƒ”แƒ แƒ˜ แƒ˜แƒ’แƒ˜แƒ•แƒ” แƒ˜แƒ›แƒฃแƒจแƒแƒ•แƒ”แƒ‘แƒก Firefox-แƒจแƒ˜.

แƒจแƒ”แƒ›แƒ“แƒ”แƒ’แƒ˜, getUserMedia() แƒแƒ‘แƒ แƒฃแƒœแƒ”แƒ‘แƒก Promise-แƒก, แƒ แƒแƒ›แƒ”แƒšแƒกแƒแƒช แƒ’แƒแƒ“แƒแƒกแƒชแƒ”แƒ›แƒก MediaStream แƒแƒ‘แƒ˜แƒ”แƒฅแƒขแƒก - แƒ•แƒ˜แƒ“แƒ”แƒ-แƒแƒฃแƒ“แƒ˜แƒ แƒ›แƒแƒœแƒแƒชแƒ”แƒ›แƒ”แƒ‘แƒ˜แƒก แƒœแƒแƒ™แƒแƒ“แƒก. แƒฉแƒ•แƒ”แƒœ แƒแƒ› แƒแƒ‘แƒ˜แƒ”แƒฅแƒขแƒก แƒ•แƒแƒœแƒ˜แƒญแƒ”แƒ‘แƒ— แƒ•แƒ˜แƒ“แƒ”แƒ แƒ”แƒšแƒ”แƒ›แƒ”แƒœแƒขแƒ˜แƒก 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>

แƒ“แƒ˜แƒ“แƒ˜ แƒฎแƒœแƒ˜แƒก แƒ’แƒแƒœแƒ›แƒแƒ•แƒšแƒแƒ‘แƒแƒจแƒ˜ แƒ•แƒชแƒ“แƒ˜แƒšแƒแƒ‘แƒ“แƒ˜ แƒ’แƒแƒ›แƒ”แƒ’แƒ, แƒ แƒแƒขแƒแƒ› แƒแƒ แƒ˜แƒก แƒจแƒ”แƒฃแƒซแƒšแƒ”แƒ‘แƒ”แƒšแƒ˜แƒ แƒ›แƒ˜แƒฆแƒ”แƒ‘แƒฃแƒšแƒ˜ แƒœแƒแƒฌแƒ˜แƒšแƒ”แƒ‘แƒ˜แƒก แƒ“แƒแƒฃแƒงแƒแƒœแƒ”แƒ‘แƒšแƒ˜แƒ• แƒ’แƒแƒ’แƒ–แƒแƒ•แƒœแƒ แƒ•แƒ˜แƒ“แƒ”แƒ แƒ”แƒšแƒ”แƒ›แƒ”แƒœแƒขแƒ–แƒ” แƒ“แƒแƒกแƒแƒ™แƒ แƒแƒ•แƒแƒ“, แƒ›แƒแƒ’แƒ แƒแƒ› แƒแƒฆแƒ›แƒแƒฉแƒœแƒ“แƒ, แƒ แƒแƒ› แƒแƒ›แƒ˜แƒก แƒ’แƒแƒ™แƒ”แƒ—แƒ”แƒ‘แƒ แƒจแƒ”แƒฃแƒซแƒšแƒ”แƒ‘แƒ”แƒšแƒ˜แƒ, แƒ แƒ แƒ—แƒฅแƒ›แƒ แƒฃแƒœแƒ“แƒ, แƒฏแƒ”แƒ  แƒฃแƒœแƒ“แƒ แƒฉแƒแƒกแƒ•แƒแƒ— แƒœแƒแƒญแƒ”แƒ แƒ˜ แƒกแƒžแƒ”แƒชแƒ˜แƒแƒšแƒฃแƒ  แƒ‘แƒฃแƒคแƒ”แƒ แƒจแƒ˜, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒจแƒ”แƒ™แƒ แƒฃแƒšแƒ˜แƒ แƒ•แƒ˜แƒ“แƒ”แƒ แƒ”แƒšแƒ”แƒ›แƒ”แƒœแƒขแƒก แƒ“แƒ แƒ›แƒฎแƒแƒšแƒแƒ“ แƒแƒ›แƒ˜แƒก แƒจแƒ”แƒ›แƒ“แƒ”แƒ’ แƒ“แƒแƒ˜แƒฌแƒงแƒ”แƒ‘แƒก แƒ•แƒ˜แƒ“แƒ”แƒ แƒœแƒแƒ™แƒแƒ“แƒ˜แƒก แƒ“แƒแƒ™แƒ•แƒ แƒแƒก. แƒแƒ›แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก แƒ“แƒแƒ’แƒญแƒ˜แƒ แƒ“แƒ”แƒ‘แƒแƒ— MediaSource 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, แƒ แƒแƒ›แƒ”แƒšแƒ˜แƒช แƒกแƒแƒจแƒฃแƒแƒšแƒ”แƒ‘แƒแƒก แƒ’แƒแƒซแƒšแƒ”แƒ•แƒ— แƒ’แƒแƒ“แƒแƒ˜แƒขแƒแƒœแƒแƒ— แƒ•แƒ˜แƒ“แƒ”แƒ แƒœแƒแƒ™แƒแƒ“แƒ˜ แƒ˜แƒกแƒ”แƒ—แƒ˜ แƒฎแƒ แƒ˜แƒ™แƒ”แƒ‘แƒ˜แƒก แƒ’แƒแƒ แƒ”แƒจแƒ”, แƒ แƒแƒ’แƒแƒ แƒ˜แƒชแƒแƒ แƒœแƒแƒ™แƒแƒ“แƒ˜แƒก แƒœแƒแƒฌแƒ˜แƒšแƒ”แƒ‘แƒแƒ“ แƒ“แƒแƒงแƒแƒคแƒ. แƒ“แƒแƒ’แƒ แƒแƒ•แƒ˜แƒšแƒ˜ แƒฉแƒแƒ›แƒแƒ แƒฉแƒ”แƒœแƒ, แƒ•แƒคแƒ˜แƒฅแƒ แƒแƒ‘, แƒ’แƒแƒœแƒžแƒ˜แƒ แƒแƒ‘แƒ”แƒ‘แƒฃแƒšแƒ˜แƒ แƒ˜แƒ›แƒ˜แƒ—, แƒ แƒแƒ› แƒ‘แƒ แƒแƒฃแƒ–แƒ”แƒ แƒ˜ แƒ’แƒแƒ“แƒแƒชแƒ”แƒ›แƒแƒ›แƒ“แƒ” แƒฎแƒ”แƒšแƒแƒฎแƒšแƒ แƒแƒ™แƒแƒžแƒ˜แƒ แƒ”แƒ‘แƒก แƒ—แƒ˜แƒ—แƒแƒ”แƒฃแƒš แƒœแƒแƒฌแƒ˜แƒšแƒก webm แƒคแƒแƒ แƒ›แƒแƒขแƒจแƒ˜. แƒ›แƒ” แƒแƒฆแƒแƒ  แƒ’แƒแƒ•แƒ—แƒฎแƒแƒ แƒ”, แƒ›แƒแƒ’แƒ แƒแƒ› แƒ“แƒแƒ•แƒ˜แƒฌแƒงแƒ” WebRTC-แƒ˜แƒก แƒจแƒ”แƒกแƒฌแƒแƒ•แƒšแƒ. แƒ•แƒคแƒ˜แƒฅแƒ แƒแƒ‘, แƒชแƒแƒšแƒ™แƒ” แƒกแƒขแƒแƒขแƒ˜แƒแƒก แƒ“แƒแƒ•แƒฌแƒ”แƒ  แƒฉแƒ”แƒ›แƒ˜ แƒ™แƒ•แƒšแƒ”แƒ•แƒ˜แƒก แƒจแƒ”แƒ“แƒ”แƒ’แƒ”แƒ‘แƒ˜แƒก แƒจแƒ”แƒกแƒแƒฎแƒ”แƒ‘, แƒ—แƒฃ แƒ˜แƒก แƒกแƒแƒ–แƒแƒ’แƒแƒ“แƒแƒ”แƒ‘แƒ˜แƒกแƒ—แƒ•แƒ˜แƒก แƒกแƒแƒ˜แƒœแƒขแƒ”แƒ แƒ”แƒกแƒ แƒ˜แƒฅแƒœแƒ”แƒ‘แƒ.

แƒฌแƒงแƒแƒ แƒ: www.habr.com

แƒแƒฎแƒแƒšแƒ˜ แƒ™แƒแƒ›แƒ”แƒœแƒขแƒแƒ แƒ˜แƒก แƒ“แƒแƒ›แƒแƒขแƒ”แƒ‘แƒ