پدې مقاله کې زه غواړم د دریمې ډلې براوزر پلگ انونو لکه اډوب فلش پلیر کارولو پرته د ویب ساکټونو له لارې د ویډیو جریان کولو هڅې شریک کړم. د دې موندلو لپاره ولولئ چې څه یې راغلي.
Adobe Flash، پخوا د Macromedia Flash، د غوښتنلیکونو جوړولو لپاره یو پلیټ فارم دی چې په ویب براوزر کې چلیږي. د میډیا سټریم API معرفي کولو دمخه ، دا په عملی ډول د ویب کیم څخه د ویډیو او غږ خپرولو لپاره یوازینی پلیټ فارم و ، په بیله بیا په براوزر کې د مختلف ډول کنفرانسونو او چیټونو رامینځته کولو لپاره. د میډیا معلوماتو لیږدولو پروتوکول RTMP (ریښتیني وخت پیغام رسولو پروتوکول) واقعیا د اوږدې مودې لپاره تړل شوی و ، پدې معنی: که تاسو غواړئ خپل سټیمینګ خدمت ته وده ورکړئ ، نو د اډوب پخپله سافټویر کارولو لپاره مهربان اوسئ - Adobe میډیا سرور (AMS).
په 2012 کې یو څه وخت وروسته، Adobe خلکو ته "له لاسه ورکړه او هغه یې توی کړه".
د اډوب فلش پلیټ فارم له 20 کلونو څخه ډیر زوړ دی ، پدې وخت کې ډیری جدي زیانونه موندل شوي ، ملاتړ
زما د پروژې لپاره، ما سمدلاسه پریکړه وکړه چې په براوزر کې د فلش کارول په بشپړه توګه پریږدي. ما پورته اصلي دلیل ته اشاره وکړه؛ فلش هم په ګرځنده پلیټ فارمونو کې هیڅ ملاتړ نه کوي ، او زه واقعیا نه غواړم په وینډوز (وین ایمولیټر) کې د پراختیا لپاره اډوب فلش ځای په ځای کړم. نو ما په جاواسکریپټ کې د پیرودونکي لیکلو لپاره پیل وکړ. دا به یوازې یو پروټوټایپ وي ، ځکه چې وروسته ما پوهیدلي چې سټرینګ د 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)
}
په پیرودونکي (سټریمینګ اړخ) کې ، تاسو لومړی اړتیا لرئ کیمرې ته لاسرسی ومومئ. دا له لارې ترسره کیږي
موږ کیمرې / مایکروفون ته لاسرسی (اجازه) ترلاسه کوو
بیا، 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>
په ساکټونو کې د ویډیو جریان خپرولو لپاره، تاسو اړتیا لرئ چې دا په کوم ځای کې کوډ کړئ، بفر یې کړئ، او په برخو کې یې انتقال کړئ. د خام ویډیو جریان د ویب ساکټونو له لارې نشي لیږدول کیدی. دا هغه ځای دی چې زموږ مرستې ته راځي
موږ د ویډیو جریان کوډ کوو، په برخو کې یې ماتوو
<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>
د خپرونې اړخ چمتو دی! اوس راځئ چې د ویډیو جریان ترلاسه کولو هڅه وکړو او په پیرودونکي کې یې وښیو. موږ د دې لپاره څه ته اړتیا لرو؟ لومړی، البته، د ساکټ پیوستون. موږ د ویب ساکټ اعتراض سره "اوریدونکي" ضمیمه کوو او د 'پیغام' پیښې ته ګډون کوو. د بائنری ډیټا یوه ټوټه ترلاسه کولو سره ، زموږ سرور دا پیرودونکو ته خپروي ، یعنی پیرودونکي. په دې حالت کې، د 'پیغام' پیښې د "اوریدونکي" سره تړلی د کال بیک فنکشن په پیرودونکي کې پیل کیږي؛ اعتراض پخپله د فنکشن دلیل ته لیږدول کیږي - د ویډیو جریان یوه ټوټه د 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>
د اوږدې مودې لپاره ما هڅه وکړه چې پوه شم چې ولې دا ناشونې ده چې ترلاسه شوي ټوټې سمدلاسه د ویډیو عنصر ته د پلے بیک لپاره واستوئ، مګر دا معلومه شوه چې دا نشي ترسره کیدی، البته، تاسو باید لومړی ټوټه په ځانګړي بفر کې واچوئ. د ویډیو عنصر، او یوازې بیا به دا د ویډیو جریان پیل کړي. د دې لپاره تاسو اړتیا لرئ
میډیا سرچینه د میډیا پلے بیک څیز او د دې میډیا جریان سرچینې ترمینځ د یو ډول مینځګړی په توګه کار کوي. د میډیا سورس اعتراض د ویډیو/آډیو جریان سرچینې لپاره د پلګ وړ وړ بفر لري. یوه ځانګړتیا دا ده چې بفر یوازې د Uint8 ډاټا ساتلی شي، نو تاسو به د داسې بفر جوړولو لپاره فایل ریډر ته اړتیا ولرئ. کوډ وګورئ او دا به نور روښانه شي:
د ویډیو جریان پلی کول
<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 شاته پاتې شي؛ موږ دا پخپله تنظیم کوو کله چې سرور ته د لیږدولو دمخه د ویډیو جریان ویشلو. سربیره پردې ، کله چې ما په خپل لپ ټاپ کې چیک کړ ، د لیږد او ترلاسه کولو اړخونو ترمینځ وقفه په تدریجي ډول راټولیږي ، دا په څرګنده توګه لیدل کیده. ما د دې نیمګړتیا د لرې کولو لپاره د لارو په لټه کې پیل وکړ، او ... راورسید
سرچینه: www.habr.com