弹幕

1. 弹幕演示

2. 注意事项

  • 1、内置弹幕UI发送弹幕: 需要开启弹幕服务器,具体参看弹幕设置说明

  • 2、本地弹幕测试: 只是本地调用接口appendDanmu测试弹幕显示,不需要弹幕服务器。

3. 示例代码

示例代码仅供参考,实际使用时需要根据实际情况进行修改。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta name="renderer" content="webkit">
    <meta name="viewport"
          content="width=device-width,initial-scale=1, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <meta name="x5-fullscreen" content="true">
    <meta name="full-screen" content="yes">
    <meta name="apple-mobile-web-app-capable" content="yes"/>
    <meta name="apple-mobile-web-app-status-bar-style" content="black"/>
    <meta name="format-detection" content="telephone=no">
    <title>弹幕演示</title>
    <script type="text/javascript" charset="utf-8" src="https://cdn.zwplayer.cn/v3/zwplayer/zwplayer.js"></script>
    <style>
        html, body {
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
        }

        .player-wrap {
            position: relative;
            padding: 20px;
            width: 80%;
            margin-left: auto;
            margin-right: auto;
            min-width: 1024px;
        }

        .vxplayer {
            width: 1024px;
            height: 576px;
            margin: 0 auto;
            background-color: #222;
        }

        .vxplayer-toolbar {
            height: 40px;
            border: 1px solid #c0c0c0;
            margin-top: 20px;
            width: 100%;
            margin-left: auto;
            margin-right: auto;
            padding: 6px 10px;
            box-sizing: border-box;
            position: relative;
        }

        .vxplayer-toolbar .btn {
            border: 1px solid #a0a0a0;
            border-radius: 5px;
            min-width: 60px;
            height: 26px;
            box-sizing: border-box;
            margin: 0 5px;
            float: left;
        }

        .vxplayer-toolbar .btn:hover {
            background: #b8e1ee;
            border-color: #89baf2;
            color: #003566;
        }

        .vxplayer-toolbar .btn:hover {
            background: #83aab7;
            color: #016789;
            border-color: #2c5c81;
        }

        .url-inputbox {
            height: 26px;
            display: inline-block;
            padding: 0px 10px;
            float: left;
            font-size: 14px;
        }

        .url-inputbox .label {
            display: inline-block;
            width: 120px;
            height: 26px;
            line-height: 26px;
            padding-right: 6px;
            text-align: right;
        }

        .url-inputbox input[type="text"] {
            height: 26px;
            width: 525px;
            border: 1px solid #ccc;
            border-radius: 3px;
            line-height: 22px;
            box-sizing: border-box;
            padding-left: 6px;
            padding-right: 6px;
        }

        .vxplayer-toolbar.danmubar {
            height: 48px;
            background-color: #474343;
            padding-left: 200px;
            margin-top: 0;
            border-top: 0;
            border-color: #000;
        }

    </style>
    <script language="javascript">

        function onOpenUrl(url) {
            if (!window.zwplayer) {
                window.zwplayer = new ZWPlayer({
                    url: url,
                    playerElm: '#player-holder', //player 元素ID ,也可以直接的DOM对象 playerDom
                    autoplay: true,
                    controlbar: true,
                    infoButton: true,
                    speedButton: true,
                    optionButton: true,
                    snapshotButton: true,
                    enableDanmu: true,
                    sendDanmu: function (text) {
                        if (typeof window.ws_send === 'function') {
                            window.ws_send(text);
                        }
                    }
                });
                window.zwplayer.buildDanmuControlbar('player-dammu-controlbar');
            } else {
                window.zwplayer.play(url, false, false);
            }
        }

        function onload() {
            var url = 'https://d2zihajmogu5jn.cloudfront.net/elephantsdream/ed_hd.mp4';
            setTimeout(function () {
                onOpenUrl(url);
            }, 100);
            window.channelinfo = {
                id: '001'
            };
            (function (root) {
                var wsChat = null;
                var logView = null;
                var wschat_server = "ws://10.234.1.106:3000/";  //替换为实际弹幕服务器地址
                var reconnect = false;
                var msg_queue = [];
                var force_close = false;
                var userCurrent = {};


                function chat_log(str) {
                    console.log(str);
                }

                function toast(type, msg) {

                }

                root.ws_init = function chatSocketInit() {

                    if (wsChat) return wsChat;
                    // Connect to Web Socket.
                    // Change host/port here to your own Web Socket server.
                    try {
                        wsChat = new WebSocket(wschat_server);
                    } catch (e) {
                        return false;
                        reconnect = false;
                    }

                    // Set event handlers.
                    wsChat.onopen = function () {
                        chat_log("wsChat onopen");

                        if (window.enableBalance == '1' && !window.mediaserver) {
                            root.ws_getmediaserver();
                        }

                        window.setTimeout(function () {
                            delete userCurrent.loginChat;
                            if (!wsChat) return;
                            wsChat.send('{type:"hello"}');

                            if (reconnect) {
                                toast('showToast', {
                                    text: '与互动服务器的重新建立连接成功。',
                                    sticky: false,
                                    stayTime: 3000,
                                    position: 'top-center',
                                    type: 'notice'
                                });
                                reconnect = false;
                                if (msg_queue['userlogin']) {
                                    wsChat.send(msg_queue['userlogin']);
                                    delete msg_queue['userlogin'];
                                }
                            }
                        }, 40);
                    };


                    wsChat.onmessage = function (e) {
                        // e.data contains received string.
                        chat_log("wsChat onmessage: " + e.data);

                        if (e.data.length > 0) {
                            if (e.data.charAt(0) === '{') {
                                var msgContent;
                                var msgObj = JSON.parse(e.data);

                                if (typeof (msgObj) === 'object') {
                                    if (msgObj.text)
                                        msgContent = msgObj.text;
                                    else
                                        msgContent = '';

                                    if (msgObj.type === 'danmu') {
                                        if (window.zwplayer) {
                                            if (msgContent == '') return;
                                            // msgObj.text = msgContent;
                                            window.zwplayer.appendDanmu(msgObj);
                                        }
                                    } else if (msgObj.type === 'hello') {
                                        window.joinRoomOk = true;
                                        //获得授予的UID
                                        window.current_uid = msgObj.uid;
                                        var roomname = 'videoroom_' + window.channelinfo.id;
                                        window.ws_send('{"type":"join","room":"' + roomname + '"}');
                                    } else if (msgObj.type === 'login') {
                                        if (!msgObj.result || msgObj.result != 'success') {
                                            toast('showNoticeToast', '登录到互动服务器返回不成功。<br/>可能影响聊天互动!');
                                        } else {
                                            userCurrent.loginChat = true;
                                        }
                                    } else if (msgObj.type === 'logout') {
                                        //用户自己登出的回馈
                                        delete userCurrent.loginChat;
                                    } else if (msgObj.type === 'event') {
                                        if (msgObj.event === 'joinroom') {
                                            //别的用户与自己连接到聊天服务器
                                            if (msgObj.uid) {
                                                if (msgObj.uid === window.current_uid) {
                                                    userCurrent.joinroom = true;
                                                }
                                            }
                                        } else if (msgObj.event === 'leaveroom' || msgObj.event === 'exitroom') {
                                            //别的用户离开聊天服务器
                                            if (msgObj.uid) {
                                                if (msgObj.uid === window.current_uid) {
                                                    userCurrent.joinroom = false;
                                                }
                                            }
                                        } else if (msgObj.event === 'login') {
                                            //别的用户连接到聊天服务器
                                            if (msgObj.uid) {

                                            }
                                        } else if (msgObj.event === 'logout') {
                                            //别的用户离开聊天服务器
                                            if (msgObj.uid) {

                                            }
                                        }
                                    } else if (msgObj.type == 'userlist') {
                                        //连接到聊天服务器后服务器马上推送在线用户列表,该列表不包括自己
                                        if (msgObj.users.length > 1) {

                                        }
                                    } else if (msgObj.type === 'setuserid') {
                                        //连接建立后将收到这个事件
                                        window.current_uid = msgObj.uid;
                                        userCurrent.userid = msgObj.uid;
                                    }
                                }
                            }
                        }
                    };

                    wsChat.onclose = function () {
                        chat_log("wsChat onclose");
                        wsChat = null;
                        toast('showToast', {
                            text: '与互动服务器的连接已经断开。',
                            sticky: false,
                            stayTime: 3000,
                            position: 'top-center',
                            type: 'notice'
                        });
                        if (force_close) {


                        } else if (!reconnect) { //当前不是重连状态,则尝试重连
                            reconnect = true; //设置为正在重连状态
                            var on_reconnect = function () {
                                if (force_close) return;

                                wschat = root.wschat = root.ws_init();
                                if (!wschat) {
                                    reconnect = true;
                                    window.setTimeout(on_reconnect, 10000);
                                }
                            }
                            window.setTimeout(on_reconnect, 10000);
                        }
                    };

                    wsChat.onerror = function () {

                        chat_log("wsChat onerror");
                        wsChat = null;
                    };

                    return wsChat;
                }

                root.ws_send = function wsChatSend(data) {
                    chat_log("wsChat send: " + data);

                    if (wsChat) {
                        wsChat.send(data);
                        return true;
                    } else {
                        toast('showToast', {
                            text: '聊天交互服务没有连接成功或已经中断!<br/>正在尝试重连,请稍候再试...',
                            sticky: false,
                            stayTime: 3000,
                            position: 'top-center',
                            type: 'warning'
                        });

                        reconnect = true;
                        wschat = root.wschat = root.ws_init();

                        return false;
                    }
                }

                root.ws_queue = function wsQueue(type, msg) {
                    msg_queue[type] = msg;
                }

                root.ws_close = function wsChatClose() {
                    if (wsChat) {
                        force_close = true;
                        wsChat.close();
                        wsChat = null;
                    } else {

                    }
                }

                root.wschat = wsChat;
            })(window);
            window.ws_init();
        }

        function onSendDanmu() {
            var danmuText = document.getElementById('danmu-box').value;
            if (!danmuText)
                return;
            var danmu = {
                //outlineColor: '#f00',
                border: '1px solid #ccc',
                text: danmuText
            };

            if (window.zwplayer) {
                window.zwplayer.appendDanmu(danmu);
            }
        }

        function onDisableDanmu() {
            if (window.zwplayer) {
                window.zwplayer.setEnableDanmu(false);
            }
        }

        function onEnableDanmu() {
            if (window.zwplayer) {
                window.zwplayer.setEnableDanmu(true);
            }
        }

    </script>
</head>
<body onload="onload()">
<div class="player-wrap">
    <div class="vxplayer" id="player-holder" style="width: 100%;height: 450px; margin: 0; padding: 0;">
    </div>
    <div class="vxplayer-toolbar danmubar" id="player-dammu-controlbar"></div>
    <div class="vxplayer-toolbar" id="player-dammubar">
        <div class="url-inputbox">
            <span class="label">本地弹幕测试:</span>
            <input type="text" id="danmu-box" value="">
        </div>
        <button class="btn" onclick="onSendDanmu();">发送弹幕</button>
        <button class="btn" onclick="onEnableDanmu();">允许弹幕</button>
        <button class="btn" onclick="onDisableDanmu();">禁止弹幕</button>
    </div>
</div>
</body>
</html>
目录导航