(ಬಹುತೇಕ) ಬ್ರೌಸರ್‌ನಿಂದ ಅನುಪಯುಕ್ತ ವೆಬ್‌ಕ್ಯಾಮ್ ಸ್ಟ್ರೀಮಿಂಗ್. ಮೀಡಿಯಾ ಸ್ಟ್ರೀಮ್ ಮತ್ತು ವೆಬ್‌ಸಾಕೆಟ್‌ಗಳು

ಈ ಲೇಖನದಲ್ಲಿ ನಾನು ಅಡೋಬ್ ಫ್ಲ್ಯಾಶ್ ಪ್ಲೇಯರ್‌ನಂತಹ ಮೂರನೇ ವ್ಯಕ್ತಿಯ ಬ್ರೌಸರ್ ಪ್ಲಗಿನ್‌ಗಳನ್ನು ಬಳಸದೆ ವೆಬ್‌ಸಾಕೆಟ್‌ಗಳ ಮೂಲಕ ವೀಡಿಯೊವನ್ನು ಸ್ಟ್ರೀಮ್ ಮಾಡುವ ನನ್ನ ಪ್ರಯತ್ನಗಳನ್ನು ಹಂಚಿಕೊಳ್ಳಲು ಬಯಸುತ್ತೇನೆ. ಅದರಿಂದ ಏನಾಯಿತು ಎಂದು ತಿಳಿಯಲು ಮುಂದೆ ಓದಿ.

ಅಡೋಬ್ ಫ್ಲ್ಯಾಶ್, ಹಿಂದೆ ಮ್ಯಾಕ್ರೋಮೀಡಿಯಾ ಫ್ಲ್ಯಾಶ್, ವೆಬ್ ಬ್ರೌಸರ್‌ನಲ್ಲಿ ಕಾರ್ಯನಿರ್ವಹಿಸುವ ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ರಚಿಸಲು ಒಂದು ವೇದಿಕೆಯಾಗಿದೆ. ಮೀಡಿಯಾ ಸ್ಟ್ರೀಮ್ API ಅನ್ನು ಪರಿಚಯಿಸುವ ಮೊದಲು, ಇದು ಪ್ರಾಯೋಗಿಕವಾಗಿ ವೆಬ್‌ಕ್ಯಾಮ್‌ನಿಂದ ವೀಡಿಯೊ ಮತ್ತು ಧ್ವನಿಯನ್ನು ಸ್ಟ್ರೀಮಿಂಗ್ ಮಾಡಲು ಮತ್ತು ಬ್ರೌಸರ್‌ನಲ್ಲಿ ವಿವಿಧ ರೀತಿಯ ಕಾನ್ಫರೆನ್ಸ್ ಮತ್ತು ಚಾಟ್‌ಗಳನ್ನು ರಚಿಸಲು ಏಕೈಕ ವೇದಿಕೆಯಾಗಿತ್ತು. ಮಾಧ್ಯಮ ಮಾಹಿತಿಯನ್ನು ರವಾನಿಸುವ ಪ್ರೋಟೋಕಾಲ್ RTMP (ರಿಯಲ್ ಟೈಮ್ ಮೆಸೇಜಿಂಗ್ ಪ್ರೋಟೋಕಾಲ್) ಅನ್ನು ದೀರ್ಘಕಾಲದವರೆಗೆ ಮುಚ್ಚಲಾಗಿದೆ, ಇದರರ್ಥ: ನಿಮ್ಮ ಸ್ಟ್ರೀಮಿಂಗ್ ಸೇವೆಯನ್ನು ಹೆಚ್ಚಿಸಲು ನೀವು ಬಯಸಿದರೆ, Adobe ನಿಂದ ಸಾಫ್ಟ್‌ವೇರ್ ಅನ್ನು ಬಳಸಲು ಸಾಕಷ್ಟು ದಯೆಯಿಂದಿರಿ - Adobe Media Server (AMS).

2012 ರಲ್ಲಿ ಸ್ವಲ್ಪ ಸಮಯದ ನಂತರ, ಅಡೋಬ್ ಸಾರ್ವಜನಿಕರಿಗೆ "ಅದನ್ನು ಬಿಟ್ಟುಕೊಟ್ಟಿತು ಮತ್ತು ಉಗುಳಿತು". ನಿರ್ದಿಷ್ಟತೆ RTMP ಪ್ರೋಟೋಕಾಲ್, ಇದು ದೋಷಗಳನ್ನು ಒಳಗೊಂಡಿದೆ ಮತ್ತು ಮೂಲಭೂತವಾಗಿ ಅಪೂರ್ಣವಾಗಿದೆ. ಆ ಹೊತ್ತಿಗೆ, ಅಭಿವರ್ಧಕರು ಈ ಪ್ರೋಟೋಕಾಲ್ನ ತಮ್ಮದೇ ಆದ ಅನುಷ್ಠಾನಗಳನ್ನು ಮಾಡಲು ಪ್ರಾರಂಭಿಸಿದರು, ಮತ್ತು Wowza ಸರ್ವರ್ ಕಾಣಿಸಿಕೊಂಡಿತು. 2011 ರಲ್ಲಿ, RTMP-ಸಂಬಂಧಿತ ಪೇಟೆಂಟ್‌ಗಳ ಅಕ್ರಮ ಬಳಕೆಗಾಗಿ ಅಡೋಬ್ ವೊವ್ಜಾ ವಿರುದ್ಧ ಮೊಕದ್ದಮೆ ಹೂಡಿತು; 4 ವರ್ಷಗಳ ನಂತರ, ಸಂಘರ್ಷವನ್ನು ಸೌಹಾರ್ದಯುತವಾಗಿ ಪರಿಹರಿಸಲಾಯಿತು.

ಅಡೋಬ್ ಫ್ಲ್ಯಾಶ್ ಪ್ಲಾಟ್‌ಫಾರ್ಮ್ 20 ವರ್ಷಗಳಿಗಿಂತ ಹೆಚ್ಚು ಹಳೆಯದಾಗಿದೆ, ಈ ಸಮಯದಲ್ಲಿ ಅನೇಕ ನಿರ್ಣಾಯಕ ದೋಷಗಳನ್ನು ಕಂಡುಹಿಡಿಯಲಾಗಿದೆ, ಬೆಂಬಲ ಭರವಸೆ ನೀಡಿದರು ಸ್ಟ್ರೀಮಿಂಗ್ ಸೇವೆಗಾಗಿ ಕೆಲವು ಪರ್ಯಾಯಗಳನ್ನು ಬಿಟ್ಟು 2020 ರ ವೇಳೆಗೆ ಕೊನೆಗೊಳ್ಳುತ್ತದೆ.

ನನ್ನ ಯೋಜನೆಗಾಗಿ, ಬ್ರೌಸರ್‌ನಲ್ಲಿ ಫ್ಲ್ಯಾಶ್ ಬಳಕೆಯನ್ನು ಸಂಪೂರ್ಣವಾಗಿ ತ್ಯಜಿಸಲು ನಾನು ತಕ್ಷಣವೇ ನಿರ್ಧರಿಸಿದೆ. ನಾನು ಮೇಲಿನ ಮುಖ್ಯ ಕಾರಣವನ್ನು ಸೂಚಿಸಿದ್ದೇನೆ; ಮೊಬೈಲ್ ಪ್ಲಾಟ್‌ಫಾರ್ಮ್‌ಗಳಲ್ಲಿ ಫ್ಲ್ಯಾಶ್ ಅನ್ನು ಸಹ ಬೆಂಬಲಿಸುವುದಿಲ್ಲ ಮತ್ತು ವಿಂಡೋಸ್ (ವೈನ್ ಎಮ್ಯುಲೇಟರ್) ನಲ್ಲಿ ಅಭಿವೃದ್ಧಿಗಾಗಿ ಅಡೋಬ್ ಫ್ಲ್ಯಾಶ್ ಅನ್ನು ನಿಯೋಜಿಸಲು ನಾನು ನಿಜವಾಗಿಯೂ ಬಯಸುವುದಿಲ್ಲ. ಹಾಗಾಗಿ ಜಾವಾಸ್ಕ್ರಿಪ್ಟ್‌ನಲ್ಲಿ ಕ್ಲೈಂಟ್ ಬರೆಯಲು ನಾನು ಹೊರಟೆ. ಇದು ಕೇವಲ ಒಂದು ಮೂಲಮಾದರಿಯಾಗಿದೆ, ಏಕೆಂದರೆ 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)
}

ಕ್ಲೈಂಟ್‌ನಲ್ಲಿ (ಸ್ಟ್ರೀಮಿಂಗ್ ಸೈಡ್), ನೀವು ಮೊದಲು ಕ್ಯಾಮರಾವನ್ನು ಪ್ರವೇಶಿಸಬೇಕಾಗುತ್ತದೆ. ಇದರ ಮೂಲಕ ಮಾಡಲಾಗುತ್ತದೆ ಮೀಡಿಯಾಸ್ಟ್ರೀಮ್ API.

ನಾವು ಕ್ಯಾಮೆರಾ/ಮೈಕ್ರೊಫೋನ್‌ಗೆ ಪ್ರವೇಶವನ್ನು (ಅನುಮತಿ) ಪಡೆಯುತ್ತೇವೆ ಮಾಧ್ಯಮ ಸಾಧನಗಳ API. ಈ API ಒಂದು ವಿಧಾನವನ್ನು ಒದಗಿಸುತ್ತದೆ MediaDevices.getUserMedia(), ಇದು ಪಾಪ್ಅಪ್ ಅನ್ನು ತೋರಿಸುತ್ತದೆ. ಕ್ಯಾಮರಾ ಮತ್ತು/ಅಥವಾ ಮೈಕ್ರೊಫೋನ್ ಅನ್ನು ಪ್ರವೇಶಿಸಲು ಅನುಮತಿಗಾಗಿ ಬಳಕೆದಾರರನ್ನು ಕೇಳುವ ವಿಂಡೋ. ನಾನು Google Chrome ನಲ್ಲಿ ಎಲ್ಲಾ ಪ್ರಯೋಗಗಳನ್ನು ನಡೆಸಿದ್ದೇನೆ ಎಂದು ನಾನು ಗಮನಿಸಲು ಬಯಸುತ್ತೇನೆ, ಆದರೆ Firefox ನಲ್ಲಿ ಎಲ್ಲವೂ ಒಂದೇ ರೀತಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ ಎಂದು ನಾನು ಭಾವಿಸುತ್ತೇನೆ.

ಮುಂದೆ, 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>

ಸಾಕೆಟ್‌ಗಳ ಮೂಲಕ ವೀಡಿಯೊ ಸ್ಟ್ರೀಮ್ ಅನ್ನು ಪ್ರಸಾರ ಮಾಡಲು, ನೀವು ಅದನ್ನು ಎಲ್ಲೋ ಎನ್‌ಕೋಡ್ ಮಾಡಬೇಕಾಗುತ್ತದೆ, ಅದನ್ನು ಬಫರ್ ಮಾಡಿ ಮತ್ತು ಭಾಗಗಳಲ್ಲಿ ರವಾನಿಸಬೇಕು. ಕಚ್ಚಾ ವೀಡಿಯೊ ಸ್ಟ್ರೀಮ್ ಅನ್ನು ವೆಬ್‌ಸಾಕೆಟ್‌ಗಳ ಮೂಲಕ ರವಾನಿಸಲಾಗುವುದಿಲ್ಲ. ಇದು ನಮ್ಮ ನೆರವಿಗೆ ಬರುವುದು ಇಲ್ಲಿಯೇ ಮೀಡಿಯಾ ರೆಕಾರ್ಡರ್ 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 и ಫೈಲ್ ರೀಡರ್ API.

ಮೀಡಿಯಾ ಸೋರ್ಸ್ ಮಾಧ್ಯಮ ಪ್ಲೇಬ್ಯಾಕ್ ವಸ್ತು ಮತ್ತು ಈ ಮಾಧ್ಯಮ ಸ್ಟ್ರೀಮ್‌ನ ಮೂಲದ ನಡುವೆ ಒಂದು ರೀತಿಯ ಮಧ್ಯವರ್ತಿಯಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ. MediaSource ಆಬ್ಜೆಕ್ಟ್ ವೀಡಿಯೊ/ಆಡಿಯೋ ಸ್ಟ್ರೀಮ್‌ನ ಮೂಲಕ್ಕಾಗಿ ಪ್ಲಗ್ ಮಾಡಬಹುದಾದ ಬಫರ್ ಅನ್ನು ಒಳಗೊಂಡಿದೆ. ಒಂದು ವೈಶಿಷ್ಟ್ಯವೆಂದರೆ ಬಫರ್ 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 ಎಂಎಸ್‌ಗಳಷ್ಟು ಹಿಂದುಳಿಯುತ್ತದೆ; ಸರ್ವರ್‌ಗೆ ರವಾನಿಸುವ ಮೊದಲು ವೀಡಿಯೊ ಸ್ಟ್ರೀಮ್ ಅನ್ನು ವಿಭಜಿಸುವಾಗ ನಾವು ಇದನ್ನು ಹೊಂದಿಸುತ್ತೇವೆ. ಇದಲ್ಲದೆ, ನನ್ನ ಲ್ಯಾಪ್‌ಟಾಪ್‌ನಲ್ಲಿ ನಾನು ಪರಿಶೀಲಿಸಿದಾಗ, ರವಾನಿಸುವ ಮತ್ತು ಸ್ವೀಕರಿಸುವ ಬದಿಗಳ ನಡುವಿನ ವಿಳಂಬವು ಕ್ರಮೇಣ ಸಂಗ್ರಹವಾಯಿತು, ಇದು ಸ್ಪಷ್ಟವಾಗಿ ಗೋಚರಿಸುತ್ತದೆ. ನಾನು ಈ ಅನನುಕೂಲತೆಯನ್ನು ಜಯಿಸಲು ಮಾರ್ಗಗಳನ್ನು ಹುಡುಕಲು ಪ್ರಾರಂಭಿಸಿದೆ, ಮತ್ತು ... ಅಡ್ಡ ಬಂದಿತು RTCPeerConection API, ಇದು ಸ್ಟ್ರೀಮ್ ಅನ್ನು ತುಂಡುಗಳಾಗಿ ವಿಭಜಿಸುವಂತಹ ತಂತ್ರಗಳಿಲ್ಲದೆ ವೀಡಿಯೊ ಸ್ಟ್ರೀಮ್ ಅನ್ನು ರವಾನಿಸಲು ನಿಮಗೆ ಅನುಮತಿಸುತ್ತದೆ. ಸಂಚಯಿಸುವ ಮಂದಗತಿ, ಬ್ರೌಸರ್ ಪ್ರತಿ ತುಣುಕನ್ನು ಪ್ರಸರಣಕ್ಕೆ ಮೊದಲು ವೆಬ್‌ಎಂ ಸ್ವರೂಪಕ್ಕೆ ಮರು-ಎನ್‌ಕೋಡ್ ಮಾಡುತ್ತದೆ ಎಂದು ನಾನು ಭಾವಿಸುತ್ತೇನೆ. ನಾನು ಮತ್ತಷ್ಟು ಅಗೆಯಲಿಲ್ಲ, ಆದರೆ ವೆಬ್‌ಆರ್‌ಟಿಸಿಯನ್ನು ಅಧ್ಯಯನ ಮಾಡಲು ಪ್ರಾರಂಭಿಸಿದೆ. ನನ್ನ ಸಂಶೋಧನೆಯ ಫಲಿತಾಂಶಗಳು ಸಮುದಾಯಕ್ಕೆ ಆಸಕ್ತಿದಾಯಕವಾಗಿದ್ದರೆ ಅದರ ಬಗ್ಗೆ ಪ್ರತ್ಯೇಕ ಲೇಖನವನ್ನು ಬರೆಯುತ್ತೇನೆ ಎಂದು ನಾನು ಭಾವಿಸುತ್ತೇನೆ.

ಮೂಲ: www.habr.com

ಕಾಮೆಂಟ್ ಅನ್ನು ಸೇರಿಸಿ