á€áá±á¬ááºážáá«ážááœáẠAdobe Flash Player áá²á·ááá¯á·áá±á¬ ááŒááºáááá±á¬ááºáᬠááááºá¡ááºáá»á¬ážááᯠá¡áá¯á¶ážáááŒá¯áá² websocket áá»á¬ážááŸáá
áºááá·áº áá®áá®ááá¯ááŒáá·áºááŸá¯ááẠááŒáá¯ážáááºážááŸá¯áá»á¬ážááᯠáá»áŸáá±ááá¯áá«áááºá á¡á²áá«á áá¬ááŒá
áºáá¬áá²ááá¯áá¬ááᯠáááºáááºááŒáá·áºááá¯ááºáá«á
Adobe Flash ááẠááááºá Macromedia Flash ááẠáááºááá±á¬ááºáá¬áá
áºáá¯ááœáẠáá¯ááºáá±á¬ááºááá·áº á¡ááá®áá±ážááŸááºážáá»á¬áž áááºáá®ážáááºá¡ááœáẠááááºáá±á¬ááºážáá
áºáá¯ááŒá
áºáááºá Media Stream API ááᯠááááºáááºááŒááºážáááŒá¯áá®á áááºážááẠáááºáááºááá¬á០áá®áá®ááá¯ááŸáá·áº á¡áá¶ááᯠááá¯ááºááá¯ááºááŒáá·áºááŸá¯ááẠáá
áºáá¯áááºážáá±á¬ááááºáá±á¬ááºážááŒá
áºááŒá®áž ááá±á¬ááºáá¬ááœáẠááœááºáááá·áºáá»á¬ážááŸáá·áº áá»ááºáááºá¡áá»áá¯ážáá»áá¯ážááᯠáááºáá®ážáááºá¡ááœáẠáááºááœá±á·áá»áá«áááºá áá®áá®áá¬á¡áá»ááºá¡áááºáá»á¬áž áá±ážááá¯á·ááŒááºážá¡ááœáẠáááá¯ááá¯áá±á¬ RTMP (Real Time Messaging Protocol) ááẠá¡áá»áááºá¡áá±á¬áºááŒá¬á¡á±á¬áẠááááºáá¬ážááŒá®áž ááá¯ááá¯áááºááŸá¬- áááºá streaming áááºáá±á¬ááºááŸá¯ááᯠááŒáŸáá·áºáááºááá¯áá«á Adobe ááá¯ááºááá¯ááºá០áá±á¬á·ááºáá²ááºááᯠá¡áá¯á¶ážááŒá¯ááẠááŒááºáá¬áá« - Adobe Media Server (AMS)á
2012 ááœáẠá¡áá»áááºá¡áá±á¬áºááŒá¬ááŒá®ážáá±á¬ááºá Adobe ááẠá¡áá»á¬ážáá°ááŸá¬ âá
áœáá·áºáá
áºá áá¶ááœá±ážááœá±ážâ áá²á·áááºá
Adobe Flash ááááºáá±á¬ááºážááẠááŸá
áºáá±á«ááºáž 20 áá»á±á¬áº áááºáááºážááŸáááŒá®ááŒá
áºááŒá®áž á¡ááá¯áá«áá¬áá¡ááœááºáž á¡áá±ážááŒá®ážáá±á¬ á¡á¬ážáááºážáá»ááºáá»á¬ážá
áœá¬ááᯠááŸá¬ááœá±ááœá±á·ááŸááá²á·ááŒá±á¬ááºážá
áá»áœááºá¯ááºáááá±á¬áá»ááºá¡ááœááºá áá»áœááºá¯ááºááẠááá±á¬ááºáá¬ááœáẠFlash á¡áá¯á¶ážááŒá¯ááŸá¯ááᯠáá¯á¶ážáá áœáá·áºááœáŸááºááẠáá¯á¶ážááŒááºááá¯ááºáááºá á¡áááºáá±á¬áºááŒáá« á¡áááá¡ááŒá±á¬ááºážáááºážááᯠáá»áœááºá¯ááºááœáŸááºááŒáá²á·áááºá Flash ááᯠááá¯ááá¯ááºážááááºáá±á¬ááºážáá»á¬ážááœáẠáá¯á¶ážá áá¶á·ááá¯ážááá±ážáá¬ážááá·áºá¡ááŒáẠWindows (ááá¯áẠemulator) ááœáẠááœá¶á·ááŒáá¯ážááá¯ážáááºááŸá¯á¡ááœáẠAdobe Flash ááᯠá¡ááŸááºáááẠá¡áá¯á¶ážáááŒá¯ááá¯áá²á·áá«á áá«ááŒá±á¬áá·áº JavaScript ááŸá¬ client áá áºáá¯áá±ážááá¯á· á áááºáá°ážáá¬ážáá«áááºá áááºážááẠp2p ááá¯á¡ááŒá±áá¶á streaming ááá¯ááá¯ááá¯áááá±á¬ááºá áœá¬áá¯ááºáá±á¬ááºááá¯ááºáááºááá¯áá±á¬ááºááá¯ááºážááœááºáá»áœááºá¯ááºá¡ááœááºááŸá±á·ááŒá±ážáá¯á¶á á¶áá áºáá¯áá¬ááŒá áºáááá·áºáááºá áá»áœááºá¯ááºá¡ááœááºáá¬áááºážááẠpeer - server - peers ááŒá áºáááá·áºáááºá ááá¯á·áá±á¬áºáááºážáááºá¡áááºááá·áºáááŒá áºáá±ážáá±á¬ááŒá±á¬áá·áºáá±á¬ááºáááºá¡áá»áááºáá»á¬ážááœááºááá¯ááá¯áá¯ááºáá±á¬ááºááá¯ááºáááºá
á áááºáááºá áá»áœááºá¯ááºááá¯á·ááẠá¡ááŸááºáááẠwebsockets áá¬áᬠááá¯á¡ááºáá«áááºá melody go package ááᯠá¡ááŒá±áá¶ááŒá®áž á¡ááá¯ážááŸááºážáá¯á¶ážáá áºáá¯ááᯠáá¯ááºáá¬ážáá«áááº
áá¬áá¬áá¯ááº
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)
}
áááá¯ááºážááá·áº (ááá¯ááºááá¯ááºáá¯ááºááœáŸáá·áºááá·áºáááºááœááº) áááºááá¬ááᯠáŠážá
áœá¬á¡áá¯á¶ážááŒá¯ááẠááá¯á¡ááºáááºá áá®ááá±áááá·áº áá¯ááºáá±á¬ááºáá«áááºá
áá»áœááºá¯ááºááá¯á·ááẠáááºááá¬/ááá¯ááºáááá¯áá¯ááºážááŸáááá·áº (ááœáá·áºááŒá¯áá»ááº) ááᯠáááŸááá«áááºá
ááá¯á·áá±á¬áẠgetUserMedia() ááẠ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>
áá®áá®ááá¯á
á®ážááŒá±á¬ááºážáá»á¬ážááᯠsocket áá»á¬ážáá±á«áºááœááºáá¯ááºááœáŸáá·áºáááºá áááºááẠáááºážááᯠáá
áºáá±áá¬áá¬ááœáẠáá¯ááºáá¯ááºáááºá ááŒá¬ážáá¶ááŒá®áž á¡ááá¯ááºážá¡ááá¯áẠáá¯ááºááœáŸáá·áºááẠááá¯á¡ááºáááºá áá®áá®ááá¯á¡ááŒááºážá
á®ážááŒá±á¬ááºážááᯠwebsocket áá»á¬ážááŸáá
áºááá·áº áááá¯á·ááá¯ááºáá«á á€áá±áá¬ááẠáá»áœááºá¯ááºááá¯á·á á¡áá°á¡áá®ááᯠáá±ážá
áœááºážááá¯ááºáá±áááºá
áá®áá®ááá¯á á®ážááŒá±á¬ááºážááᯠáá¯ááºáá¶áá«ááºáááºááŒá®áž á¡ááá¯ááºážááá¯ááºážááœá²áááºá
<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>
ááᯠwebsocket áá»á¬ážááŸáá
áºááá·áº áá¯ááºááœáŸáá·áºááŸá¯ááᯠááá·áºááá¯ááºááŒáá«á
áá¯á·á á¡á¶á·ááŒá
áá¬áá±á¬ááºážáá¬á áá®á¡áá¬á¡ááœáẠáááºááá¯á¡ááºáá²á·á¡áá¬áá
áºáá¯áá«áá²á
áá»áœááºá¯ááºááá¯á·ááẠáá®áá®ááá¯á á®ážááŒá±á¬ááºážááᯠáá¬áá¬ááá¯á· ááá¯á·áá«áááºá
<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>
áá¯ááºááœáŸáá·áºááá·áºáááºááœáẠá¡áááºááá·áºááŒá áºáá«ááŒá®á á¡áᯠáá®áá®ááá¯á á®ážááŒá±á¬ááºážááᯠáááºáá¶ááŒá®áž áááá¯ááºážááá·áºáá±á«áºááŸá¬ ááŒáááá¯á· ááŒáá¯ážá á¬ážááŒáá·áºáá¡á±á¬ááºá á€á¡ááœáẠáá»áœááºá¯ááºááá¯á· áá¬ááá¯á¡ááºááááºážá ááááŠážá áœá¬, áá¯ááºáá«áááº, socket áá»áááºáááºááŸá¯á áá»áœááºá¯ááºááá¯á·ááẠ"áá¬ážáá±á¬ááºáá°" ááᯠWebSocket á¡áá¬ááá¹áá¯ááœáẠáá°ážááœá²ááŒá®áž 'ááááºážá áá¬áž' ááŒá áºáááºááá¯á· á á¬áááºážááœááºážáá«á binary data áá áºááá¯ááºážááᯠáááºáá¶áááŸáááŒá®ážáá±á¬ááºá áá»áœááºá¯ááºááá¯á·ááá¬áá¬ááẠáááºážááᯠá á¬áááºážááœááºážáá°áá»á¬ážá ááá¯ááá¯áááºááŸá¬ áá±á¬ááºáááºáá»á¬ážáᶠáá¯ááºááœáŸáá·áºáááºá á€ááá á¹á ááœááºá 'ááááºážá áá¬áž' ááŒá áºáááºá "áá¬ážáááºáá°" ááŸáá·áºáááºá ááºáá±á¬ ááŒááºáá±á«áºááŒááºážáá¯ááºáá±á¬ááºáá»ááºááᯠclient ááœáẠá¡á áá»áá¯ážááá¯ááºáááºá á¡áá¬ááá¹áá¯ááá¯ááºááá¯ááºá function argument ááá¯á· áá±á¬ááºááœá¬ážááẠ- 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 ááẠáá®áá®áá¬ááœáá·áºááŒááºážá¡áá¬ááá¹áá¯ááŸáá·áº á€áá®áá®áá¬á á®ážááŒá±á¬ááºážááááºážááŒá áºá¡ááŒá¬áž ááŒá¬ážáá¶áá áºáá»áá¯ážá¡ááŒá Ạáá¯ááºáá±á¬ááºáááºá 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 áá±á¬ááºáá»áá»ááºáá±áááºááŒá
áºááŒá®ážá áááºážááᯠáá¬áá¬ááá¯á·áááá¯á·áá® áá®áá®ááá¯á
á®ážááŒá±á¬ááºážááᯠááá¯ááºážááœá²ááá·áºá¡áá« áááºážááᯠáá»áœááºá¯ááºááá¯á·ááá¯ááºááá¯áẠáááºááŸááºáá±ážáá¬ážáááºá ááá¯á·á¡ááŒááºá áá»áœááºá¯ááºááááºááºáá±á¬á·ááá¯á
á
áºáá±ážáá±á¬á¡áá«á áá¯ááºááœáŸáá·áºááŒááºážááŸáá·áºáááºáá¶ááŒááºážááŸá
áºáááºááŒá¬ážááœááºááŸá±ážááœá±ážááŸá¯áááŒááºážááŒááºážá
á¯áá±á¬ááºážáá¬áááºááá¯ááŸááºážáááºážá
áœá¬ááŒááºááááºá áá®á¡á¬ážáááºážáá»ááºááᯠáá»á±á¬áºááœáŸá¬ážááá¯á· áááºážáááºážááœá± ááŸá¬ááŒáá·áºáá±á¬á·... ááœá±á·ááœá¬ážáááºá
source: www.habr.com