(Tata) karekau karekau e rere ana mai i te kaitirotiro. Ko te Rerenga Media me nga Paetukutuku

I roto i tenei tuhinga e hiahia ana ahau ki te whakapuaki i aku ngana ki te rere ataata ma te ipurangi me te kore e whakamahi i nga taputapu tirotiro tuatoru penei i te Adobe Flash Player. Pānuihia kia mohio koe he aha i puta mai ai.

Ko te Adobe Flash, ko Macromedia Flash i mua, he papa mo te hanga tono ka rere i roto i te kaitirotiro paetukutuku. I mua i te whakaurunga o te Media Stream API, koinei anake te papaahi mo te rere ataata me te reo mai i te kaamera, me te hanga i nga momo huihuinga me nga korerorero i roto i te tirotiro. Ko te kawa mo te tuku korero pāpāho RTMP (Real Time Messaging Protocol) i tino kati mo te wa roa, ko te tikanga: ki te hiahia koe ki te whakanui i to ratonga roma, kia pai ki te whakamahi i te rorohiko mai i a Adobe ake - Adobe Media Server (AMS).

I muri i etahi wa i te tau 2012, ka "tuku a Adobe ka tuwhaina" ki te marea. whakaritenga Kawa RTMP, he hapa kei roto, kaore i oti. I taua wa, ka timata nga kaiwhakawhanake ki te hanga i a raatau ake whakatinanatanga o tenei kawa, ka puta mai te tūmau Wowza. I te tau 2011, ka tukuna e Adobe he whakawakanga ki a Wowza mo te whakamahi kore ture o nga patent e pa ana ki te RTMP; i muri i nga tau e 4, ka whakatauhia te raruraru.

Neke atu i te 20 tau te papaaho Adobe Flash, i taua wa kua kitea te maha o nga whakaraeraetanga, tautoko. oati ka mutu hei te tau 2020, he iti noa nga whiringa mo te ratonga roma.

Mo taku kaupapa, ka whakatau tonu ahau ki te whakarere i te whakamahinga o Flash i roto i te tirotiro. I tohuhia e au te take nui i runga ake nei; Kaore ano hoki te Flash i te tautokohia i runga i nga papaaho pūkoro, a kaore au i tino hiahia ki te tuku Adobe Flash mo te whakawhanaketanga i runga i te Windows (emulator waina). Na ka haere ahau ki te tuhi i tetahi kaihoko ki te JavaScript. He tauira noa tenei, no te mea i muri mai ka mohio au ka taea te mahi rerema i runga i te p2p, ko au anake ka noho hoa - kaimau - hoa, engari he maha atu mo tera waa, na te mea kaore ano kia rite.

Hei timata, me hiahia tatou ki te tūmau tukutuku pono. I hanga e ahau te mea ngawari i runga i te kete waiata haere:

Waehere tūmau

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)
}

I runga i te kiritaki (taha roma), me uru tuatahi koe ki te kamera. Ka mahia tenei ma API MediaStream.

Ka whiwhi tatou i te urunga (whakaaetanga) ki te kamera/microphone ma API Pūrere Media. Ka whakaratohia e tenei API he tikanga MediaDevices.getUserMedia(), e whakaatu ana te pahūake. he matapihi e tono ana kia whakaaetia te kaiwhakamahi kia uru atu ki te kamera me te hopuoro/ranei. E hiahia ana ahau ki te kite i mahia e au nga whakamatautau katoa i roto i a Google Chrome, engari ki taku whakaaro ka mahi nga mea katoa i roto i te Firefox.

Whai muri, ka whakahokia mai e te getUserMedia() he kupu Oati, ka tukuna he ahanoa MediaStream - he rerenga raraunga oro-ataata. Ka tautapahia tenei ahanoa ki te taonga src o te huānga ataata. Waehere:

Te taha panui

<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>

Ki te whakapaoho i tetahi awa ataata ki runga i nga turanga, me whakawaehere koe ki tetahi waahi, ka panaia, ka tuku i etahi waahanga. Kaore e taea te tuku i te awa ataata mata ma te ipurangi. Koinei te waahi ki te awhina i a maatau MediaRecorder API. Ma tenei API ka taea e koe te whakawaehere me te wawahi i te awa ki nga waahanga. Kei te whakawaehere ahau ki te kopiri i te awa ataata kia iti ake te tuku paita ki runga i te whatunga. Kua pakaruhia ki roto i nga wahanga, ka taea e koe te tuku ia wahi ki te turanga tukutuku. Waehere:

Ka whakawaeheretia e matou te awa ataata, ka wahia ki nga wahanga

<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>

Inaianei me taapiri atu te tuku ma te ipurangi. He mea whakamiharo, ko nga mea katoa e hiahia ana koe mo tenei he mea Paetukutuku. E rua noa nga tikanga tuku me te kati. Ko nga ingoa e korero ana mo ratou ano. Waehere taapiri:

Ka tukuna e matou te awa ataata ki te tūmau

<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>

Kua reri te taha haapurororaa! Inaianei me ngana ki te tango i tetahi awa ataata me te whakaatu ki te kaihoko. He aha ta tatou e hiahia ana mo tenei? Tuatahi, o te akoranga, te hononga turanga. Ka taapirihia he "kaiwhakarongo" ki te ahanoa WebSocket ka ohauru ki te kaupapa 'karere'. I te whiwhinga i tetahi waahanga o nga raraunga ruarua, ka tukuna e to maatau tūmau ki nga kaiohauru, ara, ki nga kaihoko. I tenei keehi, ko te mahi waea hoki e hono ana ki te "kaiwhakarongo" o te huihuinga 'karere' ka puta ki runga i te kiritaki; ko te ahanoa ano ka tukuna ki roto i te tautohe mahi - he waahanga o te awa ataata kua whakawaeheretia e vp8.

Ka whakaae matou ki te roma ataata

<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>

Mo te wa roa i whakamatau ahau ki te mohio he aha e kore e taea te tuku tonu i nga waahanga kua riro mai ki te huānga ataata mo te purei, engari i puta mai kaore e taea te mahi, o te akoranga, me whakauru tuatahi koe i te waahanga ki roto i tetahi papaa motuhake kua herea ki te huānga ataata, katahi ka timata te purei i te awa ataata. Mo tenei ka hiahia koe MediaSource API и APIReader API.

Ka mahi a MediaSource hei momo takawaenga i waenga i te ahanoa purei papaho me te puna o tenei awa pāpāho. Kei roto i te ahanoa MediaSource he parepare mono mo te puna o te awa ataata/ororongo. Ko tetahi o nga ahuatanga ka taea e te kaitarai te pupuri i nga raraunga Uint8 anake, no reira ka hiahia koe ki te Kaipupuri Kōnae hei hanga i taua parepare. Titiro ki te waehere ka tino marama ake:

Te purei i te roma ataata

<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>

Kua reri te tauira o te ratonga roma. Ko te kino nui ko te purei ataata ka taka ki muri i te taha tuku ma te 100 ms; ka whakatauhia e matou ma te wehe i te awa ataata i mua i te tuku ki te tūmau. I tua atu, i taku tirotiro i taku pona, ka piki haere te wa i waenga i nga taha tuku me te taha tango, ka tino kitea tenei. I timata ahau ki te rapu huarahi ki te hinga i tenei ngoikoretanga, a... ka puta RTCPeerConnection API, ka taea e koe te tuku i te awa ataata me te kore tinihanga penei i te wehewehe i te awa ki nga wahanga. Ki taku whakaaro, na te mea ka whakawaehere ano e te kaitirotiro ia waahanga ki te whakatakotoranga webm i mua i te tuku. Kaore au i keri atu, engari ka timata ahau ki te ako i te WebRTC. Ki taku whakaaro ka tuhia e au tetahi tuhinga motuhake mo nga hua o aku rangahau mena ka kitea e au he mea pai ki te hapori.

Source: will.com

Tāpiri i te kōrero