JSWebrtc.js +对应视频实例化

  • Post author:
  • Post category:其他


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



版权声明:本文为tr1098891979原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。