| | |
| | | .top-buffer { |
| | | margin-top: 10px; |
| | | } |
| | | |
| | | .container { |
| | | border: 2px solid #1b6d85; |
| | | padding: 15px; |
| | |
| | | function commondMethod(url, code, enable) { |
| | | cameraId = $('#selectDev option:selected').val(); |
| | | chanNo = $('#selectChn option:selected').val(); |
| | | opt = {"cameraId": cameraId, "chanNo": chanNo, "speed": 4, "enable": enable, "code": code}; |
| | | opt = {"cameraId": cameraId, "chanNo": chanNo, "speed": 8, "enable": enable, "code": code}; |
| | | $.ajax({ |
| | | headers: { |
| | | 'Accept': 'application/json', |
| | |
| | | type: "get", |
| | | dataType: "json", |
| | | success: function (data) { |
| | | realView(data.data.webrtcUrl + "/", e.target.id); |
| | | realView(data.data.webrtcUrl + "/"); |
| | | } |
| | | }) |
| | | }); |
| | |
| | | const retryPause = 2000; |
| | | |
| | | const video = document.getElementById('video'); |
| | | const message = document.getElementById('message'); |
| | | |
| | | let nonAdvertisedCodecs = []; |
| | | let pc = null; |
| | |
| | | let offerData = ''; |
| | | let queuedCandidates = []; |
| | | let defaultControls = false; |
| | | |
| | | const setMessage = (str) => { |
| | | if (str !== '') { |
| | | video.controls = false; |
| | | } else { |
| | | video.controls = defaultControls; |
| | | } |
| | | message.innerText = str; |
| | | }; |
| | | let whepUrl = ''; |
| | | |
| | | const unquoteCredential = (v) => ( |
| | | JSON.parse(`"${v}"`) |
| | |
| | | }; |
| | | |
| | | const loadStream = () => { |
| | | console.log('loadStream'); |
| | | requestICEServers(); |
| | | }; |
| | | |
| | |
| | | |
| | | const onError = (err) => { |
| | | if (restartTimeout === null) { |
| | | setMessage(err + ', retrying in some seconds'); |
| | | |
| | | if (pc !== null) { |
| | | pc.close(); |
| | |
| | | loadStream(); |
| | | }, retryPause); |
| | | |
| | | if (sessionUrl) { |
| | | fetch(sessionUrl, { |
| | | if (this.sessionUrl) { |
| | | fetch(this.sessionUrl, { |
| | | method: 'DELETE', |
| | | }); |
| | | } |
| | | sessionUrl = ''; |
| | | this.sessionUrl = ''; |
| | | |
| | | queuedCandidates = []; |
| | | } |
| | | }; |
| | | |
| | | const sendLocalCandidates = (candidates) => { |
| | | fetch(sessionUrl + window.location.search, { |
| | | fetch(new URL('whep', this.whepUrl), { |
| | | method: 'PATCH', |
| | | headers: { |
| | | 'Content-Type': 'application/trickle-ice-sdpfrag', |
| | |
| | | } |
| | | |
| | | if (evt.candidate !== null) { |
| | | if (sessionUrl === '') { |
| | | if (this.sessionUrl === '') { |
| | | queuedCandidates.push(evt.candidate); |
| | | } else { |
| | | sendLocalCandidates([evt.candidate]) |
| | | //sendLocalCandidates([evt.candidate]) |
| | | } |
| | | } |
| | | }; |
| | |
| | | if (restartTimeout !== null) { |
| | | return; |
| | | } |
| | | |
| | | pc.setRemoteDescription(new RTCSessionDescription({ |
| | | type: 'answer', |
| | | sdp, |
| | |
| | | }; |
| | | |
| | | const sendOffer = (offer) => { |
| | | fetch(new URL('whep', window.location.href) + window.location.search, { |
| | | fetch(new URL('whep', this.whepUrl), { |
| | | method: 'POST', |
| | | headers: { |
| | | 'Content-Type': 'application/sdp', |
| | |
| | | case 404: |
| | | throw new Error('stream not found'); |
| | | case 400: |
| | | return res.json().then((e) => { throw new Error(e.error); }); |
| | | return res.json().then((e) => { |
| | | throw new Error(e.error); |
| | | }); |
| | | default: |
| | | throw new Error(`bad status code ${res.status}`); |
| | | } |
| | | |
| | | sessionUrl = new URL(res.headers.get('location'), window.location.href).toString(); |
| | | |
| | | this.sessionUrl = new URL(res.headers.get('location'), new URL(this.whepUrl).origin).toString(); |
| | | return res.text() |
| | | .then((sdp) => onRemoteAnswer(sdp)); |
| | | }) |
| | |
| | | }; |
| | | |
| | | const onTrack = (evt) => { |
| | | setMessage(''); |
| | | |
| | | video.srcObject = evt.streams[0]; |
| | | }; |
| | | |
| | | const requestICEServers = () => { |
| | | fetch(new URL('whep', window.location.href) + window.location.search, { |
| | | fetch(new URL('whep', this.whepUrl), { |
| | | method: 'OPTIONS', |
| | | }) |
| | | .then((res) => { |
| | |
| | | }); |
| | | }; |
| | | |
| | | const parseBoolString = (str, defaultVal) => { |
| | | str = (str || ''); |
| | | |
| | | if (['1', 'yes', 'true'].includes(str.toLowerCase())) { |
| | | return true; |
| | | } |
| | | if (['0', 'no', 'false'].includes(str.toLowerCase())) { |
| | | return false; |
| | | } |
| | | return defaultVal; |
| | | const init = () => { |
| | | getNonAdvertisedCodecs(); |
| | | }; |
| | | |
| | | const loadAttributesFromQuery = () => { |
| | | const params = new URLSearchParams(window.location.search); |
| | | video.controls = parseBoolString(params.get('controls'), true); |
| | | video.muted = parseBoolString(params.get('muted'), true); |
| | | video.autoplay = parseBoolString(params.get('autoplay'), true); |
| | | video.playsInline = parseBoolString(params.get('playsinline'), true); |
| | | defaultControls = video.controls; |
| | | }; |
| | | |
| | | |
| | | function realView(whepUrl, videoId) { |
| | | function realView(whepUrl) { |
| | | console.log(whepUrl) |
| | | webrtcClient = new WHEPClient(whepUrl, videoId); |
| | | this.whepUrl = whepUrl |
| | | init(); |
| | | } |
| | | </script> |
| | | </body> |