弹幕
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>
目录导航