{"id":94138,"date":"2020-09-13T07:42:42","date_gmt":"2020-09-13T05:42:42","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/pochti-bespoleznyj-striming-vebkamery-iz-brauzera-media-stream-i-websockets"},"modified":"2020-09-13T07:42:42","modified_gmt":"2020-09-13T05:42:42","slug":"pochti-bespoleznyj-striming-vebkamery-iz-brauzera-media-stream-i-websockets","status":"publish","type":"post","link":"https:\/\/prohoster.info\/sq\/blog\/administrirovanie\/pochti-bespoleznyj-striming-vebkamery-iz-brauzera-media-stream-i-websockets","title":{"rendered":"(Gati) streaming pa p\u00ebrdorim t\u00eb kamerave nga shfletuesi. Media Stream dhe Websockets","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>N\u00eb k\u00ebt\u00eb artikull, dua t\u00eb ndajem p\u00ebrpjekjet e mia p\u00ebr t\u00eb b\u00ebr\u00eb streaming video p\u00ebrmes websockets pa p\u00ebrdorur plugina t\u00eb pal\u00ebve t\u00eb treta t\u00eb shfletuesit, si Adobe Flash Player. \u00c7far\u00eb doli nga kjo, lexoni m\u00eb posht\u00eb.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><br \/>\nAdobe Flash \u2014 m\u00eb par\u00eb Macromedia Flash, \u00ebsht\u00eb nj\u00eb platform\u00eb p\u00ebr krijimin e aplikacioneve q\u00eb funksionojn\u00eb n\u00eb shfletuesin e internetit. Para se t\u00eb p\u00ebrdorej Media Stream API, kjo ishte praktisht platforma e vetme p\u00ebr streaming video dhe audio nga kamera, si dhe p\u00ebr krijimin e llojeve t\u00eb ndryshme t\u00eb konferencave dhe bisedave n\u00eb shfletues. Protokolli p\u00ebr transferimin e informacionit mediatik RTMP (Real Time Messaging Protocol), ishte faktikisht i mbyllur p\u00ebr nj\u00eb koh\u00eb t\u00eb gjat\u00eb, \u00e7ka do t\u00eb thoshte: n\u00ebse d\u00ebshiron t\u00eb krijosh sh\u00ebrbimin t\u00ebnd t\u00eb streaming, duhet t\u00eb p\u00ebrdor\u00ebsh softin e Adobe \u2014 Adobe Media Server (AMS). <\/p>\n<p>Pas nj\u00eb koh\u00eb, n\u00eb 2012, Adobe \"u dor\u00ebzuan dhe e lan\u00eb\" publikun t\u00eb njihte <noindex><a rel=\"nofollow\" href=\"http:\/\/wwwimages.adobe.com\/www.adobe.com\/content\/dam\/acom\/en\/devnet\/rtmp\/pdf\/rtmp_specification_1.0.pdf\">specifikimin<\/a><\/noindex> protokollin RTMP, i cili kishte gabime dhe faktikisht nuk ishte i plot\u00eb. E n\u00eb at\u00eb koh\u00eb zhvilluesit filluan t\u00eb krijonin implementime t\u00eb veta t\u00eb k\u00ebtij protokolli, k\u00ebshtu q\u00eb u krijua serveri Wowza. N\u00eb 2011, Adobe paditi Wowza p\u00ebr p\u00ebrdorimin e paligjsh\u00ebm t\u00eb patentave lidhur me RTMP, dhe pas 4 vitesh, konflikti u zgjodh n\u00eb paqe. <\/p>\n<p>Platforma Adobe Flash \u00ebsht\u00eb mbi 20 vje\u00e7are, dhe gjat\u00eb k\u00ebsaj kohe jan\u00eb zbuluar shum\u00eb vulnerabilitete kritike, mb\u00ebshtetja <noindex><a rel=\"nofollow\" href=\"https:\/\/webkit.org\/blog\/7839\/adobe-announces-flash-distribution-and-updates-to-end\/\">u premtonin<\/a><\/noindex> do t\u00eb p\u00ebrfundoj\u00eb n\u00eb vitin 2020, k\u00ebshtu q\u00eb alternativat p\u00ebr sh\u00ebrbimin e streamingut nuk jan\u00eb aq t\u00eb shumta. <\/p>\n<p>P\u00ebr projektin tim, vendosa menj\u00ebher\u00eb t\u00eb heq dor\u00eb plot\u00ebsisht nga p\u00ebrdorimi i Flash n\u00eb shfletues. Arsyeja kryesore e kam p\u00ebrmendur m\u00eb lart, gjithashtu Flash nuk mb\u00ebshtetet n\u00eb platformat mobile, dhe gjithashtu nuk doja t\u00eb konfigurja Adobe Flash p\u00ebr zhvillim n\u00eb Windows (n\u00eb emulatorin Wine). Prandaj, fillova t\u00eb shkruaj nj\u00eb klient n\u00eb JavaScript. Kjo do t\u00eb jet\u00eb vet\u00ebm nj\u00eb prototip, pasi m\u00eb von\u00eb m\u00ebsova se streaming mund t\u00eb b\u00ebhet shum\u00eb m\u00eb efektivisht mbi baz\u00ebn e p2p, vet\u00ebm se n\u00eb rastin tim do t\u00eb jet\u00eb peer \u2014 server \u2014 peers, por p\u00ebr k\u00ebt\u00eb nj\u00ebher\u00eb tjet\u00ebr, sepse akoma nuk \u00ebsht\u00eb gati.<\/p>\n<p>P\u00ebr t\u00eb filluar pun\u00ebn, na nevojitet nj\u00eb server websockets. Un\u00eb krijova nj\u00eb t\u00eb thjesht\u00eb mbi paket\u00ebn go melody:<\/p>\n<p>                        <b class=\"spoiler_title\">Kodi i pjes\u00ebs server<\/b><\/p>\n<pre><code class=\"go\">paket kryesor\n\nimport (\n\t\"errors\"\n\t\"github.com\/go-chi\/chi\"\n\t\"gopkg.in\/olahol\/melody.v1\"\n\t\"log\"\n\t\"net\/http\"\n\t\"time\"\n)\n\nfunksioni kryesor() {\n\tr := chi.NewRouter()\n\tm := melody.New()\n\n\tm.Config.MaxMessageSize = 204800\n\n\tr.Get(\"\/\", func(w http.ResponseWriter, r *http.Request) {\n\t\thttp.ServeFile(w, r, \"public\/index.html\")\n\t})\n\tr.Get(\"\/ws\", func(w http.ResponseWriter, r *http.Request) {\n\t\tm.HandleRequest(w, r)\n\t})\n\n         \/\/ Transmetojm\u00eb videon\n\tm.HandleMessageBinary(func(s *melody.Session, msg []byte) {\n\t\tm.BroadcastBinary(msg)\n\t})\n\n\tlog.Println(\"Duke filluar serverin...\")\n\n\thttp.ListenAndServe(\":3000\", r)\n}\n<\/code><\/pre>\n<p>N\u00eb klient (an\u00ebn q\u00eb transmeton) fillimisht \u00ebsht\u00eb e nevojshme t\u00eb fitohet akses n\u00eb kamer\u00eb. Kjo b\u00ebhet p\u00ebrmes <noindex><a rel=\"nofollow\" href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Media_Streams_API\">MediaStream API<\/a><\/noindex>.<\/p>\n<p>Marrim lejen p\u00ebr akses n\u00eb kamer\u00eb\/mikrofon p\u00ebrmes <noindex><a rel=\"nofollow\" href=\"https:\/\/developer.mozilla.org\/ru\/docs\/Web\/API\/MediaDevices\">Media Devices API<\/a><\/noindex>. Ky API ofron metod\u00ebn <noindex><a rel=\"nofollow\" href=\"https:\/\/developer.mozilla.org\/ru\/docs\/Web\/API\/MediaDevices\/getUserMedia\">MediaDevices.getUserMedia()<\/a><\/noindex>, e cila shfaq nj\u00eb dritare pop-up, q\u00eb k\u00ebrkon lejen e p\u00ebrdoruesit p\u00ebr akses n\u00eb kamer\u00eb ose\/edhe mikrofon. D\u00ebshiroj t\u00eb theksoj se t\u00eb gjitha eksperimentet i kam krejt n\u00eb Google Chrome, por mendoj se n\u00eb Firefox do t\u00eb funksionoj\u00eb p\u00ebraf\u00ebrsisht si\u00e7 duhet.<\/p>\n<p>M\u00eb pas getUserMedia() kthen nj\u00eb Promise, n\u00eb t\u00eb cilin d\u00ebrgon nj\u00eb objekt MediaStream \u2014 nj\u00eb rrjedh\u00eb t\u00eb dh\u00ebnash video-audio. Ky objekt e kemi caktuar n\u00eb pron\u00ebsin\u00eb src t\u00eb elementit video. Kodi:<\/p>\n<p>                        <b class=\"spoiler_title\">An\u00eb e transmetimit<\/b><\/p>\n<pre><code class=\"javascript\">&lt;style&gt;\n  #videoObjectHtml5ApiServer { width: 320px; height: 240px; background: #666; }\n&lt;\/style&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n&lt;!-- \u0417\u0434\u0435\u0441\u044c \u0432 \u044d\u0442\u043e\u043c &quot;\u043e\u043a\u043e\u0448\u0435\u0447\u043a\u0435&quot; \u043a\u043b\u0438\u0435\u043d\u0442 \u0431\u0443\u0434\u0435\u0442 \u0432\u0438\u0434\u0435\u0442\u044c \u0441\u0435\u0431\u044f --&gt;\n&lt;video autoplay id=&quot;videoObjectHtml5ApiServer&quot;&gt;&lt;\/video&gt;\n\n&lt;script type=&quot;application\/javascript&quot;&gt;\n  var\n        video = document.getElementById(&#039;videoObjectHtml5ApiServer&#039;);\n\n\/\/ \u0435\u0441\u043b\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d MediaDevices API, \u043f\u044b\u0442\u0430\u0435\u043c\u0441\u044f \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u043a\u0430\u043c\u0435\u0440\u0435 (\u043c\u043e\u0436\u043d\u043e \u0435\u0449\u0435 \u0438 \u043a \u043c\u0438\u043a\u0440\u043e\u0444\u043e\u043d\u0443)\n\/\/ getUserMedia \u0432\u0435\u0440\u043d\u0435\u0442 \u043e\u0431\u0435\u0449\u0430\u043d\u0438\u0435, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u043e\u0434\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c\u0441\u044f \u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u0432\u0438\u0434\u0435\u043e\u043f\u043e\u0442\u043e\u043a \u0432 \u043a\u043e\u043b\u0431\u0435\u043a\u0435 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0432 video \u043e\u0431\u044a\u0435\u043a\u0442 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435\n\nif (navigator.mediaDevices.getUserMedia) {\n        navigator.mediaDevices.getUserMedia({video: true}).then(function (stream) {\n          \/\/ \u0432\u0438\u0434\u0435\u043e \u043f\u043e\u0442\u043e\u043a \u043f\u0440\u0438\u0432\u044f\u0437\u044b\u0432\u0430\u0435\u043c \u043a video \u0442\u0435\u0433\u0443, \u0447\u0442\u043e\u0431\u044b \u043a\u043b\u0438\u0435\u043d\u0442 \u043c\u043e\u0433 \u0432\u0438\u0434\u0435\u0442\u044c \u0441\u0435\u0431\u044f \u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \n          video.srcObject = stream;\n        });\n}\n&lt;\/script&gt;\n<\/code><\/pre>\n<p>P\u00ebr t\u00eb transmetuar videopolit p\u00ebrmes soketeve, \u00ebsht\u00eb e nevojshme q\u00eb ndonj\u00eb m\u00ebnyr\u00eb ta kodosh, ta bufferosh, dhe ta transmetosh n\u00eb pjes\u00eb. Nj\u00eb rrjedh\u00eb videoje e pap\u00ebrpunuar nuk mund t\u00eb d\u00ebrgohet p\u00ebrmes websockets. K\u00ebtu vjen n\u00eb ndihm\u00eb <noindex><a rel=\"nofollow\" href=\"https:\/\/developer.mozilla.org\/ru\/docs\/Web\/API\/MediaStream_Recording_API\">MediaRecorder API<\/a><\/noindex>. Ky API lejon kodimin dhendarjen e rrjedh\u00ebs n\u00eb copa. Kodimi e b\u00ebj p\u00ebr t\u00eb kompresuar rrjedh\u00ebn video, q\u00eb t\u00eb b\u00ebj m\u00eb pak bytes n\u00eb rrjet. Pasi t\u00eb ndahet n\u00eb copa, \u00e7do cop\u00eb mund t\u00eb d\u00ebrgohet n\u00eb websocket. Kodi:<\/p>\n<p>                        <b class=\"spoiler_title\">Kodojm\u00eb rrjedh\u00ebn video, e ndajm\u00eb n\u00eb pjes\u00eb<\/b><\/p>\n<pre><code class=\"javascript\">&lt;style&gt;\n  #videoObjectHtml5ApiServer { width: 320px; height: 240px; background: #666; }\n&lt;\/style&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n&lt;!-- \u0417\u0434\u0435\u0441\u044c \u0432 \u044d\u0442\u043e\u043c &quot;\u043e\u043a\u043e\u0448\u0435\u0447\u043a\u0435&quot; \u043a\u043b\u0438\u0435\u043d\u0442 \u0431\u0443\u0434\u0435\u0442 \u0432\u0438\u0434\u0435\u0442\u044c \u0441\u0435\u0431\u044f --&gt;\n&lt;video autoplay id=&quot;videoObjectHtml5ApiServer&quot;&gt;&lt;\/video&gt;\n\n&lt;script type=&quot;application\/javascript&quot;&gt;\n  var\n        video = document.getElementById(&#039;videoObjectHtml5ApiServer&#039;);\n\n\/\/ \u0435\u0441\u043b\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d MediaDevices API, \u043f\u044b\u0442\u0430\u0435\u043c\u0441\u044f \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u043a\u0430\u043c\u0435\u0440\u0435 (\u043c\u043e\u0436\u043d\u043e \u0435\u0449\u0435 \u0438 \u043a \u043c\u0438\u043a\u0440\u043e\u0444\u043e\u043d\u0443)\n\/\/ getUserMedia \u0432\u0435\u0440\u043d\u0435\u0442 \u043e\u0431\u0435\u0449\u0430\u043d\u0438\u0435, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u043e\u0434\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c\u0441\u044f \u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u0432\u0438\u0434\u0435\u043e\u043f\u043e\u0442\u043e\u043a \u0432 \u043a\u043e\u043b\u0431\u0435\u043a\u0435 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0432 video \u043e\u0431\u044a\u0435\u043a\u0442 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435\n\nif (navigator.mediaDevices.getUserMedia) {\n        navigator.mediaDevices.getUserMedia({video: true}).then(function (stream) {\n          \/\/ \u0432\u0438\u0434\u0435\u043e \u043f\u043e\u0442\u043e\u043a \u043f\u0440\u0438\u0432\u044f\u0437\u044b\u0432\u0430\u0435\u043c \u043a video \u0442\u0435\u0433\u0443, \u0447\u0442\u043e\u0431\u044b \u043a\u043b\u0438\u0435\u043d\u0442 \u043c\u043e\u0433 \u0432\u0438\u0434\u0435\u0442\u044c \u0441\u0435\u0431\u044f \u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \n          video.srcObject = s;\n          var\n            recorderOptions = {\n                mimeType: &#039;video\/webm; codecs=vp8&#039; \/\/ \u0431\u0443\u0434\u0435\u043c \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u0438\u0434\u0435\u043e\u043f\u043e\u0442\u043e\u043a \u0432 \u0444\u043e\u0440\u043c\u0430\u0442 webm \u043a\u043e\u0434\u0435\u043a\u043e\u043c vp8\n              },\n              mediaRecorder = new MediaRecorder(s, recorderOptions ); \/\/ \u043e\u0431\u044a\u0435\u043a\u0442 MediaRecorder\n\n               mediaRecorder.ondataavailable = function(e) {\n                if (e.data &amp;&amp; e.data.size &gt; 0) {\n                  \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043a\u0443\u0441\u043e\u0447\u0435\u043a \u0432\u0438\u0434\u0435\u043e\u043f\u043e\u0442\u043e\u043a\u0430 \u0432 e.data\n                }\n            }\n\n            mediaRecorder.start(100); \/\/ \u0434\u0435\u043b\u0438\u0442 \u043f\u043e\u0442\u043e\u043a \u043d\u0430 \u043a\u0443\u0441\u043e\u0447\u043a\u0438 \u043f\u043e 100 \u043c\u0441 \u043a\u0430\u0436\u0434\u044b\u0439\n\n        });\n}\n&lt;\/script&gt;\n<\/code><\/pre>\n<p>Tani, le t'i shtojm\u00eb d\u00ebrgimin p\u00ebrmes websockets. Si\u00e7 \u00ebsht\u00eb e habitshme, p\u00ebr k\u00ebt\u00eb nevojitet vet\u00ebm nj\u00eb objekt <noindex><a rel=\"nofollow\" href=\"https:\/\/developer.mozilla.org\/ru\/docs\/Web\/API\/WebSocket\">WebSocket<\/a><\/noindex>. Ka vet\u00ebm dy metoda send dhe close. Emrat flasin p\u00ebr veten. Kodi i plot\u00ebsuar:<\/p>\n<p>                        <b class=\"spoiler_title\">D\u00ebrgojm\u00eb rrjedh\u00ebn video n\u00eb server<\/b><\/p>\n<pre><code class=\"javascript\">&lt;style&gt;\n  #videoObjectHtml5ApiServer { width: 320px; height: 240px; background: #666; }\n&lt;\/style&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n&lt;!-- \u0417\u0434\u0435\u0441\u044c \u0432 \u044d\u0442\u043e\u043c &quot;\u043e\u043a\u043e\u0448\u0435\u0447\u043a\u0435&quot; \u043a\u043b\u0438\u0435\u043d\u0442 \u0431\u0443\u0434\u0435\u0442 \u0432\u0438\u0434\u0435\u0442\u044c \u0441\u0435\u0431\u044f --&gt;\n&lt;video autoplay id=&quot;videoObjectHtml5ApiServer&quot;&gt;&lt;\/video&gt;\n\n&lt;script type=&quot;application\/javascript&quot;&gt;\n  var\n        video = document.getElementById(&#039;videoObjectHtml5ApiServer&#039;);\n\n\/\/ \u0435\u0441\u043b\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d MediaDevices API, \u043f\u044b\u0442\u0430\u0435\u043c\u0441\u044f \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u043a\u0430\u043c\u0435\u0440\u0435 (\u043c\u043e\u0436\u043d\u043e \u0435\u0449\u0435 \u0438 \u043a \u043c\u0438\u043a\u0440\u043e\u0444\u043e\u043d\u0443)\n\/\/ getUserMedia \u0432\u0435\u0440\u043d\u0435\u0442 \u043e\u0431\u0435\u0449\u0430\u043d\u0438\u0435, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u043e\u0434\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c\u0441\u044f \u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u0432\u0438\u0434\u0435\u043e\u043f\u043e\u0442\u043e\u043a \u0432 \u043a\u043e\u043b\u0431\u0435\u043a\u0435 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0432 video \u043e\u0431\u044a\u0435\u043a\u0442 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435\n\nif (navigator.mediaDevices.getUserMedia) {\n        navigator.mediaDevices.getUserMedia({video: true}).then(function (stream) {\n          \/\/ \u0432\u0438\u0434\u0435\u043e \u043f\u043e\u0442\u043e\u043a \u043f\u0440\u0438\u0432\u044f\u0437\u044b\u0432\u0430\u0435\u043c \u043a video \u0442\u0435\u0433\u0443, \u0447\u0442\u043e\u0431\u044b \u043a\u043b\u0438\u0435\u043d\u0442 \u043c\u043e\u0433 \u0432\u0438\u0434\u0435\u0442\u044c \u0441\u0435\u0431\u044f \u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \n          video.srcObject = s;\n          var\n            recorderOptions = {\n                mimeType: &#039;video\/webm; codecs=vp8&#039; \/\/ \u0431\u0443\u0434\u0435\u043c \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u0438\u0434\u0435\u043e\u043f\u043e\u0442\u043e\u043a \u0432 \u0444\u043e\u0440\u043c\u0430\u0442 webm \u043a\u043e\u0434\u0435\u043a\u043e\u043c vp8\n              },\n              mediaRecorder = new MediaRecorder(s, recorderOptions ), \/\/ \u043e\u0431\u044a\u0435\u043a\u0442 MediaRecorder\n              socket = new WebSocket(&#039;ws:\/\/127.0.0.1:3000\/ws&#039;);\n\n               mediaRecorder.ondataavailable = function(e) {\n                if (e.data &amp;&amp; e.data.size &gt; 0) {\n                  \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043a\u0443\u0441\u043e\u0447\u0435\u043a \u0432\u0438\u0434\u0435\u043e\u043f\u043e\u0442\u043e\u043a\u0430 \u0432 e.data\n                 socket.send(e.data);\n                }\n            }\n\n            mediaRecorder.start(100); \/\/ \u0434\u0435\u043b\u0438\u0442 \u043f\u043e\u0442\u043e\u043a \u043d\u0430 \u043a\u0443\u0441\u043e\u0447\u043a\u0438 \u043f\u043e 100 \u043c\u0441 \u043a\u0430\u0436\u0434\u044b\u0439\n\n        }).catch(function (err) { console.log(err); });\n}\n&lt;\/script&gt;\n<\/code><\/pre>\n<p>Oseja transmetuese \u00ebsht\u00eb gati! Tani le t\u00eb provojm\u00eb t\u00eb marrim videoprodhimin dhe ta shfaqim at\u00eb n\u00eb klient. \u00c7far\u00eb na nevojitet p\u00ebr k\u00ebt\u00eb? S\u00eb pari, natyrisht, lidhja me soket. Ne vendosim nj\u00eb \"d\u00ebgjues\" (listener) mbi objektin WebSocket dhe regjistrohemi p\u00ebr ngjarjen 'message'. Pas marrjes s\u00eb nj\u00eb cop\u00eb binar\u00ebsh, serveri yn\u00eb transmeton ato te abonent\u00ebt e tij, dmth te klient\u00ebt. N\u00eb an\u00ebn e klientit, funksioni i kthimit (callback) aktivizohet i lidhur me \"d\u00ebgjuesin\" e ngjarjes 'message', dhe si argument t\u00eb funksionit i jepet vet\u00eb objekti - cop\u00ebza e videoprodhimit, e koduar me vp8. <\/p>\n<p>                        <b class=\"spoiler_title\">Pranojm\u00eb rrjedh\u00ebn video<\/b><\/p>\n<pre><code class=\"javascript\">&lt;style&gt;\n  #videoObjectHtml5ApiServer { width: 320px; height: 240px; background: #666; }\n&lt;\/style&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n&lt;!-- \u0417\u0434\u0435\u0441\u044c \u0432 \u044d\u0442\u043e\u043c &quot;\u043e\u043a\u043e\u0448\u0435\u0447\u043a\u0435&quot; \u043a\u043b\u0438\u0435\u043d\u0442 \u0431\u0443\u0434\u0435\u0442 \u0432\u0438\u0434\u0435\u0442\u044c \u0442\u0435\u0431\u044f --&gt;\n&lt;video autoplay id=&quot;videoObjectHtml5ApiServer&quot;&gt;&lt;\/video&gt;\n\n&lt;script type=&quot;application\/javascript&quot;&gt;\n  var\n        video = document.getElementById(&#039;videoObjectHtml5ApiServer&#039;),\n         socket = new WebSocket(&#039;ws:\/\/127.0.0.1:3000\/ws&#039;), \n         arrayOfBlobs = [];\n\n         socket.addEventListener(&#039;message&#039;, function (event) {\n                \/\/ &quot;\u043a\u043b\u0430\u0434\u0435\u043c&quot; \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u043a\u0443\u0441\u043e\u0447\u0435\u043a \u0432 \u043c\u0430\u0441\u0441\u0438\u0432 \n                arrayOfBlobs.push(event.data);\n                \/\/ \u0437\u0434\u0435\u0441\u044c \u0431\u0443\u0434\u0435\u043c \u0447\u0438\u0442\u0430\u0442\u044c \u043a\u0443\u0441\u043e\u0447\u043a\u0438\n                readChunk();\n            });\n&lt;\/script&gt;\n<\/code><\/pre>\n<p>Kam kaluar nj\u00eb koh\u00eb t\u00eb gjat\u00eb duke u p\u00ebrpjekur t\u00eb kuptoj pse blloqet e marra nuk mund t\u00eb d\u00ebrgohen direkt p\u00ebr t'u luajtur nga elementi video, por duket se k\u00ebshtu nuk mund t\u00eb ndodh\u00eb, duhet s\u00eb pari ta vendos\u00ebsh bllokun n\u00eb nj\u00eb buffer t\u00eb ve\u00e7ant\u00eb t\u00eb lidhur me elementin video, dhe vet\u00ebm at\u00ebher\u00eb do t\u00eb filloj\u00eb t\u00eb luaj\u00eb rrjedh\u00ebn video. P\u00ebr k\u00ebt\u00eb do t\u00eb na nevojitet <noindex><a rel=\"nofollow\" href=\"https:\/\/developer.mozilla.org\/ru\/docs\/Web\/API\/MediaSource\">MediaSource API<\/a><\/noindex> dhe <noindex><a rel=\"nofollow\" href=\"https:\/\/developer.mozilla.org\/ru\/docs\/Web\/API\/FileReader\">FileReader API<\/a><\/noindex>.<\/p>\n<p>MediaSource vepron si nj\u00eb nd\u00ebrmjet\u00ebs midis objektit t\u00eb riprodhimit t\u00eb medias dhe burimit t\u00eb k\u00ebtij rrjedhje media. Objekti MediaSource p\u00ebrmban nj\u00eb bufer t\u00eb lidhsh\u00ebm p\u00ebr burimin e rrjedh\u00ebs video\/audio. Nj\u00eb ve\u00e7ori \u00ebsht\u00eb se buferi mund t\u00eb p\u00ebrmbaj\u00eb vet\u00ebm t\u00eb dh\u00ebna t\u00eb tipit Uint8, prandaj p\u00ebr t\u00eb krijuar nj\u00eb bufer t\u00eb till\u00eb do t\u00eb nevojitet FileReader. Shikoni kodin, dhe do t\u00eb kuptoni m\u00eb qart\u00eb:<\/p>\n<p>                        <b class=\"spoiler_title\">Riprodho rrjedh\u00ebn video<\/b><\/p>\n<pre><code class=\"javascript\">&lt;style&gt;\n  #videoObjectHtml5ApiServer { width: 320px; height: 240px; background: #666; }\n&lt;\/style&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n&lt;!-- \u0417\u0434\u0435\u0441\u044c \u0432 \u044d\u0442\u043e\u043c &quot;\u043e\u043a\u043e\u0448\u0435\u0447\u043a\u0435&quot; \u043a\u043b\u0438\u0435\u043d\u0442 \u0431\u0443\u0434\u0435\u0442 \u0432\u0438\u0434\u0435\u0442\u044c \u0442\u0435\u0431\u044f --&gt;\n&lt;video autoplay id=&quot;videoObjectHtml5ApiServer&quot;&gt;&lt;\/video&gt;\n\n&lt;script type=&quot;application\/javascript&quot;&gt;\n  var\n        video = document.getElementById(&#039;videoObjectHtml5ApiServer&#039;),\n         socket = new WebSocket(&#039;ws:\/\/127.0.0.1:3000\/ws&#039;),\n        mediaSource = new MediaSource(), \/\/ \u043e\u0431\u044a\u0435\u043a\u0442 MediaSource\n        vid2url = URL.createObjectURL(mediaSource), \/\/ \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043e\u0431\u044a\u0435\u043a\u0442 URL \u0434\u043b\u044f \u0441\u0432\u044f\u0437\u044b\u0432\u0430\u043d\u0438\u044f \u0432\u0438\u0434\u0435\u043e\u043f\u043e\u0442\u043e\u043a\u0430 \u0441 \u043f\u0440\u043e\u0438\u0433\u0440\u044b\u0432\u0430\u0442\u0435\u043b\u0435\u043c\n        arrayOfBlobs = [],\n        sourceBuffer = null; \/\/ \u0431\u0443\u0444\u0435\u0440, \u043f\u043e\u043a\u0430 \u043d\u0443\u043b\u044c-\u043e\u0431\u044a\u0435\u043a\u0442\n\n         socket.addEventListener(&#039;message&#039;, function (event) {\n                \/\/ &quot;\u043a\u043b\u0430\u0434\u0435\u043c&quot; \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u043a\u0443\u0441\u043e\u0447\u0435\u043a \u0432 \u043c\u0430\u0441\u0441\u0438\u0432 \n                arrayOfBlobs.push(event.data);\n                \/\/ \u0437\u0434\u0435\u0441\u044c \u0431\u0443\u0434\u0435\u043c \u0447\u0438\u0442\u0430\u0442\u044c \u043a\u0443\u0441\u043e\u0447\u043a\u0438\n                readChunk();\n            });\n\n         \/\/ \u043a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e MediaSource \u0431\u0443\u0434\u0435\u0442 \u043e\u043f\u043e\u0432\u0435\u0449\u0435\u043d , \u0447\u0442\u043e \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0433\u043e\u0442\u043e\u0432 \u043e\u0442\u0434\u0430\u0432\u0430\u0442\u044c \u043a\u0443\u0441\u043e\u0447\u043a\u0438 \n        \/\/ \u0432\u0438\u0434\u0435\u043e\/\u0430\u0443\u0434\u0438\u043e \u043f\u043e\u0442\u043e\u043a\u0430\n        \/\/ \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0431\u0443\u0444\u0435\u0440 , \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0431\u0443\u0444\u0435\u0440 \u0434\u043e\u043b\u0436\u0435\u043d \u0437\u043d\u0430\u0442\u044c \u0432 \u043a\u0430\u043a\u043e\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u0435 \n        \/\/ \u043a\u0430\u043a\u0438\u043c \u043a\u043e\u0434\u0435\u043a\u043e\u043c \u0431\u044b\u043b \u0437\u0430\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d \u043f\u043e\u0442\u043e\u043a, \u0447\u0442\u043e\u0431\u044b \u0442\u0435\u043c \u0436\u0435 \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0432\u0438\u0434\u0435\u043e\u043f\u043e\u0442\u043e\u043a\n         mediaSource.addEventListener(&#039;sourceopen&#039;, function() {\n            var mediaSource = this;\n            sourceBuffer = mediaSource.addSourceBuffer(&quot;video\/webm; codecs=&quot;vp8&quot;&quot;);\n        });\n\n      function readChunk() {\n        var reader = new FileReader();\n        reader.onload = function(e) { \n          \/\/ \u043a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e FileReader \u0431\u0443\u0434\u0435\u0442 \u0433\u043e\u0442\u043e\u0432, \u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442 \u0441\u0435\u0431\u0435 \u043a\u0443\u0441\u043e\u0447\u0435\u043a \u0432\u0438\u0434\u0435\u043e\u043f\u043e\u0442\u043e\u043a\u0430\n          \/\/ \u043c\u044b &quot;\u043f\u0440\u0438\u0446\u0435\u043f\u043b\u044f\u0435\u043c&quot; \u043f\u0435\u0440\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0432 Uint8Array (\u0431\u044b\u043b Blob) \u043a\u0443\u0441\u043e\u0447\u0435\u043a \u0432 \u0431\u0443\u0444\u0435\u0440, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0439\n          \/\/ \u0441 \u043f\u0440\u043e\u0438\u0433\u0440\u044b\u0432\u0430\u0442\u0435\u043b\u0435\u043c, \u0438 \u043f\u0440\u043e\u0438\u0433\u0440\u044b\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u044c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u043a\u0443\u0441\u043e\u0447\u0435\u043a \u0432\u0438\u0434\u0435\u043e\/\u0430\u0443\u0434\u0438\u043e\n          sourceBuffer.appendBuffer(new Uint8Array(e.target.result));\n\n          reader.onload = null;\n        }\n        reader.readAsArrayBuffer(arrayOfBlobs.shift());\n      }\n&lt;\/script&gt;\n<\/code><\/pre>\n<p>Prototipi i sh\u00ebrbimit t\u00eb transmetimit \u00ebsht\u00eb gati. Dob\u00ebsia kryesore \u00ebsht\u00eb se riprodhimi i videos do t\u00eb ka nj\u00eb vones\u00eb prej 100 ms nga pala e transmetimit, k\u00ebt\u00eb e kemi vendosur ne vet\u00eb duke ndar\u00eb rrjedh\u00ebn video para se ta d\u00ebrgojm\u00eb n\u00eb server. M\u00eb tej, kur e verifikoja n\u00eb laptopin tim, fillova t\u00eb p\u00ebrjetoj nj\u00eb vones\u00eb n\u00eb rritje midis pal\u00ebs q\u00eb transmeton dhe asaj q\u00eb pranon, ishte shum\u00eb e dukshme. Fillova t\u00eb k\u00ebrkoj m\u00ebnyra p\u00ebr t\u00eb p\u00ebrballuar k\u00ebt\u00eb disavantazh dhe\u2026 p\u00ebrfundova n\u00eb <noindex><a rel=\"nofollow\" href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/RTCPeerConnection\">RTCPeerConnection API<\/a><\/noindex>, i cili lejon d\u00ebrgimin e rrjedh\u00ebs video pa mashtresa t\u00eb tilla si ndarja e rrjedh\u00ebs n\u00eb cop\u00ebza. Vonesa e akumuluar, mendoj, ndodh p\u00ebr shkak se n\u00eb shfletues para d\u00ebrgimit ndodh rikodimi i \u00e7do cop\u00ebze n\u00eb formatin webm. Nuk vazhdova m\u00eb tej me hulumtimin, por fillova t\u00eb studioj WebRTC, dhe mendoj se do t\u00eb shkruaj nj\u00eb artikull t\u00eb ve\u00e7ant\u00eb p\u00ebr rezultatet e hulumtimeve t\u00eb mia, n\u00ebse e gjykoj t\u00eb till\u00eb t\u00ebrheq\u00ebse p\u00ebr komunitetin.<br \/>\n<br \/>Burimi: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/461769\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0445\u043e\u0447\u0443 \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0441\u0432\u043e\u0438\u043c\u0438 \u043f\u043e\u043f\u044b\u0442\u043a\u0430\u043c\u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0442\u0440\u0438\u043c\u043c\u0438\u043d\u0433 \u0432\u0438\u0434\u0435\u043e \u0447\u0435\u0440\u0435\u0437 websockets \u0431\u0435\u0437 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0445 \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430 \u0442\u0438\u043f\u0430 Adobe Flash Player. \u0427\u0442\u043e \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0447\u0438\u0442\u0430\u0439\u0442\u0435 \u0434\u0430\u043b\u0435\u0435. Adobe Flash \u2014 \u0440\u0430\u043d\u0435\u0435 Macromedia Flash, \u044d\u0442\u043e \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0430 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439, \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0438\u0445 \u0432 \u0432\u0435\u0431-\u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435. \u0414\u043e \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u044f Media Stream API \u044d\u0442\u043e \u0431\u044b\u043b\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u0430\u044f \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0430 \u0434\u043b\u044f \u0441\u0442\u0440\u0438\u043c\u043c\u0438\u043d\u0433\u0430 \u0441 \u0432\u0435\u0431-\u043a\u0430\u043c\u0435\u0440\u044b [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-94138","post","type-post","status-publish","format-standard","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.0.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0445\u043e\u0447\u0443 \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0441\u0432\u043e\u0438\u043c\u0438 \u043f\u043e\u043f\u044b\u0442\u043a\u0430\u043c\u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0442\u0440\u0438\u043c\u043c\u0438\u043d\u0433 \u0432\u0438\u0434\u0435\u043e \u0447\u0435\u0440\u0435\u0437 websockets \u0431\u0435\u0437 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0445 \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430 \u0442\u0438\u043f\u0430 Adobe Flash Player.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/sq\/blog\/administrirovanie\/pochti-bespoleznyj-striming-vebkamery-iz-brauzera-media-stream-i-websockets\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.0.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"sq_AL\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47(\u041f\u043e\u0447\u0442\u0438) \u0431\u0435\u0441\u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0439 \u0441\u0442\u0440\u0438\u043c\u0438\u043d\u0433 \u0432\u0435\u0431\u043a\u0430\u043c\u0435\u0440\u044b \u0438\u0437 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430. Media Stream \u0438 Websockets | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0445\u043e\u0447\u0443 \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0441\u0432\u043e\u0438\u043c\u0438 \u043f\u043e\u043f\u044b\u0442\u043a\u0430\u043c\u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0442\u0440\u0438\u043c\u043c\u0438\u043d\u0433 \u0432\u0438\u0434\u0435\u043e \u0447\u0435\u0440\u0435\u0437 websockets \u0431\u0435\u0437 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0445 \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430 \u0442\u0438\u043f\u0430 Adobe Flash Player.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/sq\/blog\/administrirovanie\/pochti-bespoleznyj-striming-vebkamery-iz-brauzera-media-stream-i-websockets\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-09-13T05:42:42+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-09-13T05:42:42+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47(Gati) transmetim i pafavorsh\u00ebm i kamer\u00ebs nga shfletuesi. Media Stream dhe Websockets | ProHoster","description":"N\u00eb k\u00ebt\u00eb artikull dua t\u00eb ndaja p\u00ebrpjekjet e mia p\u00ebr t\u00eb realizuar transmetimin e videove p\u00ebrmes websockets pa p\u00ebrdorimin e shtesave t\u00eb jashtme t\u00eb shfletuesit si Adobe Flash Player.","canonical_url":"https:\/\/prohoster.info\/sq\/blog\/administrirovanie\/pochti-bespoleznyj-striming-vebkamery-iz-brauzera-media-stream-i-websockets","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"sq_AL","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47(\u041f\u043e\u0447\u0442\u0438) \u0431\u0435\u0441\u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0439 \u0441\u0442\u0440\u0438\u043c\u0438\u043d\u0433 \u0432\u0435\u0431\u043a\u0430\u043c\u0435\u0440\u044b \u0438\u0437 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430. Media Stream \u0438 Websockets | ProHoster","og:description":"\u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0445\u043e\u0447\u0443 \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0441\u0432\u043e\u0438\u043c\u0438 \u043f\u043e\u043f\u044b\u0442\u043a\u0430\u043c\u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0442\u0440\u0438\u043c\u043c\u0438\u043d\u0433 \u0432\u0438\u0434\u0435\u043e \u0447\u0435\u0440\u0435\u0437 websockets \u0431\u0435\u0437 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0445 \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430 \u0442\u0438\u043f\u0430 Adobe Flash Player.","og:url":"https:\/\/prohoster.info\/sq\/blog\/administrirovanie\/pochti-bespoleznyj-striming-vebkamery-iz-brauzera-media-stream-i-websockets","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-09-13T05:42:42+00:00","article:modified_time":"2020-09-13T05:42:42+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"94138","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 11:32:23","updated":"2022-10-01 11:18:30","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/posts\/94138","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/comments?post=94138"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/posts\/94138\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/media?parent=94138"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/categories?post=94138"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/tags?post=94138"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}