国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

websocket+node實(shí)現(xiàn)直播(弱雞版)

這篇具有很好參考價(jià)值的文章主要介紹了websocket+node實(shí)現(xiàn)直播(弱雞版)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

心血?dú)v程

這部分主要是寫在寫這些的時(shí)候遇到的問題以及換思路的過程,可以之間看正文
在之前我也寫過直播功能,并且與websocket相結(jié)合實(shí)現(xiàn)了直播彈幕。只不過直播是使用的騰訊云的,而不是手寫的直播推流拉流,這次又有一個(gè)新的項(xiàng)目,和直播息息相關(guān)(直播自習(xí)平臺(tái)),所以就想著使用原生的寫直播推流、拉流,搞了兩天,實(shí)現(xiàn)了一個(gè)基礎(chǔ)版本的直播。
這兩天搞直播也挺難受的,原本我和后端想的和之前寫項(xiàng)目一樣,一個(gè)拉流地址,一個(gè)推流地址,不過后端寫好之后也用軟件測(cè)試了一下可行,興高采烈的給我說寫好了,既然后端接口寫好了,剩下的就是前端去交互了,經(jīng)過一段時(shí)間的交互,拉流報(bào)錯(cuò),推流也報(bào)錯(cuò),經(jīng)過一番百度原來是瀏覽器不支持rtmp協(xié)議,只能另尋它法,最后想到使用websocket去連接,我把采集到的音視頻流數(shù)據(jù)傳輸給后端,后端在傳輸給我,我再統(tǒng)一處理,寫好之后發(fā)現(xiàn)了一個(gè)小問題就是每次推流與拉流之間都會(huì)閃一下,原本想著使用mediaSource視頻流去搞一下,不過最后發(fā)現(xiàn)視頻格式對(duì)于不同瀏覽器的要求是不一樣的,而且瀏覽器對(duì)于視頻格式要求也比較嚴(yán),最后就不搞了。經(jīng)過與后端的商量,最終決定項(xiàng)目中寫兩版直播,一版是原生寫的,一版是使用騰訊云直播寫的。下面就進(jìn)入正文吧。

直播常見協(xié)議
  1. RTMP
    RTMP(Real-Time Messaging Protocol)是一種用于音頻、視頻和數(shù)據(jù)傳輸?shù)膮f(xié)議。它最初由Adobe開發(fā),用于在Flash播放器和媒體服務(wù)器之間進(jìn)行實(shí)時(shí)通信。RTMP通過建立持久的連接來傳輸流媒體數(shù)據(jù),支持實(shí)時(shí)的流媒體傳輸和即時(shí)通信。
  2. HTTP-FLV
    HTTP-FLV(HTTP-Flash Video)是一種基于HTTP協(xié)議的流媒體傳輸協(xié)議。它是由阿里巴巴開發(fā)的,用于在Web瀏覽器中播放Flash視頻。HTTP-FLV通過HTTP協(xié)議傳輸FLV(Flash Video)格式的視頻,可以實(shí)現(xiàn)低延遲的視頻直播和點(diǎn)播。
  3. HLS
    HLS(HTTP Live Streaming)是一種由蘋果公司開發(fā)的流媒體傳輸協(xié)議。它通過將視頻和音頻切片成小的TS(Transport Stream)文件,并使用HTTP協(xié)議傳輸這些文件,實(shí)現(xiàn)了在不同網(wǎng)絡(luò)環(huán)境下的自適應(yīng)流媒體傳輸。HLS支持多種編碼格式和分辨率的視頻,可以在iOS設(shè)備和Web瀏覽器上播放。
    總的來說RTMP是一種實(shí)時(shí)的流媒體傳輸協(xié)議,適用于實(shí)時(shí)通信和互動(dòng)性較高的應(yīng)用;HTTP-FLV是一種基于HTTP協(xié)議的低延遲流媒體傳輸協(xié)議,適用于Web瀏覽器中的Flash視頻播放;HLS是一種適用于不同網(wǎng)絡(luò)環(huán)境下的自適應(yīng)流媒體傳輸協(xié)議,適用于iOS設(shè)備和Web瀏覽器的播放。
    直播基本流程
    websocket+node實(shí)現(xiàn)直播(弱雞版),websocket,網(wǎng)絡(luò)協(xié)議,網(wǎng)絡(luò),前端,直播

看上圖可知直播分為以下三個(gè)步驟:

  1. 視頻/音頻采集(推流)
  2. 流媒體服務(wù)器(用于推流/拉流的中轉(zhuǎn)服務(wù)器)
  3. 播放(拉流)
    對(duì)于前端來說推流以及拉流都是我們所要操心的事,而后端要做的是中轉(zhuǎn)服務(wù)器作用
直播代碼

經(jīng)過以上的說明,大家對(duì)直播有了一個(gè)簡單的了解,那么我們之間上代碼
node端(需要下載ws第三方庫)

const WebSocket = require("ws");

const wss = new WebSocket.Server({
  port: 3000,
});

wss.on("connection", (ws) => {
  ws.on("message", (msg) => {
    wss.clients.forEach((ws) => {
      ws.send(msg);
    });
  });
});

node端我們做的很簡潔,就是把前端發(fā)給我們的數(shù)據(jù)再發(fā)給前端
那么就顯得數(shù)據(jù)很重要了,既然是直播那么我們的數(shù)據(jù)就是我們直播的數(shù)據(jù)(及視頻,音頻),另外需要補(bǔ)充兩點(diǎn)就是我們傳輸?shù)臄?shù)據(jù)一般比較大,websocket的傳輸雖然理論上是無限,但是為了不明顯的卡頓,我們前端傳輸數(shù)據(jù)采用分段上傳。另外就是為了保證數(shù)據(jù)的準(zhǔn)確,我們傳輸?shù)氖嵌M(jìn)制數(shù)據(jù),這樣就能保證了觀看與直播的相對(duì)無誤差。
在寫前端代碼之前,我來解釋一下為什么這個(gè)直播是弱雞版,我們實(shí)現(xiàn)的是推流是前端錄視頻一段時(shí)間之后發(fā)給后端,后端再轉(zhuǎn)接給前端,循環(huán)往復(fù),由此就實(shí)現(xiàn)了直播功能,這也是推流拉流時(shí)屏幕閃的原因。不過更多的是讓大家了解一下大致的流程,及一個(gè)可行的方法。
前端推流代碼

<!--用以預(yù)覽-->
    <video></video>

    <button onclick="onStartRecord()">開始共享</button>
    <button onclick="onDownload()">手動(dòng)推流</button>
    <button onclick="close()">關(guān)閉</button>
    <script>
        var socket = new WebSocket("ws://127.0.0.1:3000");
        socket.onopen = () => {
            console.log("WebSocket 連接成功");
        };
        socket.onclose = (event) => {
            console.log("WebSocket 連接關(guān)閉", event);
        };
        socket.onerror = (error) => {
            console.error("發(fā)生錯(cuò)誤", error);
        };
        socket.onmessage = (event) => {
            console.log("收到信息", event.data);
        };
        // 想要獲取一個(gè)最接近 1280x720 的相機(jī)分辨率
        var recordedChunks = [];
        var stream

        var onStartRecord = function () {
            navigator.mediaDevices
                .getDisplayMedia({
                    video: {
                        mediaSource: "screen",
                    },
                    audio: true
                })
                .then(async function (mediaStream) {
                    const audioTrack = await navigator.mediaDevices.getUserMedia({ audio: true });
                    // 添加聲音軌道
                    await mediaStream.addTrack(audioTrack.getAudioTracks()[0]);
                    var video = document.querySelector('video');
                  //本地預(yù)覽視頻
                    video.srcObject = mediaStream;
                    stream = mediaStream
                    video.onloadedmetadata = function (e) {
                        video.play();
                    };
                  //采集視頻
                    startRecord(mediaStream);
                })
                .catch(function (err) {
                    console.log(err.name + ': ' + err.message);
                }); // 總是在最后檢查錯(cuò)誤
        };

        var timer = null

        function startRecord(stream) {
            recordedChunks = []
            var options = { mimeType: 'video/webm; codecs=vp9' };
            mediaRecorder = new MediaRecorder(stream, options);

            mediaRecorder.ondataavailable = handleDataAvailable;
            mediaRecorder.start();
            clearInterval(timer)
          //每隔5秒自動(dòng)推流
            timer = setInterval(async () => {
                await onDownload()
                await startRecord(stream)
            }, 5000)
        }

        //onDownloadClick,調(diào)用stop會(huì)停止并會(huì)觸發(fā)ondataavailable,相應(yīng)下載邏輯在回調(diào)中完成
        var onDownload = function () {
            mediaRecorder.stop();
        };


        function handleDataAvailable(event) {
            if (event.data.size > 0) {
                recordedChunks.push(event.data);
                download();
            } else {
                // ...
            }
        }

        const CHUNK_SIZE = 1024 * 5; // 每個(gè)數(shù)據(jù)塊的大小為 16KB
      //分片上傳
        function sliceBlob(blob) {
            const chunks = [];
            let offset = 0;
            while (offset < blob.size) {
                const chunk = blob.slice(offset, offset + CHUNK_SIZE);
                chunks.push(chunk);
                offset += CHUNK_SIZE;
            }
            return chunks;
        }

        async function download() {
            var blob = new Blob(recordedChunks, {
                type: 'video/webm',
            });
            console.log(blob);
            const binaryChunks = sliceBlob(blob);
            for (const chunk of binaryChunks) {
                console.log(chunk);
                await socket.send(chunk);
            }
        }
      //關(guān)閉直播
        function close() {
            stream.getTracks().map((track) => track.stop());
        }

    </script>

前端拉流代碼

 <video src="" id="mv" controls></video>
    <script>
        const mv = document.getElementById('mv')
        var socket = new WebSocket("ws://127.0.0.1:3000");
        socket.onopen = () => {
            console.log("WebSocket 連接成功");
        };

        socket.onclose = (event) => {
            console.log("WebSocket 連接關(guān)閉", event);
        };

        socket.onerror = (error) => {
            console.error("WebSocket Error:", error);
        };
        let videoData = []
        socket.onmessage = async (event) => {
            if (event.data.size < 1024 * 5) {
              //合并數(shù)據(jù)進(jìn)行渲染
                const blob = new Blob(videoData, { type: 'video/webm' })
                mv.src = URL.createObjectURL(blob);
                videoData = []
                mv.play()
            } else {
                // 接收數(shù)據(jù)
                videoData.push(event.data)
            }
        }

    </script>

注意事項(xiàng):
我們使用blob時(shí)要指定格式,以此方便我們播放的時(shí)候?yàn)g覽器解碼

總結(jié)

之后遇到項(xiàng)目的問題再繼續(xù)分享吧。之后也正式開始寫項(xiàng)目了。我們一同進(jìn)步。文章來源地址http://www.zghlxwxcb.cn/news/detail-630907.html

到了這里,關(guān)于websocket+node實(shí)現(xiàn)直播(弱雞版)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 持久雙向通信網(wǎng)絡(luò)協(xié)議-WebSocket-入門案例實(shí)現(xiàn)demo

    持久雙向通信網(wǎng)絡(luò)協(xié)議-WebSocket-入門案例實(shí)現(xiàn)demo

    1 介紹 WebSocket 是基于 TCP 的一種新的 網(wǎng)絡(luò)協(xié)議 。它實(shí)現(xiàn)了瀏覽器與服務(wù)器全雙工通信——瀏覽器和服務(wù)器只需要完成一次握手,兩者之間就可以創(chuàng)建 持久性 的連接, 并進(jìn)行 雙向 數(shù)據(jù)傳輸。 HTTP協(xié)議和WebSocket協(xié)議對(duì)比: HTTP是 短連接 (一次響應(yīng)完即消除) WebSocket是 長連接

    2024年01月16日
    瀏覽(22)
  • 用 Node.js 手寫 WebSocket 協(xié)議

    用 Node.js 手寫 WebSocket 協(xié)議

    目錄 引言 從 http 到 websocekt 的切換 Sec-WebSocket-Key 與 Sec-WebSocket-Accept 全新的二進(jìn)制協(xié)議 自己實(shí)現(xiàn)一個(gè) websocket 服務(wù)器 按照協(xié)議格式解析收到的Buffer 取出opcode 取出MASK與payload長度 根據(jù)mask key讀取數(shù)據(jù) 根據(jù)類型處理數(shù)據(jù) frame 幀 數(shù)據(jù)的發(fā)送 完整代碼 總結(jié) ????????我們知道,

    2024年02月16日
    瀏覽(19)
  • [前端基礎(chǔ)]websocket協(xié)議

    [前端基礎(chǔ)]websocket協(xié)議

    (1)websocket websocket(簡寫為ws),是一種輕量化的協(xié)議,經(jīng)過最開始的握手階段以后,前后端之間允許自由地發(fā)送信息不受限制(建議發(fā)送json字符串).雖然理論上這個(gè)東西是屬于協(xié)議內(nèi)容,但是已經(jīng)被瘋狂封裝得像框架一樣了. websocket協(xié)議具有天然的優(yōu)勢(shì)處理前端多線程并發(fā),并且只需要一

    2024年02月08日
    瀏覽(17)
  • WebSocket 網(wǎng)絡(luò)協(xié)議(實(shí)時(shí)更新 )

    WebSocket 網(wǎng)絡(luò)協(xié)議(實(shí)時(shí)更新 )

    WebSocket 是一種在客戶端和服務(wù)器之間建立雙向通信信道的網(wǎng)絡(luò)協(xié)議。它在客戶端和服務(wù)器之間建立一個(gè)持久的、全雙工的連接,允許數(shù)據(jù)在兩個(gè)方向上實(shí)時(shí)傳輸,而不需要像HTTP一樣進(jìn)行多次請(qǐng)求和響應(yīng)。 ?WebSocket 的主要優(yōu)勢(shì)是減少了服務(wù)器和客戶端之間的通信延遲,因?yàn)閿?shù)

    2024年01月17日
    瀏覽(24)
  • 【spring(六)】WebSocket網(wǎng)絡(luò)傳輸協(xié)議

    【spring(六)】WebSocket網(wǎng)絡(luò)傳輸協(xié)議

    ??鍵盤敲爛,年薪30萬?? 目錄 核心概要: 概念介紹: 對(duì)比HTTP協(xié)議:? WebSocket入門案例:? websocket對(duì)比http ? ? ? ? WebSocket是Web服務(wù)器的一個(gè)組件,WebSocket是一種基于TCP的新的 網(wǎng)絡(luò)傳輸協(xié)議 ,它實(shí)現(xiàn)了瀏覽器與服務(wù)器全雙工通信——瀏覽器只需要完成 一次握手 ,兩者之

    2024年02月05日
    瀏覽(20)
  • 使用node實(shí)現(xiàn)websocket

    使用node實(shí)現(xiàn)websocket

    websocket 代表了 Web 應(yīng)用程序通信方式的根本轉(zhuǎn)變。不同于傳統(tǒng)的 HTTP 請(qǐng)求響應(yīng)周期,即客戶端從服務(wù)器請(qǐng)求數(shù)據(jù)并等待響應(yīng), websocket 在客戶端和服務(wù)器之間建立一個(gè)持久的全雙工連接。這意味著一旦建立了 websocket ,數(shù)據(jù)可以在任何時(shí)候雙向流動(dòng),而不需要重復(fù)請(qǐng)求。 Web

    2024年02月08日
    瀏覽(13)
  • Node.js實(shí)現(xiàn)WebSocket

    1、Http協(xié)議發(fā)布REST API 的不足: 每次請(qǐng)求響應(yīng)完成之后,服務(wù)器與客戶端之間的連接就斷開了,如果客戶端想要繼續(xù)獲取服務(wù)器的消息,必須再次向服務(wù)器發(fā)起請(qǐng) 求。這顯然無法適應(yīng)對(duì)實(shí)時(shí)通信有高要求的場(chǎng)景。 2、改善http的不足:Web通信領(lǐng)域出現(xiàn)了一些其他的解決方案,如

    2024年02月02日
    瀏覽(16)
  • 【websocket】Node+Vue2+WebSocket實(shí)現(xiàn)前后端通訊

    【websocket】Node+Vue2+WebSocket實(shí)現(xiàn)前后端通訊

    WebSocket是一個(gè)長連接,客戶端可以給服務(wù)端發(fā)送消息,服務(wù)端也可以給客戶端發(fā)送消息,是 全雙工通信。 平時(shí)的前后端分離項(xiàng)目,是前端請(qǐng)求結(jié)果獲取后端服務(wù)器數(shù)據(jù),從而渲染到頁面,服務(wù)端無法主動(dòng)向客戶端發(fā)起消息,某些需求場(chǎng)景下,一旦客戶端 需要知道服務(wù)端的頻

    2024年02月02日
    瀏覽(22)
  • WebSocket | 基于TCP的全雙工通信網(wǎng)絡(luò)協(xié)議

    WebSocket | 基于TCP的全雙工通信網(wǎng)絡(luò)協(xié)議

    ???作者介紹:雙非本科大三網(wǎng)絡(luò)工程專業(yè)在讀,阿里云專家博主,專注于Java領(lǐng)域?qū)W習(xí),擅長web應(yīng)用開發(fā)、數(shù)據(jù)結(jié)構(gòu)和算法,初步涉獵Python人工智能開發(fā)和前端開發(fā)。 ??主頁:@逐夢(mèng)蒼穹 ??所屬專欄:Java EE ? 您的一鍵三連,是我創(chuàng)作的最大動(dòng)力?? WebSocket 是基于 TCP 的一

    2024年02月19日
    瀏覽(27)
  • 網(wǎng)絡(luò)通信協(xié)議-HTTP、WebSocket、MQTT的比較與應(yīng)用

    網(wǎng)絡(luò)通信協(xié)議-HTTP、WebSocket、MQTT的比較與應(yīng)用

    在今天的數(shù)字化世界中,各種通信協(xié)議起著關(guān)鍵的作用,以確保信息的傳遞和交換。HTTP、WebSocket?和?MQTT?是三種常用的網(wǎng)絡(luò)通信協(xié)議,它們各自適用于不同的應(yīng)用場(chǎng)景。本文將比較這三種協(xié)議,并探討它們的主要應(yīng)用領(lǐng)域。 HTTP (超文本傳輸協(xié)議) HTTP ?是最常見的協(xié)議之一

    2024年02月05日
    瀏覽(40)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包