聲網 Agora SDK 體驗-直播|掘金技術徵文

概述

一直好奇直播這個東東是如何實現的,譬如音視頻流是如何採集的? 音視頻流是如何推送到訂閱方 ? 如何支撐上萬級、百萬級用戶同時觀看直播 ?javascript

下面就基於聲網 Agora SDK 開發一個簡單的直播網站來體驗一下吧。html

功能設計

直播功能腦圖

如上圖所示爲直播 Demo 實現的基本功能展現,包括:java

主播端:json

  • 建立直播間
  • 發佈、取消發佈視頻
  • 下播
  • 瀏覽發送彈幕

訪客端:api

  • 瀏覽直播間
  • 觀看直播
  • 退出直播間
  • 瀏覽發送彈幕

下面看下本次實現的簡易架構圖:架構

直播架構

實現

在實現以前咱們須要建立 Agora 帳號並獲取 App ID(參見聲網的開發者中心)。app

主播端

建立直播間

本次實現對於直播間的建立只是簡單記錄下直播間的名稱ide

存儲直播間名稱
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 獲取直播間名稱
        String room = req.getParameter("room");
        // 新增直播間
        RoomListHolder.addRoom(room);

        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("application/json");

        resp.getWriter().write("true");
    }
複製代碼
Agora SDK 集成
// 建立 Agora Client
    var client = AgoraRTC.createClient({mode: 'interop'});
    // 初始化 client,並在初始化成功後執行加入直播間頻道
    client.init('APP ID', function () {
        // 加入直播間頻道
        client.join(null, room, null, function (uid) {
            console.log("用戶 " + uid + "建立了直播間 " + room);
            
            // 執行本地視頻發佈
        });
    });
複製代碼
發佈視頻

主播在完成直播間的建立以後,基於 Agora SDK 實現本地視頻的發佈,這樣當有訂閱該直播間頻道的用戶將會獲取視頻流。post

獲取本地音頻設備

在發佈視頻前,須要獲取本地的音頻設備,也便是麥克風,攝像頭。網站

AgoraRTC.getDevices(function (devices) {
    for (var i = 0; i !== devices.length; ++i) {
        var device = devices[i];

        if (device.kind === 'audioinput') {
            // 獲取麥克風設備
            media.audio = device.deviceId;
        } else if (device.kind === 'videoinput') {
            // 獲取攝像頭設備
            media.video = device.deviceId;
        }
    }
});
複製代碼
發佈視頻
// 建立本地音視頻流
    var localStream = AgoraRTC.createStream({
        streamID: uid, // Agora 分配的 uid
        audio: true,
        cameraId: camera, 
        microphoneId: microphone,
        video: true,
        screen: false
    });
    // 初始化音視頻流
    localStream.init(function () {
        // 指定元素 ID 播放音視頻流
        localStream.play('video');

        // 發佈音視頻流
        client.publish(localStream, function (err) {
            console.log("音視頻發佈失敗: " + err);
        });
        // 監聽音視頻發佈事件
        client.on('stream-published', function (evt) {
            console.log("音視頻發佈成功!");
        });
    }, function (err) {
        console.log("", err);
    });
複製代碼
下播

下播對於 Agora SDK 來講便是離開頻道,同時從直播間列表中移除當前直播間。

client.leave(function () {
    // 主播執行時 會觸發訪客端事件 peer-leave
    // 訪客執行時 不會觸發
    console.log("下播成功");
    // 將 room 從直播間列表中移除
    $.post("/removeRoom?room=" + room, {}, function(data, textStatus, jqXHR) {
        // do nothing
    }, 'json');
}, function (err) {
    console.log("下播失敗");
});
複製代碼
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    // 獲取待移除的直播間
    String room = req.getParameter("room");
    // 移除直播間
    RoomListHolder.removeRoom(room);
}
複製代碼

訪客端

訪客經過瀏覽直播間列表,選擇本身感興趣的主播觀看。

瀏覽直播間
// 獲取直播間列表數據
$.get("/getRooms", function (data, status) {
    var roomHtml = '';

    if (data == null) {
        roomHtml = '當前沒有直播間';
    } else {
        $.each(data, function (i, room) {
            roomHtml += '<div class="layui-col-md6">\n' +
                ' <div class="layui-card">\n' +
                ' <div class="layui-card-header">'+ room +'</div>\n' +
                ' <div class="layui-card-body">\n' +
                ' <button channel="'+ room +'" class="layui-btn layui-btn-radius layui-btn-warm view">\n' +
                ' <i class="layui-icon">&#xe652;</i> 觀看\n' +
                ' </button>\n' +
                ' </div>\n' +
                ' </div>\n' +
                ' </div>\n' +
                ' ';
        });
    }
    // 渲染
    $('#roomList').html(roomHtml);
});
複製代碼
觀看直播

訪客觀看直播,對於 Agora SDK 來講也就是加入直播間頻道,並訂閱頻道視頻流。

client.join(null, room, null, function (uid) {
    console.log("用戶 " + uid + " 來到直播間 " + room);
}, function (err) {
    console.log("加入直播間失敗")
});

client.on('stream-added', function (evt) {
    // 主播發布視頻時會觸發 stream-added 事件
    var stream = evt.stream;
    // 訪客訂閱 stream 流
    client.subscribe(stream, function (err) {
        console.log("視頻流訂閱失敗", err);
    });
});

client.on('stream-subscribed', function (evt) {
    // 主播端視頻流訂閱成功後觸發 stram-subscribed 事件
    var stream = evt.stream;
    // 按指定元素 ID 播放視頻流
    stream.play('video_remote');
});


client.on('stream-removed', function (evt) {
    // 主播端執行 unpublish 時會觸發該事件
    var stream = evt.stream;
    // 中止視頻播放
    stream.stop();
});

client.on('peer-leave', function (evt) {
    // 主播端執行 leave 下播操做時會觸發該事件
    var stream = evt.stream;
    if (stream) {
        // 中止視頻流播放
        stream.stop();
    }
});
複製代碼

彈幕

本次只是對直播的簡單實現,彈幕的功能暫時忽略吧,o(╯□╰)o

效果

直播

觀看直播

小結

在 Agora SDK 的使用過程當中,能夠感覺到其有如下優勢:

  • 支持多種應用場景
  • 完善的 API 文檔,方便開發者查閱
  • 提供開發者社區,便於開發者交流,反饋使用過程當中的問題
  • 針對各類場景提供了 DEMO

不過在官網提供的快速開始及 API 相關重要方法譬如client.publish中,最好能說明下調用了該方法會觸發哪些事件;而不是隻有在查閱了 event api 纔會發現其是哪些操做觸發的。

Agora SDK 使用體驗徵文大賽 | 掘金技術徵文,徵文活動正在進行中

相關文章
相關標籤/搜索