HTML
<div class="context"><video id="video-webrtc" controls autoplay poster="images/nosigna.png"></video>
</div>
CSS
#video-webrtc {width: 300px;min-height: 400px;
}
JS 处理视频资源流 资源流处理文件,只需要放入JS内即可
var JSWebrtc = {Player: null,VideoElement: null,CreateVideoElements: function () {var elements = document.querySelectorAll(".jswebrtc");for (var i = 0; i < elements.length; i++) {new JSWebrtc.VideoElement(elements[i])}},FillQuery: function (query_string, obj) {obj.user_query = {};if (query_string.length == 0)return;if (query_string.indexOf("?") >= 0)query_string = query_string.split("?")[1];var queries = query_string.split("&");for (var i = 0; i < queries.length; i++) {var query = queries[i].split("=");obj[query[0]] = query[1];obj.user_query[query[0]] = query[1]}if (obj.domain) obj.vhost = obj.domain},ParseUrl: function (rtmp_url) {var a = document.createElement("a");a.href = rtmp_url.replace("rtmp://", "http://").replace("webrtc://", "http://").replace("rtc://", "http://");var vhost = a.hostname;var app = a.pathname.substr(1, a.pathname.lastIndexOf("/") - 1);var stream = a.pathname.substr(a.pathname.lastIndexOf("/") + 1);app = app.replace("...vhost...", "?vhost=");if (app.indexOf("?") >= 0) {var params = app.substr(app.indexOf("?"));app = app.substr(0, app.indexOf("?"));if (params.indexOf("vhost=") > 0) {vhost = params.substr(params.indexOf("vhost=") + "vhost=".length);if (vhost.indexOf("&") > 0) {vhost = vhost.substr(0, vhost.indexOf("&"))}}}if (a.hostname == vhost) {var re = /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/;if (re.test(a.hostname))vhost = "__defaultVhost__"}var schema = "rtmp";if (rtmp_url.indexOf("://") > 0)schema = rtmp_url.substr(0, rtmp_url.indexOf("://"));var port = a.port;if (!port) {if (schema === "http") {port = 80} else if (schema === "https") {port = 443} else if (schema === "rtmp") {port = 1935} else if (schema === "webrtc" || schema === "rtc") {port = 1985}}var ret = { url: rtmp_url, schema: schema, server: a.hostname, port: port, vhost: vhost, app: app, stream: stream };JSWebrtc.FillQuery(a.search, ret);return ret},HttpPost: function (url, data) {return new Promise(function (resolve, reject) {var xhr = new XMLHttpRequest;xhr.onreadystatechange = function () {if (xhr.readyState === 4 && (xhr.status >= 200 && xhr.status < 300)) {var respone = JSON.parse(xhr.responseText);xhr.onreadystatechange = new Function;xhr = null; resolve(respone)}};xhr.open("POST", url, true);xhr.timeout = 5e3;xhr.responseType = "text";xhr.setRequestHeader("Content-Type", "application/json");xhr.send(data)})}};if (document.readyState === "complete") {JSWebrtc.CreateVideoElements()} else {document.addEventListener("DOMContentLoaded", JSWebrtc.CreateVideoElements)}JSWebrtc.VideoElement = function () {"use strict";var VideoElement = function (element) {var url = element.dataset.url;if (!url) {throw "VideoElement has no `data-url` attribute"}var addStyles = function (element, styles) {for (var name in styles) {element.style[name] = styles[name]}};this.container = element;addStyles(this.container,{ display: "inline-block", position: "relative", minWidth: "80px", minHeight: "80px" });this.video = document.createElement("video");this.video.width = 300;this.video.height = 300;addStyles(this.video,{ display: "block", width: "100%" });this.container.appendChild(this.video);this.playButton = document.createElement("div");this.playButton.innerHTML = VideoElement.PLAY_BUTTON;addStyles(this.playButton,{ zIndex: 2, position: "absolute", top: "0", bottom: "0", left: "0", right: "0", maxWidth: "75px", maxHeight: "75px", margin: "auto", opacity: "0.7", cursor: "pointer" });this.container.appendChild(this.playButton);var options = { video: this.video };for (var option in element.dataset) {try {options[option] = JSON.parse(element.dataset[option])} catch (err) {options[option] = element.dataset[option]}}this.player = new JSWebrtc.Player(url, options);element.playerInstance = this.player;if (options.poster && !options.autoplay) {options.decodeFirstFrame = false;this.poster = new Image;this.poster.src = options.poster;this.poster.addEventListener("load", this.posterLoaded);addStyles(this.poster, { display: "block", zIndex: 1, position: "absolute", top: 0, left: 0, bottom: 0, right: 0 });this.container.appendChild(this.poster)}if (!this.player.options.streaming) {this.container.addEventListener("click", this.onClick.bind(this))}if (options.autoplay) {this.playButton.style.display = "none"}if (this.player.audioOut && !this.player.audioOut.unlocked) {var unlockAudioElement = this.container;if (options.autoplay) {this.unmuteButton = document.createElement("div");this.unmuteButton.innerHTML = VideoElement.UNMUTE_BUTTON;addStyles(this.unmuteButton, { zIndex: 2, position: "absolute", bottom: "10px", right: "20px", width: "75px", height: "75px", margin: "auto", opacity: "0.7", cursor: "pointer" });this.container.appendChild(this.unmuteButton);unlockAudioElement = this.unmuteButton}this.unlockAudioBound = this.onUnlockAudio.bind(this, unlockAudioElement);unlockAudioElement.addEventListener("touchstart", this.unlockAudioBound, false);unlockAudioElement.addEventListener("click", this.unlockAudioBound, true)}};VideoElement.prototype.onUnlockAudio = function (element, ev) {if (this.unmuteButton) {ev.preventDefault();ev.stopPropagation()}this.player.audioOut.unlock(function () {if (this.unmuteButton) {this.unmuteButton.style.display = "none"}element.removeEventListener("touchstart", this.unlockAudioBound);element.removeEventListener("click", this.unlockAudioBound)}.bind(this))};VideoElement.prototype.onClick = function (ev) {if (this.player.isPlaying) {this.player.pause();this.playButton.style.display = "block"} else {this.player.play();this.playButton.style.display = "none";if (this.poster) {this.poster.style.display = "none"}}};VideoElement.PLAY_BUTTON = '<svg style="max-width: 75px; max-height: 75px;" ' + 'viewBox="0 0 200 200" alt="Play video">' + '<circle cx="100" cy="100" r="90" fill="none" ' + 'stroke-width="15" stroke="#fff"/>' + '<polygon points="70, 55 70, 145 145, 100" fill="#fff"/>' + "</svg>";VideoElement.UNMUTE_BUTTON = '<svg style="max-width: 75px; max-height: 75px;" viewBox="0 0 75 75">' + '<polygon class="audio-speaker" stroke="none" fill="#fff" ' + 'points="39,13 22,28 6,28 6,47 21,47 39,62 39,13"/>' + '<g stroke="#fff" stroke-width="5">' + '<path d="M 49,50 69,26"/>' + '<path d="M 69,50 49,26"/>' + "</g>" + "</svg>";return VideoElement}();JSWebrtc.Player = function () {"use strict";var Player = function (url, options) {this.options = options || {};if (!url.match(/^webrtc?:\/\//)) {throw "JSWebrtc just work with webrtc"} if (!this.options.video) {throw "VideoElement is null"} this.urlParams = JSWebrtc.ParseUrl(url);this.pc = null;this.autoplay = !!options.autoplay || false;this.paused = true;if (this.autoplay) this.options.video.muted = true; this.startLoading()};Player.prototype.startLoading = function () {var _self = this;if (_self.pc) {_self.pc.close()}_self.pc = new RTCPeerConnection(null);_self.pc.ontrack = function (event) {_self.options.video["srcObject"] = event.streams[0]};_self.pc.addTransceiver("audio", { direction: "recvonly" });_self.pc.addTransceiver("video", { direction: "recvonly" });_self.pc.createOffer().then(function (offer) {return _self.pc.setLocalDescription(offer).then(function () {return offer})}).then(function (offer) {return new Promise(function (resolve, reject) {var port = _self.urlParams.port || 1985;var api = _self.urlParams.user_query.play || "/rtc/v1/play/";if (api.lastIndexOf("/") != api.length - 1) {api += "/"}var url = "http://" + _self.urlParams.server + ":" + port + api;for (var key in _self.urlParams.user_query) {if (key != "api" && key != "play") {url += "&" + key + "=" + _self.urlParams.user_query[key]}}var data = { api: url, streamurl: _self.urlParams.url, clientip: null, sdp: offer.sdp };// console.log("offer: " + JSON.stringify(data));JSWebrtc.HttpPost(url, JSON.stringify(data)).then(function (res) {// console.log("answer: " + JSON.stringify(res)); resolve(res.sdp)},function (rej) { reject(rej) })})}).then(function (answer) {return _self.pc.setRemoteDescription(new RTCSessionDescription({ type: "answer", sdp: answer }))}).catch(function (reason) { throw reason }); if (this.autoplay) {this.play()}};Player.prototype.play = function (ev) {if (this.animationId) {return} this.animationId = requestAnimationFrame(this.update.bind(this));this.paused = false};Player.prototype.pause = function (ev) {if (this.paused) {return} cancelAnimationFrame(this.animationId);this.animationId = null;this.isPlaying = false;this.paused = true;this.options.video.pause();if (this.options.onPause) {this.options.onPause(this)}};Player.prototype.stop = function (ev) {this.pause()};Player.prototype.destroy = function () {this.pause();this.pc && this.pc.close() && this.pc.destroy();this.audioOut && this.audioOut.destroy()};Player.prototype.update = function () {this.animationId = requestAnimationFrame(this.update.bind(this));if (this.options.video.readyState < 4) {return} if (!this.isPlaying) {this.isPlaying = true;this.options.video.play;//this.options.video.play() //自己修改部分 用处未知if (this.options.onPlay) {this.options.onPlay(this)}}};return Player}();
JS视频实例化对象 在需要实例化视频播放的位置插入即可
var video = document.getElementById('video-webrtc');
var url = ‘你的视频地址’;
var player = new JSWebrtc.Player(url, {video: video,autoplay: true,onPlay: (obj) => {// video.muted = false //此项设置静音播放// console.log("start play")}
});