2.2 zwplayer调用示例
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>