iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 21
2
Software Development

30天之即時網路影音開發攻略(小白本)系列 第 21

30-21之如何建立的像 17 一樣的直播功能呢 ?

黑色好看版 - 傳送門


正文開始

上一篇文章中,咱們已經學習了如何建立點播這種類型的網站應用,接下咱們要來學學如何建立直播應用。

在筆者的30-09之別人要如何聽到我的聲音呢 ?有提到三種影音的傳遞方式,分別為:

將聲音檔案直接丟給對方 ( 方法 1 )
將聲音檔案以串流的方式傳送給對方 ( 方法 2 )
像直播或網路電話一樣即時的將聲音傳送給對方 ( 方法 3 )

接下來我們將來實作方法 3 的選項,而這東西事實上就是直播網站的應用,像 17 就是這種類型的應用,本篇文章將會說明:

如何建立的像 17 一樣的直播功能呢 (可以動就好版) ?

https://ithelp.ithome.com.tw/upload/images/20181105/200893581RcXw4huRl.jpg

本篇將分為以下幾個章節:

  • 直播架構原理。
  • 實作 - 建立 Media Server。
  • 實作 - 網頁用戶端取得串流影像。

直播架構原理


直播的架構最基本的如下圖,基本上和點播很相似,只差了直播主推送聲音到 Media Server 這個步驟。

https://ithelp.ithome.com.tw/upload/images/20181105/20089358nqLraVoW8t.png

然後基本上推流的協議,應該是只有一種選擇RTMP,網路上看到有人說 HLS 這點我還要待調查,我先打個問號,
然後還有提到 WebRTC 這個可以當推流 (不過它應該不算傳輸協議),這理論上應該是行,這之後 WebRTC 的文章會來聊聊。

而拉流就有不少RTMPHLSHTTP-FLVMPEG-DASH

老樣子問個問題。

那要選擇那個協議來當拉流呢 ?

首先我覺得要先看你的直播應用是否為互動性很要求的,如果是它就只有兩個選擇 RTMP 與 HTTP-FLV。不過 RTMP 拉流應該會有不少設備無法使用(果粉),所以最後應該會選 HTTP-FLV 吧。

而如果是不會太在意互動性的直播,例如運動賽事直播這種,那選那個,我覺得就看用戶那的支援度吧。

實作 - 建立 Media Server。


這裡的 Media Server 基本上要做兩件事情。

  • 可以接受直播端的影音推流,通常是 RTMP。
  • 收到 RTMP 後,可以根據用戶的拉流協議來進行轉換 (ex. 如果是 HLS,那就要轉成 .m3u8 )

這裡咱們就直接使用這個 nodejs 的 Media Server 套件,這裡我們就不深入探討 Media Server 相關選擇,這裡先只追求可以動就好 ( 改天有空在來討探 )。

nodejs-media-server

使用方法很簡單。

首先將程式碼抓下來,然後將套件安裝好,接下來執行就好。

git clone https://github.com/illuspas/Node-Media-Server.git
cd Node-Media-Server
npm install

node app.js

執行完,如果你看到如下圖的模樣,那就代表成功了。

https://ithelp.ithome.com.tw/upload/images/20181105/20089358Tss5iyF5eU.jpg

實作 - 網頁用戶端取得串流影像


接下來我們來建立一個簡單的網頁來當聽眾,然後他會使用 HTTP-FLV 拉流來觀看直播主的畫面。這段程式碼很簡單,它就只要載入 flv.js 並且指定你要觀看的 HTTP-FLV 串流位置就完成了。

<html>

<head>
    <title>Test</title>
</head>

<body>
    <script src="https://cdn.bootcss.com/flv.js/1.4.2/flv.min.js"></script>
    <video controls id="video"></video>

    <input type="text" />
    <button id="load">Load</button>
    <script>
        if (flvjs.isSupported()) {
            document.querySelector("#load").addEventListener("click", function () {
                const video = document.getElementById('video');
                const target = document.querySelector("input").value;
                const flvPlayer = flvjs.createPlayer({
                    type: 'flv',
                    url: `http://localhost:8000/live/${target}.flv`
                });
                flvPlayer.attachMediaElement(video)
                flvPlayer.load();
                flvPlayer.play();
            })
        }
    </script>
</body>

</html>

最後執行結果


在 Server 與 Client 都完成以後,咱們接下來就來執行看看

直播端

我們使用 ffmpeg 假裝為某個直播主,然後打 RTMP 串流到 Server 中。下面指令中,我使用某個 .mp4 影片來假裝直播主的影音,接下來將它推送 rtmp 到指定的位置。

ffmpeg -re -i test.mp4 -c copy -f flv rtmp://localhost/live/mark

聽眾

然後直播主已經在開直播了,接下來我們只要指定某個直播主就好,像上面我這個直播主是用 mark 這個串流,你這時就可以使用 http://127.0.0.1:8000/live/mark.flv 就可以觀看了。

https://ithelp.ithome.com.tw/upload/images/20181105/20089358Hx7tUZPT1u.jpg

結論


本篇文章中,咱們學習到了如何建立最簡單的 17 直播功能,接下來咱們要來探討一下,現在這種架構有什麼問題。


上一篇
30-20之如何建立像 KKTV 一樣的點播功能呢 ?
下一篇
30-22之點播與直播可動版問題探討
系列文
30天之即時網路影音開發攻略(小白本)30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
轟天旅人
iT邦新手 4 級 ‧ 2021-09-12 02:58:47

想請問推流為何一般都是rtmp,有甚麼原因嗎?
如果拉流是其他的協定,那不是推流也用改協定速度或一致性會比較高嗎

nlstudio iT邦新手 2 級 ‧ 2022-03-11 10:13:37 檢舉

RTMP 與 flv兩種格式是目前延遲最少最穩定的格式
誤差在2-3秒內
另外m3u8物理限制是10秒,在不嚴格要求直播即時性來說,
也是可以考慮的格式

我要留言

立即登入留言