小良下山化了个缘

小良下山化了个缘

七牛实时音视频云视频连线demo(web部分)

官方文档:

https://doc.qnsdk.com/rtn/web

步骤

1.申请七牛云账号;

2.服务器上做token验证接口

3.web demo开发

注意事项
  1. 因为屏幕和摄像头采集只能在 localhost 或者 https 下完成;
  2. 因为项目涉及到和客户端视频连线,一开始客户端取不到web发布的视频流,后面仔细查看文档才知道需要把客户端打不得track流设置Master为true(默认false)
代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>视频连线</title>
</head>
<link rel="stylesheet" href="src/css/index.css">
<link rel="stylesheet" href="src/layui/css/layui.css">
<body>
<div class="title">演播室</div>
<div id="localtracks"></div>
<div class="title">远方记者</div>
<div id="subtracks"></div>
<div class="button">
    <button class="layui-btn layui-btn-normal" onclick="page.joinRoom()">加入房间</button>
    <button class="layui-btn layui-btn-normal" onclick="page.leaveRoom()">离开房间</button>
</div>
</body>
<script src="src/js/public/pili-rtc-web.js"></script>
<script src="src/js/public/jquery-3.3.1.min.js"></script>
<script src="src/layui/layui.all.js"></script>
<script>
    var page = {};
    page.uid = 6;
    page.roomname = '123456';
    page.token = '';
    myRoom = null;


    page.getToken = async function () {
        await $.ajax({
            url: '/QiuNiu/getToken',
            type: 'POST',
            data: {
                uid: page.uid,
                roomname: page.roomname
            },
            success: function (res) {
                res = JSON.parse(res)
                if (res.code == 200) {
                    page.token = res.data.token
                } else {
                    console.log(res.msg)
                    layer.msg(res.msg,{icon:2})
                }
            }
        });
    }

    page.joinRoom = function () {
        layer.prompt({title: '请输入房间号', value: page.roomname, maxlength: 64}, function(pass, index){
            const roomReg = /[a-zA-Z0-9_-]{3,64}/;
            if(roomReg.exec(pass)){
                page.roomname = pass
                layer.close(index);
                page.startConnect();
            } else {
                layer.msg('房间号必须为3位以上字母和数字组成!',{icon:2})
            }
        });
    }
    page.startConnect = async function () {
        await page.leaveRoom();
        await page.getToken();
        // 这里替换成刚刚生成的 RoomToken
        await  myRoom.joinRoomWithToken(page.token);
        await page.publish();
        page.autoSubscribe();
    }

    page.leaveRoom = async function () {
        myRoom.leaveRoom();
        $('#localtracks').html('');
        const tracks = await QNRTC.deviceManager.getLocalTracks({
            audio: {enabled: true, tag: "audio"},
            video: {enabled: true, tag: "video"},
        });

        // 遍历 tracks,逐个销毁释放
        for (const track of tracks) {
            track.release();
        }
    }
    page.publish = async function () {
        // 我们打开了 3 个参数,即采集音频,采集视频,采集屏幕共享。
        // 这个函数会返回一个列表,列表中每一项就是一个音视频轨对象
        const localTracks = await QNRTC.deviceManager.getLocalTracks({
            audio: {enabled: true, tag: "audio"},
            video: {enabled: true, tag: "video"},
        });
        for (const localTrack of localTracks) {
            localTrack.setMaster(true);
        }
        // 将刚刚的 Track 列表发布到房间中
        await myRoom.publish(localTracks);
        console.log("publish success!");

        const localElement = document.getElementById("localtracks");
        // 遍历本地采集的 Track 对象
        for (const localTrack of localTracks) {
            localTrack.setMaster(true);
            // 如果这是麦克风采集的音频 Track,我们就不播放它。
            if (localTrack.info.tag === "audio") continue;
            // 调用 Track 对象的 play 方法在这个元素下播放视频轨
            localTrack.play(localElement, true);
        }
    }

    // 这里的参数 myRoom 是指刚刚加入房间时初始化的 Session 对象, 同上
    // trackInfoList 是一个 trackInfo 的列表,订阅支持多个 track 同时订阅。
    page.subscribe =  async function (trackInfoList) {
        // 通过传入 trackId 调用订阅方法发起订阅,成功会返回相应的 Track 对象,也就是远端的 Track 列表了
        const remoteTracks = await myRoom.subscribe(trackInfoList.map(info => info.trackId));

        // 选择页面上的一个元素作为父元素,播放远端的音视频轨
        const remoteElement = document.getElementById("subtracks");
        // 遍历返回的远端 Track,调用 play 方法完成在页面上的播放
        for (const remoteTrack of remoteTracks) {
            remoteTrack.play(remoteElement);
        }
    }

    page.autoSubscribe =  function () {
        const trackInfoList = myRoom.trackInfoList;
        // 调用我们刚刚编写的 subscribe 方法
        // 注意这里我们没有使用 async/await,而是使用了 Promise,大家可以思考一下为什么
        page.subscribe(trackInfoList)
            .then(() => console.log("subscribe success!"))
            .catch(e => console.error("subscribe error", e));

        // 添加事件监听,当房间中出现新的 Track 时就会触发,参数是 trackInfo 列表
        myRoom.on("track-add", (trackInfoList) => {
            page.subscribe(trackInfoList)
                .then(() => console.log("subscribe success!"))
                .catch(e => console.error("subscribe error", e));
        });
        // 就是这样,就像监听 DOM 事件一样通过 on 方法监听相应的事件并给出处理函数即可
    }

    page.initRoom = async function () {
        myRoom = new QNRTC.TrackModeSession();
    }

    $(function () {
        page.initRoom();
    });

    // localhost 或者 127.0.0.1 访问刚刚那 2 个页面(因为屏幕和摄像头采集只能在 localhost 或者 https 下完成),
</script>
</html>
01-22 18:23