Yn yr erthygl hon, hoffwn rannu fy ymdrechion i ffrydio fideo drwy websockets heb ddefnyddio ategion porwr trydydd parti fel Adobe Flash Player. Darllenwch ymlaen i weld y canlyniadau.
Mae Adobe FlashβMacromedia Flash gyntβyn blatfform ar gyfer creu cymwysiadau sy'n rhedeg mewn porwr gwe. Cyn cyflwyno'r Media Stream API, hwn oedd bron yr unig blatfform ar gyfer ffrydio fideo a llais o we-gamera, yn ogystal ag ar gyfer creu gwahanol fathau o gynadleddau a sgyrsiau yn y porwr. Roedd y protocol ar gyfer trosglwyddo gwybodaeth cyfryngau, RTMP (Real Time Messaging Protocol), ar gau i bob pwrpas am amser hir, sy'n golygu os ydych chi am lansio eich gwasanaeth ffrydio eich hun, byddai'n well i chi ddefnyddio meddalwedd Adobe ei hun, Adobe Media Server (AMS).
Ar Γ΄l peth amser yn 2012, "rhoddodd Adobe y gorau iddi a'i cheisio ei daflu allan" i'r cyhoedd. Ni chafodd y protocol RTMP, a oedd yn cynnwys bygiau ac yn anghyflawn i bob pwrpas, ei weithredu'n llawn. Erbyn hynny, roedd datblygwyr wedi dechrau creu eu gweithrediadau eu hunain o'r protocol, ac felly ganwyd gweinydd Wowza. Yn 2011, ffeiliodd Adobe achos cyfreithiol yn erbyn Wowza am ddefnyddio patentau cysylltiedig ag RTMP yn anghyfreithlon; datryswyd yr anghydfod yn gyfeillgar bedair blynedd yn ddiweddarach.
Mae platfform Adobe Flash yn fwy nag 20 mlwydd oed, ac yn ystod y cyfnod hwnnw mae llawer o wendidau critigol wedi'u darganfod, cefnogaeth bydd yn peidio Γ’ bodoli erbyn 2020, gan adael ychydig o ddewisiadau eraill ar gyfer y gwasanaeth ffrydio.
Ar gyfer fy mhrosiect, penderfynais ar unwaith roi'r gorau i Flash yn y porwr yn llwyr. Soniais am y prif reswm uchod, ond nid yw Flash yn cael ei gefnogi o gwbl ar lwyfannau symudol, ac roedd defnyddio Adobe Flash ar gyfer datblygu ar Windows (gan ddefnyddio'r efelychydd Wine) yn bendant yn annymunol. Felly, penderfynais ysgrifennu cleient yn JavaScript. Dim ond prototeip fydd hwn, gan i mi ddysgu'n ddiweddarach y gellir ffrydio'n llawer mwy effeithlon gan ddefnyddio cyfoedion-i-gyfoedion (P2P), er yn fy achos i, bydd yn gyfoedion-gweinydd-cyfoedion. Ond mae honno'n stori ar gyfer amser arall, gan nad yw'n barod eto.
I ddechrau, mae angen gweinydd websockets arnom. Adeiladais un syml gan ddefnyddio'r pecyn melody go:
Cod ochr y gweinydd
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)
}
Ar y cleient (ochr y darlledu), mae angen i chi gael mynediad i'r camera yn gyntaf. Gwneir hyn drwy .
Rydym yn cael mynediad (caniatΓ’d) i'r camera/meicroffon drwy Mae'r API hwn yn darparu dull , sy'n dangos ffenestr naidlen yn gofyn i'r defnyddiwr am ganiatΓ’d i gael mynediad i'r camera a/neu'r meicroffon. Hoffwn nodi fy mod i wedi cynnal fy holl arbrofion yn Google Chrome, ond rwy'n credu y bydd yn gweithio'n debyg yn Firefox.
Nesaf, mae getUserMedia() yn dychwelyd Addewid, gan basio gwrthrych MediaStream iddoβffrwd o ddata fideo ac sain. Rydym yn aseinio'r gwrthrych hwn i'r eiddo src o'r elfen fideo. Cod:
Ochr ddarlledu
<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>
I ddarlledu ffrwd fideo dros socedi, mae angen ei amgodio, ei glustogi, a'i drosglwyddo mewn darnau. Ni ellir trosglwyddo ffrwd fideo amrwd dros websockets. Dyma lle mae websockets yn dod i'r adwy. Mae'r API hwn yn caniatΓ‘u ichi amgodio a rhannu nant yn ddarnau. Rwy'n amgodio i gywasgu'r nant fideo, gan leihau nifer y beitiau a anfonir dros y rhwydwaith. Ar Γ΄l ei rannu'n ddarnau, gellir anfon pob darn i soced gwe. Y cod:
Rydym yn amgodio'r ffrwd fideo ac yn ei rhannu'n rhannau
<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>
Nawr gadewch i ni ychwanegu trosglwyddiad websockets. Yn syndod, y cyfan sydd ei angen arnoch chi yw gwrthrych. Dim ond dau ddull sydd ganddo: anfon a chau. Mae'r enwau'n siarad drostynt eu hunain. Y cod atodedig:
Rydym yn trosglwyddo'r ffrwd fideo i'r gweinydd
<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>
Mae'r ochr ddarlledu yn barod! Nawr, gadewch i ni geisio derbyn ffrwd fideo a'i harddangos ar y cleient. Beth sydd ei angen arnom ar gyfer hyn? Yn gyntaf, wrth gwrs, cysylltiad soced. Rydym yn cysylltu gwrandΓ€wr Γ’'r gwrthrych WebSocket ac yn tanysgrifio i'r digwyddiad 'neges'. Ar Γ΄l derbyn darn o ddata deuaidd, mae ein gweinydd yn ei ddarlledu i danysgrifwyr, hynny yw, cleientiaid. Ar y cleient, mae swyddogaeth galw'n Γ΄l sy'n gysylltiedig Γ’'r gwrandΓ€wr 'neges' yn cael ei sbarduno, a dadl y swyddogaeth yw'r gwrthrych gwirioneddolβy darn o ffrwd fideo wedi'i amgodio gan VP8.
Rydym yn derbyn ffrydio fideo.
<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>
Treuliais amser hir yn ceisio darganfod pam na allwn anfon y darnau a dderbyniwyd ar unwaith i'r elfen fideo i'w chwarae, ond daeth i'r amlwg nad yw hyn yn bosibl o gwbl. Yn gyntaf mae angen i chi roi'r darn mewn byffer arbennig sydd wedi'i rwymo i'r elfen fideo, a dim ond wedyn y bydd y ffrwd fideo yn dechrau chwarae. I wneud hyn, bydd angen i chi ΠΈ .
Mae'r MediaSource yn gweithredu fel cyfryngwr rhwng y gwrthrych chwarae cyfryngau a ffynhonnell y ffrwd cyfryngau. Mae'r gwrthrych MediaSource yn cynnwys byffer plygadwy ar gyfer y ffrwd fideo/sain ffynhonnell. Un peth rhyfedd yw mai dim ond data Uint8 y gall y byffer ei gynnwys, felly mae angen FileReader i greu byffer o'r fath. Bydd edrych ar y cod yn gwneud pethau'n gliriach:
Chwarae ffrydiau fideo
<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>
Mae prototeip y gwasanaeth ffrydio yn barod. Y prif anfantais yw y bydd chwarae fideo yn llusgo ar ôl yr ochr drosglwyddo o 100 ms, a osodwyd gennym ni ein hunain wrth rannu'r ffrwd fideo cyn ei throsglwyddo i'r gweinydd. Ar ben hynny, pan brofais ef ar fy ngliniadur, profais oedi yn raddol rhwng yr ochrau trosglwyddo a derbyn, a oedd yn weladwy'n glir. Dechreuais chwilio am ffyrdd o oresgyn yr anfantais hon, a⦠des i ar draws , sy'n caniatÑu ffrydio fideo heb driciau fel rhannu'r nant yn ddarnau. Mae'r oedi cronnus, rwy'n credu, oherwydd bod y porwr yn trawsgodio pob darn i fformat WebM cyn ei drosglwyddo. Fe wnes i roi'r gorau i gloddio ymhellach a dechrau astudio WebRTC. Rwy'n bwriadu ysgrifennu erthygl ar wahÒn am ganlyniadau fy ymchwil os byddaf yn ei chael hi'n ddiddorol i'r gymuned.
Ffynhonnell: hab.com
