2.2 zwplayer调用示例

以下代码只作为功能演示,使用时将url替换为真实使用的url

注意

建议使用chrome浏览器,如果遇到跨域问题不能播放,请设置以下选项:

chrome://flags/#block-insecure-private-network-requests 为Disabled

<!DOCTYPE html>
<html>
<head>
<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>
<!-- link type='text/css' rel='stylesheet' href='zwplayer/css/zwplayer.css?v=2.971' -->
<script type="text/javascript" src="zwplayer/zwplayer.js?v=3.28"></script>

<!-- script type="text/javascript" src="https://res.wx.qq.com/mmbizwap/zh_CN/htmledition/js/vconsole/3.0.0/vconsole.min.js"></script //-->
<style>
html,body{width:100%; height:100%;margin:0;padding:0;}

.player-wrap {
	position:relative;
	padding:40px;
	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: 60px;
    height: 26px;
    line-height: 26px;
    padding-right: 6px;
    text-align: right;
}

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

.opt-panel {
	width: 160px;
	float: left;
	padding: 3px 5px;
}

.time-info {
	position: absolute;
	left: 40px;
	top: 0;
	padding: 10px;
	line-height: 20px;
}

.time-info .time-item {
	display: inline-block;
    min-width: 100px;
	padding: 0 5px;
}

.time-info .time-item SPAN.time-value {
	display: inline-block;
	padding-left: 6px;
	width: 120px;
	font-weight: 600;
}

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

.popup_box {
	position: absolute;
	width: 900px;
	height: 300px;
	left: 50px;
	bottom: 40px;
	padding: 6px;
	background-color: #f0f0f0;
	border: 1px solid #ccc;
	display: none;
	z-index: 10000;
}

.popup_box .m-urls-box {
	display: block;
	width: 100%;
	height: 260px;
	border-radius: 5px;
	box-sizing: border-box;
	padding: 6px;
	white-space: nowrap;
}

.popup_box .popup-btoolbar {
	overflow: hidden;
    padding: 8px 0;
}

.cbx {
    height: 24px;
    border: 1px solid #888;
    border-radius: 3px;
	float: left;
}

.current-time-view {
	
}

</style>

<script language="javascript">

var thumbnails = {
    "url": "http://192.168.2.202:8088/images/VMAP1BwuvRpgn5sR451sg1JqgNkih4os1wk4kkY12NU61xBlkgtklBs10MthlgFglMdi1Rg32R5i3glhll06lwc7k4YmmktulxJs4g5.jpg",
    "width": 128,
    "height": 72,
    "col": 17,
    "row": 17,
    "total": 274
};

var thumbnails = {
	"url": "http://192.168.2.202:8088/images/VMAP9BwumT9ytBsi5DNnlRRkhkUkn5d36k5u50ZjkRFohxBjkwc17wg06R5h7w4a1wo4kMo4l0hmk09hllln0Mlj1Bhn1Mdi1wge0RFkrktsg5I3j5J2l0.jpg",
	"width": 128,
	"height": 72,
	"row": 17,
	"col": 17,
	"total": 287
 };
 
 // http://192.168.1.202:8088:8030/vod/mp4/VMAP9RwunRN2n5cijn1AvB5hnM0q7w031wo6kARnl0cc0Nwc4w5.mp4
var thumbnails = {
        "url": "http://192.168.2.202:8088/images/VMAP9BwumT9ytBsi5DNnlRRkhkUkn5d36k5u50ZjkRFohxBjkwc17wg06R5n7wlg1MM1kMpgkgk00Bln0M1j0ls3kRxq2g85lBdglMo4rktsg5I3j5J2l0.jpg",
        "width": 128,
        "height": 96,
        "row": 11,
        "col": 11,
        "total": 113
     };
	 
//http://192.168.1.202:8088/vod/mp4/VMAP8BxJpQ1hhQkZ8RlvmBFshhkgk4pshCBw20pknk1ETqvdyHK3RGiG6UroAZimydekNQNsgw7.mp4
var thumbnails = {
        "url": "http://192.168.1.202:8088/images/VMAP9BwumT9ytBsi5DNnlRRkhkUkn5d36k5u50ZjkRFohxBjkwc17wg06R5n7Bg1k546kBk5lRpn1wk41Bs61MkckBxg15dm15hgkBE1rktsg5I3j5J2l0.jpg",
        "width": 128,
        "height": 72,
        "row": 7,
        "col": 7,
        "total": 43
     };

var flvUrls = {
	murls: {
"FULL_HD1": "http://pull-l3.douyincdn.com/stage/stream-7298596124380760882_or4.flv?auth_key=1699947406-0-0-759b8598bfe57b6f7c6ebf34128e027e",
"HD1": "http://pull-l3.douyincdn.com/stage/stream-7298596124380760882_hd.flv?auth_key=1699947406-0-0-74a47519044360e45bcdf3a221ff751a",
"SD1": "http://pull-l3.douyincdn.com/stage/stream-7298596124380760882_ld.flv?auth_key=1699947406-0-0-ee9fda2232a22a6822aef0822f446638",
"SD2": "http://pull-l3.douyincdn.com/stage/stream-7298596124380760882_sd.flv?auth_key=1699947406-0-0-96a86e2d04b9343b27ce46a1117748c8"
	},
	multistream: 4
};

function onOpenUrl(urlObj) {
	var url;
	var streamtype = "";
	
	if (urlObj) {
		url = urlObj;
	}
	else {
		var urlbox = document.getElementById('url-box');
	
		url = urlbox.value;
	
		if (!url) {
			alert('Please enter url.');
			urlbox.focus();
			return;
		}
		
		streamtype = document.getElementById('stream_type_cbx').value;
	}
	
	var isLive = document.getElementById('isLive-flag').checked;
	var isUseFlv = document.getElementById('isUseFlv-flag').checked;
	
	var timer = new Date();
	var timeStart = timer.getTime() - 1686800000000;
	document.getElementById('time-start').innerHTML = timeStart;
	
	if (!window.zwplayer) {
		//var playerDom = document.querySelector('#player-holder');
		window.zwplayer = new ZWPlayer({
		  url:url,
          playerElm:'#player-holder', //player 元素ID ,也可以直接的DOM对象 playerDom
		  videoElm:'#videoview',   //videoElm 元素
		  videostyle:"width:100%;height:100%;",
		  reconnect:true,
		  autoplay: true,
		  nativecontrols: false,
		  isLive: isLive,
		  useOldFlv: false,
		  useFlv: isUseFlv,
		  streamtype: streamtype,
		  // hasAudio: false,
		  xmc_url: 'http://192.168.1.202:8138/',
		  //logframe:true,
		  controlbar: true,
		  infoButton: true,
		  speedButton: true,
		  optionButton: true,
		  snapshotButton: true,
		  chapterButton: true,
		  enableDanmu: true,
		  useProgressTooltip: true,
		  fixedControlbar: true,
		  hidePlayBtn: false,
		  disablePlayBtn: false,
		  disableSeek: false,
		  disableFullscreenWin: false,
		  disablePicInPic:true,
		  disableVolumeControl: false,
		  thumbnails: thumbnails,
		  fluid: true,
		  // chapters: 'http://192.168.1.202/chapters.json?v=3',
		  muted: false,
		  onready:function() {
			console.log("Player onready");
			
		  },
		  onfirstframe:function() {
			console.log("Player onfirstframe");
		  },
		  onnetclose:function() {
			console.log("Player onnetclose");
		  },
		  onneterror:function() {
			console.log("Player onneterror");
		  },
		  onmediaevent: function(event) {
			if (['play', 'pause', 'seeked', 'ended', 'error'].includes(event.type)) {
				console.log("player video Event:", event);
				if (event.type == 'seeked') {
					var currentTime = event.srcElement.currentTime;
					
					console.log("player currentTime:", currentTime);
				}
				
				if (event.type === 'play') {
					var timeEnd = (new Date()).getTime() - 1686800000000;
					var timeTotal = timeEnd - timeStart;
					
					document.getElementById('time-end').innerHTML = timeEnd;
					document.getElementById('time-total').innerHTML = timeTotal;
				}
			}
		  },
		  sendDanmu: function(text) {
			//alert(text);
			if (typeof window.ws_send === 'function') {
				window.ws_send(text);
			}
		  }
	  });
	  
	  window.zwplayer.buildDanmuControlbar('player-dammu-controlbar');
	}
	else {
		window.zwplayer.play(url, isLive, false);
	}
}

function onClose() {
	if (window.zwplayer) {
		window.zwplayer.stop();
	}
}

function ondestroy() {
	if (window.zwplayer) {
		window.zwplayer.destroy();
		delete window.zwplayer;
	}
}
//multistream-urls multistream-urls-input
function onMultiStreams() {
	var popupbox = document.getElementById('multistream-urls-box');
	var display = popupbox.style.display;
	
	display = display !== 'block' ? 'block' : 'none';
	popupbox.style.display = display;
}

function onGetCurrentTime() {
	if (window.zwplayer) {
		var curTime = window.zwplayer.CurrentTime;
		
		document.getElementById('current-time-view').innerHTML = curTime;
	}
}

function onMultiStreamsOpen() {
	var inputBox = document.getElementById('multistream-urls-input');
	var urlText = inputBox.value;
		
	if (urlText.startsWith('{') || urlText.startsWith('[')) {
		try {
			var urls = JSON.parse(urlText);
			
			if (urls) {
				var urlInfo = {
					murls: urls,
					multistream: 1
				};
				
				onOpenUrl(urlInfo);
				
				document.getElementById('multistream-urls-box').style.display = 'none';
			}
		}
		catch(err) {
			console.error(err);
		}
	}
}

function onMultiStreamsCancel() {
	document.getElementById('multistream-urls-box').style.display = 'none';
}

function onload() {
	var url = location.protocol + '//' + location.hostname + ':8085/live/stream001.rtc';
	url = 'http://192.168.1.202:8088/vod/mp4/VMAP9RxJk5Fon5g83BxAmB1gmh8$hktnmQ04jMZ112.mp4';
	// url = 'http://192.168.1.136:1966/live/stream007.rtc';
	
	document.getElementById('url-box').value = url;
	
	setTimeout(function() {
		//alert('ok');
		onOpenUrl();
	}, 100);
	
	//new VConsole();
}

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);
	}
}

function onLoadChapters() {
	if (window.zwplayer) {
		window.zwplayer.setChapters('http://192.168.1.202/chapters.json?v=239');
	}
}

function onLoadSubtitle() {
	if (window.zwplayer) {
		var subtitleUrl = 'http://192.168.1.202:8088/data/VMAP9RxJk5Fon5g83BxAmB1gmh8$hktnmQ04jN53h2.srt';
		var subtitleURL_korean = 'http://192.168.1.202:8088/data/VMAP9RxJk5Fon5g83BxAmB1gmh8$hktnmQ04fyBug5oqhAgl.srt';
		var subtitleURL_japan = 'http://192.168.1.202:8088/data/VMAP9RxJk5Fon5g83BxAmB1gmh8$hktnmQ04fwx1kRQqhAgl.srt';
		
		window.zwplayer.addSubtitle(subtitleURL_korean, '1');
		
		window.zwplayer.addSubtitle(subtitleURL_japan, '2');
	}
}

function onRemoveSubtitle() {
	if (window.zwplayer) {
		window.zwplayer.removeSubtitle();
	}
}

window.channelinfo = {
	id: '001'
};

(function(root) {
    var wsChat = null;
    var logView = null;
    var wschat_server = 'ws://192.168.1.202:3000/';//"ws://192.168.1.202:9168/";
	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();

</script>
</head>

<body onload="onload()">
	<div class="player-wrap">
		<div class="time-info">
			<div class="time-item"><span>start:</span><span class="time-value" id="time-start"></span></div>
			<div class="time-item"><span>end:</span><span class="time-value" id="time-end"></span></div>
			<div class="time-item"><span>Time:</span><span class="time-value" id="time-total"></span></div>
		</div>
		<div class="vxplayer" id="player-holder">
			<!-- video id="videoview"> </video //-->
		</div>
		<div class="vxplayer-toolbar danmubar" id="player-dammu-controlbar"></div>
		<div class="vxplayer-toolbar" id="player-toolbar">
			<button class="btn" onclick="onOpenUrl();">Open</button>
			<button class="btn" onclick="onClose();">Close</button>
			<button class="btn" onclick="ondestroy();">Destroy</button>
			
			<div class="url-inputbox">
			<span class="label">URL:</span>
			<input type="text" id="url-box" value1="http://192.168.1.203:2085/live/stream001.rtc" 
			value1="http://192.168.1.202:8088/vod/mp4/VMAP9RxJk5Fon5g83BxAmB1gmh8$hktnmQ04jMZ112.mp4"
			value="http://192.168.1.202:8088/vod/mp4/VMAP95xJsnNWoRYi2RVstSpUpjQahlpslQoo3gJ7lR1sl48Z5kp5rRBqg0w77RZ300.mp4"
			>
			</div>
			<div class="opt-panel">
				<input type="checkbox" id="isLive-flag" value="1">
				<label for="isLive-flag">LIVE</label>
				
				<input type="checkbox" id="isUseFlv-flag" value="1" title="use flv player">
				<label for="isUseFlv-flag">Use Flv</label>
			</div>
			
			<div class="popup_box" id="multistream-urls-box">
				<textarea class="m-urls-box" id="multistream-urls-input"></textarea>
				<div class="popup-btoolbar">
					<button class="btn" onclick="onMultiStreamsOpen();">Open</button>
					<button class="btn" onclick="onMultiStreamsCancel();">Cancel</button>
				</div>
			</div>
		</div>
		<div class="vxplayer-toolbar" id="player-dammubar">
			<div class="url-inputbox">
			<span class="label">DANMU:</span>
			<input type="text" id="danmu-box" value="">
			</div>
			<button class="btn" onclick="onSendDanmu();">Send</button>
			<button class="btn" onclick="onDisableDanmu();">Disable Danmu</button>
			<button class="btn" onclick="onEnableDanmu();">Enable Danmu</button>
			<button class="btn" onclick="onLoadChapters();">Load Chapters</button>
		</div>
		
		<div class="vxplayer-toolbar" id="player-other">
			<button class="btn" onclick="onLoadSubtitle();">Load Subtitle</button>
			<button class="btn" onclick="onRemoveSubtitle();">Remove Subtitle</button>
			<button class="btn" onclick="onMultiStreams();">MStreams</button>
			<select class="cbx" id="stream_type_cbx">
				<option value="">No specified</option>
				<option value="httpflv">httpflv</option>
				<option value="hls">HLS</option>
				<option value="dash">DASH</option>
				<option value="mpegts">MPEGTS</option>
			</select>
			<button class="btn" onclick="onGetCurrentTime();">CurrentTime</button>
			<span id="current-time-view" class="current-time-view"></span>
		</div>
	</div>
</body>

</html>

上次更新: 2024/9/14 09:30:11