<html> <meta charset="utf-8"> <head> <title>ZLM RTC demo</title> <script src="./ZLMRTCClient.js"></script> </head> <body> <div style="text-align: center;"> <div> <video id='video' controls autoplay style="text-align:left;"> Your browser is too old which doesn't support HTML5 video. </video> <video id='selfVideo' controls autoplay style="text-align:right;"> Your browser is too old which doesn't support HTML5 video. </video> </div> <div style="float: left; width:30%;"> <span>已存在的流列表,点击自动播放:</span> <ol id="olstreamlist"> <li>初始演示</li> <li>每秒自动刷新</li> </ol> </div> <div style="float: right; width: 70%"> <p> <label for="streamUrl">url:</label> <input type="text" style="co; width:70%" id='streamUrl' value="http://192.168.1.101/index/api/webrtc?app=live&stream=xiong&type=play"> </p> <p> <label for="simulcast">simulcast:</label> <input type="checkbox" id='simulcast'> </p> <p> <label for="useCamera">useCamera:</label> <input type="checkbox" id='useCamera' checked="checked"> </p> <p> <label for="audioEnable">audioEnable:</label> <input type="checkbox" id='audioEnable' checked="checked"> </p> <p> <label for="videoEnable">videoEnable:</label> <input type="checkbox" id='videoEnable' checked="checked"> </p> <p> <label for="method">method(play or push or echo):</label> <input type="radio" name="method" value="echo" >echo <input type="radio" name="method" value="push" >push <input type="radio" name="method" value="play" checked = true>play </p> <p> <label for="resolution">resolution:</label> <select id="resolution"> </select> </p> <p> <label for="datachannel">datachannel:</label> <input id='datachannel' name="datachannel" type="checkbox" value="0"> </p> <button onclick="start()">开始(start)</button> <button onclick="stop()">停止(stop)</button> <p> <label for="msgsend">msgsend:</label> <input type="text" id='msgsend' value="hello word !"> </p> <p> <label for="msgrecv">msgrecv:</label> <input type="text" id='msgrecv' disabled> </p> <button onclick="send()">发送(send by datachannel)</button> <button onclick="close()">关闭(close datachannel)</button> </div> </div> <script> var player = null var recvOnly = true var resArr = [] var ishttps = 'https:' == document.location.protocol ? true : false var isLocal = "file:" == document.location.protocol ? true : false const searchParams = new URL(document.location.href).searchParams; let type = searchParams.get('type'); if (!['echo','push','play'].includes(type)) { type = 'play'; } recvOnly = type === 'play'; const apiPath = `/index/api/webrtc?app=${searchParams.get('app') ?? 'live'}&stream=${searchParams.get('stream') ?? 'test'}&type=${type}`; if(!ishttps && !isLocal){ alert('本demo需要在https的网站访问 ,如果你要推流的话(this demo must access in site of https if you want push stream)') } const apiHost = isLocal ? "http://127.0.0.1" : `${document.location.protocol}//${window.location.host}`; var url = apiHost + apiPath; document.getElementById('streamUrl').value = url document.getElementsByName("method").forEach((el,idx) => { el.checked = el.value === type; el.onclick = function(e) { let url = new URL(document.getElementById('streamUrl').value); url.searchParams.set("type",el.value); document.getElementById('streamUrl').value = url.toString() if(el.value == "play"){ recvOnly = true; }else if(el.value == "echo"){ recvOnly = false; }else{ recvOnly = false; } }; }); ZLMRTCClient.GetAllScanResolution().forEach((r,i) => { opt = document.createElement('option'); opt.text = `${r.label}(${r.width}x${r.height})`; opt.value = r; if (1080*720 <= r.width * r.height && r.width * r.height <= 1280*720) { opt.selected = true; } document.getElementById("resolution").add(opt,null) }); function start_play(){ let elr = document.getElementById("resolution"); let res = elr.options[elr.selectedIndex].text.match(/\d+/g); let h = parseInt(res.pop()); let w = parseInt(res.pop()); player = new ZLMRTCClient.Endpoint( { element: document.getElementById('video'),// video 标签 debug: true,// 是否打印日志 zlmsdpUrl:document.getElementById('streamUrl').value,//流地址 simulcast:document.getElementById('simulcast').checked, useCamera:document.getElementById('useCamera').checked, audioEnable:document.getElementById('audioEnable').checked, videoEnable:document.getElementById('videoEnable').checked, recvOnly:recvOnly, resolution:{w:w,h:h}, usedatachannel:document.getElementById('datachannel').checked, } ); player.on(ZLMRTCClient.Events.WEBRTC_ICE_CANDIDATE_ERROR,function(e) {// ICE 协商出错 console.log('ICE 协商出错') }); player.on(ZLMRTCClient.Events.WEBRTC_ON_REMOTE_STREAMS,function(e) {//获取到了远端流,可以播放 console.log('播放成功',e.streams) }); player.on(ZLMRTCClient.Events.WEBRTC_OFFER_ANWSER_EXCHANGE_FAILED,function(e) {// offer anwser 交换失败 console.log('offer anwser 交换失败',e) stop(); }); player.on(ZLMRTCClient.Events.WEBRTC_ON_LOCAL_STREAM,function(s) {// 获取到了本地流 document.getElementById('selfVideo').srcObject=s; document.getElementById('selfVideo').muted = true; //console.log('offer anwser 交换失败',e) }); player.on(ZLMRTCClient.Events.CAPTURE_STREAM_FAILED,function(s) {// 获取本地流失败 console.log('获取本地流失败') }); player.on(ZLMRTCClient.Events.WEBRTC_ON_CONNECTION_STATE_CHANGE,function(state) {// RTC 状态变化 ,详情参考 https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/connectionState console.log('当前状态==>',state) }); player.on(ZLMRTCClient.Events.WEBRTC_ON_DATA_CHANNEL_OPEN,function(event) { console.log('rtc datachannel 打开 :',event) }); player.on(ZLMRTCClient.Events.WEBRTC_ON_DATA_CHANNEL_MSG,function(event) { console.log('rtc datachannel 消息 :',event.data) document.getElementById('msgrecv').value = event.data }); player.on(ZLMRTCClient.Events.WEBRTC_ON_DATA_CHANNEL_ERR,function(event) { console.log('rtc datachannel 错误 :',event) }); player.on(ZLMRTCClient.Events.WEBRTC_ON_DATA_CHANNEL_CLOSE,function(event) { console.log('rtc datachannel 关闭 :',event) }); } function start() { stop(); let elr = document.getElementById("resolution"); let res = elr.options[elr.selectedIndex].text.match(/\d+/g); let h = parseInt(res.pop()); let w = parseInt(res.pop()); if(document.getElementById('useCamera').checked && !recvOnly) { ZLMRTCClient.isSupportResolution(w,h).then(e=>{ start_play() }).catch(e=>{ alert("not support resolution") }); }else{ start_play() } } function stop() { if(player) { player.close(); player = null; var remote = document.getElementById('video'); if(remote) { remote.srcObject = null; remote.load(); } var local = document.getElementById('selfVideo'); local.srcObject = null; local.load(); } } function send(){ if(player){ //send msg refernece https://developer.mozilla.org/en-US/docs/Web/API/RTCDataChannel/send player.sendMsg(document.getElementById('msgsend').value) } } function close(){ if(player){ player.closeDataChannel() } } function on_click_to_play(app, stream) { console.log(`on_click_to_play: ${app}/${stream}`); var url = `${document.location.protocol}//${window.location.host}/index/api/webrtc?app=${app}&stream=${stream}&type=play`; document.getElementById('streamUrl').value = url; start(); } function clearStreamList() { let content = document.getElementById("olstreamlist"); while (content.hasChildNodes()) { content.removeChild(content.firstChild); } } function fillStreamList(json) { clearStreamList(); if (json.code != 0 || !json.data) { return; } let ss = {}; for (let o of json.data) { if (ss[o.app]) { ss[o.app].add(o.stream); } else { let set = new Set(); set.add(o.stream); ss[o.app] = set; } } for (let o in ss) { let app = o; for (let s of ss[o]) { if (s) { //console.log(app, s); let content = document.getElementById("olstreamlist"); let child = `<li app="${app}" stream="${s}" onmouseover="this.style.color='blue';" onclick="on_click_to_play('${app}', '${s}')">${app}/${s}</li>`; content.insertAdjacentHTML("beforeend", child); } } } } async function getData(url) { const response = await fetch(url, { method: 'GET' }); const data = await response.json(); //console.log(data); return data; } function get_media_list() { let url = document.location.protocol+"//"+window.location.host+"/index/api/getMediaList?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc"; let json = getData(url); json.then((json)=> fillStreamList(json)); } setInterval(() => { // get_media_list(); }, 5000); </script> </body> <script> </script> </html>