网页中播放RTSP(5) WebSocket播放视频

WebSocket播放视频是结合MediaSource的

总结:通过WebSocket获取视频流,提供给MediaSource,MediaSource结合video标签,播放视频。

这一套完全就是基于浏览器支持MediaSourceExtension(MSE)的,而我最终的目的是在unity3d里面播放视频,加入uinty3d不支持MediaSource和video标签,怎么折腾都没用。可能最后还会变成在uinty里面调要能够网页上的video来播放视频,调整一下窗口的大小。

在AppStore里面找了一下,没找到合适的资料,有个Embedded Browser说是完全支持HTML5包括视频,但是它的平台是windows,ios,linux,其实就是一个浏览器嵌入到unity程序中,没有webgl,而webgl其实就在浏览器里面了。这个在淘宝上有,3.0还买到35或者80。

接下来三个方向 1.WebRTC 2.Unity调用浏览器 3.解码播放

 

参考:MediaSource

1.理解并修改h5splayer.js

将文件和github上面的h5media.js以及h5sevent.js比较,将混淆后的变量名和方法名还原回去

function H5sPlayerWS(conf) {
    var s;
    this.sourceBuffer, this.buffer = [], this._mediaSource, this.video, this.wsSocket, this.checkSourceBufferTimerId, this.keepAliveTimerId, this.h = 0, this.l = 0,
        this.u = 0, this.S = false, this.v = false, this.p = false, this.strCodec, this._conf = conf, console.log("Websocket Conf:",
            conf), this._videoId = conf.videoid, this._pbconf = conf.pbconf, this._token = conf.token, void 0 === this._videoId ? (this._videoElemet = conf.videodom,
                console.log(conf.token, "use dom directly")) : (this._videoElemet = document.getElementById(this._videoId), console.log(conf.token,
                    "use videoid")), this.video = this._videoElemet, null != this._pbconf && "false" == this._pbconf.showposter || (s = this._conf.protocol + "//" + this._conf.host + this._conf.rootpath + "api/v1/GetImage?token=" + this._token + "&session=" + this._conf.session,
                        console.log(conf.token, "connect src"), this._videoElemet.setAttribute("poster", s))
}
function H5sPlayerRTC(conf) {
    var s;
    this.wsSocket, this.checkSourceBufferTimerId, this.keepAliveTimerId, this.h = 0, this.l = 0, this.u = 0, this.S = false, this.v = false, this._conf = conf,
        this._videoId = conf.videoid, this._pbconf = conf.pbconf, this._token = conf.token, void 0 === this._videoId ? (this._videoElemet = conf.videodom,
            console.log(conf.token, "use dom directly")) : (this._videoElemet = document.getElementById(this._videoId), console.log(conf.token,
                "use videoid")), this.video = this._videoElemet, this.R = null, this.I = {
                    optional: [{
                        DtlsSrtpKeyAgreement: true
                    }]
                },
        this.A = {
            mandatory: {
                offerToReceiveAudio: true, offerToReceiveVideo: true
            }
        },
        this.T = {
            M: []
        },
        this.O = [], null != this._pbconf && "false" == this._pbconf.showposter || (s = this._conf.protocol + "//" + this._conf.host + this._conf.rootpath + "api/v1/GetImage?token=" + this._token + "&session=" + this._conf.session,
            console.log("connect src", conf.token), this._videoElemet.setAttribute("poster", s))
}
function createRTCSessionDescription(t) {
    return console.log("createRTCSessionDescription "), new RTCSessionDescription(t)
}
function H5sPlayerHls(t) {
    this.wsSocket, this.keepAliveTimerId, this._conf = t, this._videoId = t.videoid, this._token = t.token, this.J, this.N = t.hlsver, void 0 === this._videoId ? (this._videoElemet = t.videodom,
        console.log(t.token, "use dom directly")) : (this._videoElemet = document.getElementById(this._videoId), console.log(t.token,
            "use videoid")), this.g = this._videoElemet, this.g.type = "application/x-mpegURL", this.B = 0, this.U = 0;
    var s = this._conf.protocol + "//" + window.location.host + "/api/v1/GetImage?token=" + this._token + "&session=" + this._conf.session;
    this._videoElemet.setAttribute("poster", s)
}
function H5sPlayerAudio(t) {
    this.buffer = [], this.wsSocket, this.S = false, this.v = false, this._conf = t, console.log("Aduio Player Conf:",
        t), this._token = t.token, this._ = new AudioContext
}
function H5sPlayerAudBack(t) {
    this.buffer = [], this.wsSocket, this.S = false, this.v = false, this._conf = t, this.L = 0, this.D = 48e3, this.G = false,
        console.log("Aduio Back Conf:", t), this._token = t.token, this._ = new AudioContext, console.log("sampleRate",
            this._.sampleRate), this.K()
}
function float32ToInt16(t) {
    for (var s = t.length, e = new Int16Array(s); s--;) {
        e[s] = 32767 * Math.min(1, t[s]);
    }
    return e
}
H5sPlayerWS.prototype.reconnectFunction = function () {
    console.error('reconnectFunction'+new Date());
    true === this.S && (console.log("Reconnect..."), this.setupWebSocket(this._token), this.S = false)
},
    H5sPlayerWS.prototype.getWebSocket = function (url) {
        console.log('>> H5sPlayerWS.prototype.getWebSocket');
        var ws;
        try {
            "http:" == this._conf.protocol && (ws = "undefined" != typeof MozWebSocket ? new MozWebSocket("ws://" + this._conf.host + url) : new WebSocket("ws://" + this._conf.host + url)),
                "https:" == this._conf.protocol && (console.log(this._conf.host), ws = "undefined" != typeof MozWebSocket ? new MozWebSocket("wss://" + this._conf.host + url) : new WebSocket("wss://" + this._conf.host + url)),
                console.log(this._conf.host)
        }
        catch (err) {
            return void alert("error")
        }
        return ws;
    },
    H5sPlayerWS.prototype.readFromBuffer = function () {
        //console.error('F');
        //console.log(this.sourceBuffer);
        if (null !== this.sourceBuffer && void 0 !== this.sourceBuffer) {
            if (0 !== this.buffer.length && !this.sourceBuffer.updating) {
                try {
                    var first = this.buffer.shift(), buff = new Uint8Array(first);
                    this.sourceBuffer.appendBuffer(buff)
                }
                catch (err) {
                    console.log(err)
                }
            }
        }
        else {
            console.log(this.sourceBuffer, "is null or undefined");
        }
        //console.log(this.sourceBuffer);
    },
    H5sPlayerWS.prototype.keepAlive = function () {
        //console.error('X keepaliveTimer');
        //console.log(this);
        //console.log(this.wsSocket);
        try {
            var t = {
                cmd: "H5_KEEPALIVE"
            };
            this.wsSocket.send(JSON.stringify(t))
        }
        catch (err) {
            console.log(err)
        }
    },

    //获取websocket数据
    H5sPlayerWS.prototype.onReceived = function (msg) {
        //console.log('>> H5sPlayerWS.prototype.onReceived');
        //console.log(msg.data);
        //var ttt=String.fromCharCode.apply(null, new Uint8Array(msg.data));
        //console.log(ttt);
        return msg.data, ArrayBuffer, "string" == typeof msg.data ? (console.log("string"), void (null != this._pbconf && null != this._pbconf.callback && this._pbconf.callback(msg.data,
            this._pbconf.userdata))) : true !== this.v ? false === this.p ? (this.strCodec = String.fromCharCode.apply(null, new Uint8Array(msg.data)),
                this.initMediaSource(this), void (this.p = true)) : (this.buffer.push(msg.data), void this.readFromBuffer()) : void 0;
    },
    
    H5sPlayerWS.prototype.initMediaSource = function (player) {
        console.log('initMediaSource');
        try {
            window.MediaSource = window.MediaSource || window.WebKitMediaSource, window.MediaSource || console.log("MediaSource API is not available");
            var codec = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';
            "MediaSource" in window && MediaSource.isTypeSupported(codec) ? console.log("MIME type or codec: ",
                codec) : console.log("Unsupported MIME type or codec: ", codec), player._mediaSource = new window.MediaSource, player.video.autoplay = true,
                console.log(player._videoId);
            player.video.src = window.URL.createObjectURL(player._mediaSource), player.video.play(), player._mediaSource.addEventListener("sourceopen",
                player.onMediaSourceOpen.bind(player), false)
        }
        catch (err) {
            console.log(err)
        }
    },
    H5sPlayerWS.prototype.onMediaSourceOpen = function () {
        console.log("Add SourceBuffer"), this.sourceBuffer = this._mediaSource.addSourceBuffer(this.strCodec), this._mediaSource.duration = 1 / 0,
            this._mediaSource.removeEventListener("sourceopen", this.onMediaSourceOpen, false), this.sourceBuffer.addEventListener("updateend",
                this.readFromBuffer.bind(this), false);
    },
    H5sPlayerWS.prototype.setupWebSocket = function (token) {
        console.log('>> H5sPlayerWS.prototype.setupWebSocket');
        this.video.autoplay = true;
        var url = "api/v1/h5swsapi", prof = "main";
        if (void 0 === this._conf.streamprofile || (prof = this._conf.streamprofile), void 0 === this._pbconf) {
            url = this._conf.rootpath + url + "?token=" + token + "&profile=" + prof + "&session=" + this._conf.session;
        }
        else {
            var i = "false", o = "fake";
            void 0 === this._pbconf.serverpb || (i = this._pbconf.serverpb), void 0 === this._pbconf.filename || (o = this._pbconf.filename),
                url = this._conf.rootpath + url + "?token=" + token + "&playback=true&profile=" + prof + "&serverpb=" + i + "&begintime=" + encodeURIComponent(this._pbconf.begintime) + "&endtime=" + encodeURIComponent(this._pbconf.endtime) + "&filename=" + o + "&session=" + this._conf.session
        }
        this._conf.session, console.log(url), this.wsSocket = this.getWebSocket(url), console.log("setupWebSocket", this.wsSocket), this.wsSocket.binaryType = "arraybuffer",
            (this.wsSocket._player = this).wsSocket.onmessage = this.onReceived.bind(this), this.wsSocket.onopen = function () {
                console.log("wsSocket.onopen", this._player), this._player.checkSourceBufferTimerId = setInterval(this._player.checkSourceBuffer.bind(this._player), 1e4),
                    this._player.keepAliveTimerId = setInterval(this._player.keepAlive.bind(this._player), 1e3), null != this._player._pbconf && "true" === this._player._pbconf.autoplay && this._player.start();
            },
            this.wsSocket.onclose = function () {
                console.log("wsSocket.onclose", this._player), true === this._player.v ? console.log("wsSocket.onclose disconnect") : this._player.S = true,
                    this._player.cleanupSourceBuffer(this._player), this._player.cleanupWebSocket(this._player), this._player.strCodec = "", this._player.p = false;
            }
    },
    H5sPlayerWS.prototype.cleanupSourceBuffer = function (player) {
        console.log("Cleanup Source Buffer", player);
        try {
            player.sourceBuffer.removeEventListener("updateend", player.readFromBuffer, false), player.sourceBuffer.abort(), document.documentMode || /Edge/.test(navigator.userAgent) ? console.log("IE or EDGE!") : player._mediaSource.removeSourceBuffer(player.sourceBuffer),
                player.sourceBuffer = null, player._mediaSource = null, player.buffer = []
        }
        catch (err) {
            console.log(err)
        }
    },
    H5sPlayerWS.prototype.cleanupWebSocket = function (player) {
        
        console.log("CleanupWebSocket", player);
        //console.error(player);
        clearInterval(player.keepAliveTimerId), clearInterval(player.checkSourceBufferTimerId), player.h = 0, player.l = 0, player.u = 0;
    },
    H5sPlayerWS.prototype.checkSourceBuffer = function () {
        if (void 0 === this._pbconf) {
            true === this.v && (console.log("CheckSourceBuffer has been disconnect", this), clearInterval(this.keepAliveTimerId),
                clearInterval(this.checkSourceBufferTimerId), clearInterval(this.reconnectTimerId));
            try {
                if (console.log("CheckSourceBuffer", this), this.sourceBuffer.buffered.length <= 0) {
                    if (this.h++ , 8 < this.h) {
                        return console.log("CheckSourceBuffer Close 1"), void this.wsSocket.close();
                    }
                }
                else {
                    this.h = 0;
                    this.sourceBuffer.buffered.start(0);
                    var t = this.sourceBuffer.buffered.end(0), s = t - this.video.currentTime;
                    if (5 < s || s < 0) {
                        return console.log("CheckSourceBuffer Close 2", s), void this.wsSocket.close();
                    }
                    if (t == this.l) {
                        if (this.u++ , 3 < this.u) {
                            return console.log("CheckSourceBuffer Close 3"), void this.wsSocket.close();
                        }
                    }
                    else {
                        this.u = 0;
                    }
                    this.l = t;
                }
            }
            catch (err) {
                console.log(err)
            }
        }
    },
    H5sPlayerWS.prototype.connect = function () {
        this.setupWebSocket(this._token);
        this.reconnectTimerId = setInterval(this.reconnectFunction.bind(this), 3e3);//没3s重连一次。
    },
    H5sPlayerWS.prototype.disconnect = function () {
        console.log("disconnect", this), this.v = true, clearInterval(this.reconnectTimerId), null != this.wsSocket && (this.wsSocket.close(),
            this.wsSocket = null), console.log("disconnect", this);
    },
    H5sPlayerWS.prototype.start = function () {
        try {
            var t = {
                cmd: "H5_START"
            };
            this.wsSocket.send(JSON.stringify(t))
        }
        catch (err) {
            console.log(err)
        }
    },
    H5sPlayerWS.prototype.pause = function () {
        try {
            var t = {
                cmd: "H5_PAUSE"
            };
            this.wsSocket.send(JSON.stringify(t))
        }
        catch (err) {
            console.log(err)
        }
    },
    H5sPlayerWS.prototype.resume = function () {
        try {
            var t = {
                cmd: "H5_RESUME"
            };
            this.wsSocket.send(JSON.stringify(t))
        }
        catch (err) {
            console.log(err)
        }
    },
    H5sPlayerWS.prototype.seek = function (t) {
        try {
            var s = {
                cmd: "H5_SEEK"
            };
            s.nSeekTime = t, this.wsSocket.send(JSON.stringify(s))
        }
        catch (err) {
            console.log(err)
        }
    },
    H5sPlayerWS.prototype.speed = function (t) {
        try {
            var s = {
                cmd: "H5_SPEED"
            };
            s.nSpeed = t, this.wsSocket.send(JSON.stringify(s))
        }
        catch (err) {
            console.log(err)
        }
    },
    H5sPlayerRTC.prototype.reconnectFunction = function () {
        true === this.S && (console.log("Reconnect..."), this.j(this._token), this.S = false)
    },
    H5sPlayerRTC.prototype.q = function (t) {
        var s;
        console.log("H5SWebSocketClient");
        try {
            "http:" == this._conf.protocol && (s = "undefined" != typeof MozWebSocket ? new MozWebSocket("ws://" + this._conf.host + t) : new WebSocket("ws://" + this._conf.host + t)),
                "https:" == this._conf.protocol && (console.log(this._conf.host), s = "undefined" != typeof MozWebSocket ? new MozWebSocket("wss://" + this._conf.host + t) : new WebSocket("wss://" + this._conf.host + t)),
                console.log(this._conf.host)
        }
        catch (err) {
            return void alert("error")
        }
        return s;
    },
    H5sPlayerRTC.prototype.keepAlive = function () {
        try {
            var t = {
                type: "keepalive"
            };
            this.wsSocket.send(JSON.stringify(t))
        }
        catch (err) {
            console.log(err)
        }
    },
    H5sPlayerRTC.prototype.nt = function (t) {
        if (t.candidate) {
            var s;
            console.log("onIceCandidate currentice", t.candidate), s = t.candidate, console.log("onIceCandidate currentice",
                s, JSON.stringify(s));
            var e = JSON.parse(JSON.stringify(s));
            e.type = "remoteice", console.log("onIceCandidate currentice new", e, JSON.stringify(e)), this.wsSocket.send(JSON.stringify(e))
        }
        else {
            console.log("End of candidates.");
        }
    },
    H5sPlayerRTC.prototype.ht = function (t) {
        var s;
        console.log("Remote track added:" + JSON.stringify(t)), s = t.ct ? t.ct[0] : t.stream;
        var e = this._videoElemet;
        e.src = URL.createObjectURL(s), e.play();
    },
    H5sPlayerRTC.prototype.rt = function () {
        console.log("createPeerConnection  config: " + JSON.stringify(this.T) + " option:" + JSON.stringify(this.I));
        var s = new RTCPeerConnection(this.T, this.I), e = this;
        return s.onicecandidate = function (t) {
            e.nt.call(e, t)
        },
            void 0 !== s.lt ? s.lt = function (t) {
                e.ht.call(e, t)
            }
                : s.onaddstream = function (t) {
                    e.ht.call(e, t)
                },
            s.oniceconnectionstatechange = function (t) {
                console.log("oniceconnectionstatechange  state: " + s.iceConnectionState)
            },
            console.log("Created RTCPeerConnnection with config: " + JSON.stringify(this.T) + "option:" + JSON.stringify(this.I)),
            s
    },
    H5sPlayerRTC.prototype.at = function (t) {
        console.log("ProcessRTCOffer", t);
        try {
            this.R = this.rt(), this.O.length = 0;
            var s = this;
            this.R.setRemoteDescription(createRTCSessionDescription(t)), this.R.createAnswer(this.A).then(function (t) {
                console.log("Create answer:" + JSON.stringify(t)), s.R.setLocalDescription(t, function () {
                    console.log("ProcessRTCOffer createAnswer", t), s.s.send(JSON.stringify(t))
                },
                    function () { })
            },
                function (t) {
                    alert("Create awnser error:" + JSON.stringify(t))
                })
        }
        catch (err) {
            this.disconnect(), alert("connect error: " + err)
        }
    },
    H5sPlayerRTC.prototype.ut = function (t) {
        console.log("ProcessRemoteIce", t);
        try {
            var s = new RTCIceCandidate({
                sdpMLineIndex: t.sdpMLineIndex, candidate: t.candidate
            });
            console.log("ProcessRemoteIce", s), console.log("Adding ICE candidate :" + JSON.stringify(s)),
                this.R.addIceCandidate(s, function () {
                    console.log("addIceCandidate OK")
                },
                    function (t) {
                        console.log("addIceCandidate error:" + JSON.stringify(t))
                    })
        }
        catch (err) {
            alert("connect ProcessRemoteIce error: " + err)
        }
    },
    H5sPlayerRTC.prototype.onReceived = function (msg) {
        msg.data, ArrayBuffer, msg.data, console.log("RTC received ", msg.data);
        var s = JSON.parse(msg.data);
        return console.log("Get Message type ", s.type), "offer" === s.type ? (console.log("Process Message type ",
            s.type), void this.at(s)) : "remoteice" === s.type ? (console.log("Process Message type ", s.type),
                void this.ut(s)) : void (null != this._pbconf && null != this._pbconf.callback && this._pbconf.callback(msg.data, this._pbconf.userdata))
    },
    H5sPlayerRTC.prototype.j = function (t) {
        this.video.autoplay = true;
        var s = "api/v1/h5srtcapi", e = "main";
        if (void 0 === this._conf.streamprofile || (e = this._conf.streamprofile), void 0 === this._pbconf) {
            s = this._conf.rootpath + s + "?token=" + t + "&profile=" + e + "&session=" + this._conf.session;
        }
        else {
            var i = "false", o = "fake";
            void 0 === this._pbconf.serverpb || (i = this._pbconf.serverpb), void 0 === this._pbconf.filename || (o = this._pbconf.filename),
                s = this._conf.rootpath + s + "?token=" + t + "&playback=true&profile=" + e + "&serverpb=" + i + "&begintime=" + encodeURIComponent(this._pbconf.begintime) + "&endtime=" + encodeURIComponent(this._pbconf.endtime) + "&filename=" + o + "&session=" + this._conf.session
        }
        console.log(s), this.wsSocket = this.q(s), console.log("setupWebSocket", this.wsSocket), this.wsSocket.binaryType = "arraybuffer",
            (this.wsSocket._player = this).wsSocket.onmessage = this.onReceived.bind(this), this.wsSocket.onopen = function () {
                console.log("wsSocket.onopen", this._player);
                var t = {
                    type: "open"
                };
                this._player.s.send(JSON.stringify(t)), this._player.keepAliveTimerId = setInterval(this._player.keepAlive.bind(this._player), 1e3), null != this._player._pbconf && "true" === this._player._pbconf.autoplay && this._player.start();
            },
            this.wsSocket.onclose = function () {
                console.log("wsSocket.onclose", this._player), true === this._player.v ? console.log("wsSocket.onclose disconnect") : this._player.S = true,
                    this._player.cleanupWebSocket(this._player)
            }
    },
    H5sPlayerRTC.prototype.cleanupWebSocket = function (t) {
        console.log("CleanupWebSocket", t), clearInterval(t.keepAliveTimerId), t.h = 0, t.l = 0, t.u = 0;
    },
    H5sPlayerRTC.prototype.connect = function () {
        this.j(this._token), this.reconnectTimerId = setInterval(this.reconnectFunction.bind(this), 3e3);
    },
    H5sPlayerRTC.prototype.disconnect = function () {
        console.log("disconnect", this), this.v = true, clearInterval(this.reconnectTimerId), null != this.wsSocket && (this.wsSocket.close(),
            this.wsSocket = null), console.log("disconnect", this);
    },
    H5sPlayerRTC.prototype.start = function () {
        try {
            var t = {
                cmd: "H5_START"
            };
            this.wsSocket.send(JSON.stringify(t))
        }
        catch (err) {
            console.log(err)
        }
    },
    H5sPlayerRTC.prototype.pause = function () {
        try {
            var t = {
                cmd: "H5_PAUSE"
            };
            this.wsSocket.send(JSON.stringify(t))
        }
        catch (err) {
            console.log(err)
        }
    },
    H5sPlayerRTC.prototype.resume = function () {
        try {
            var t = {
                cmd: "H5_RESUME"
            };
            this.wsSocket.send(JSON.stringify(t))
        }
        catch (err) {
            console.log(err)
        }
    },
    H5sPlayerRTC.prototype.seek = function (t) {
        try {
            var s = {
                cmd: "H5_SEEK"
            };
            s.nSeekTime = t, this.wsSocket.send(JSON.stringify(s))
        }
        catch (err) {
            console.log(err)
        }
    },
    H5sPlayerRTC.prototype.speed = function (t) {
        try {
            var s = {
                cmd: "H5_SPEED"
            };
            s.nSpeed = t, this.wsSocket.send(JSON.stringify(s))
        }
        catch (err) {
            console.log(err)
        }
    },
    H5sPlayerHls.prototype.q = function (t) {
        var s;
        console.log("H5SWebSocketClient");
        try {
            "http:" == this._conf.protocol && (s = "undefined" != typeof MozWebSocket ? new MozWebSocket("ws://" + this._conf.host + t) : new WebSocket("ws://" + this._conf.host + t)),
                "https:" == this._conf.protocol && (console.log(this._conf.host), s = "undefined" != typeof MozWebSocket ? new MozWebSocket("wss://" + this._conf.host + t) : new WebSocket("wss://" + this._conf.host + t)),
                console.log(this._conf.host)
        }
        catch (err) {
            return void alert("error")
        }
        return s;
    },
    H5sPlayerHls.prototype.keepAlive = function () {
        try {
            var t = {
                type: "keepalive"
            };
            this.wsSocket.send(JSON.stringify(t))
        }
        catch (err) {
            console.log(err)
        }
    },
    H5sPlayerHls.prototype.onReceived = function (msg) {
        console.log("HLS received ", msg.data)
    },
    H5sPlayerHls.prototype.j = function (t) {
        var s = "api/v1/h5swscmnapi";
        s = this._conf.rootpath + s + "?token=" + t + "&session=" + this._conf.session, console.log(s), this.wsSocket = this.q(s),
            console.log("setupWebSocket", this.wsSocket), this.wsSocket.binaryType = "arraybuffer", (this.wsSocket._player = this).wsSocket.onmessage = this.onReceived.bind(this),
            this.wsSocket.onopen = function () {
                console.log("wsSocket.onopen", this._player), this._player.keepAliveTimerId = setInterval(this._player.keepAlive.bind(this._player), 1e3);
            },
            this.wsSocket.onclose = function () {
                console.log("wsSocket.onclose", this._player), this._player.cleanupWebSocket(this._player)
            }
    },
    H5sPlayerHls.prototype.cleanupWebSocket = function (t) {
        console.log("H5sPlayerHls CleanupWebSocket", t), clearInterval(t.keepAliveTimerId)
    },
    H5sPlayerHls.prototype.dt = function () {
        console.log("HLS video.ended", this.g.ended), console.log("HLS video.currentTime", this.g.currentTime);
        var t = this.g.currentTime, s = t - this.B;
        console.log("HLS diff", s), 0 === s && this.U++ , this.B = t, 3 < this.U && (null != this.wsSocket && (this.wsSocket.close(),
            this.wsSocket = null), this.j(this._token), console.log("HLS reconnect"), this.g.src = "", this.B = 0, this.U = 0,
            this.g.src = this._conf.protocol + "//" + this._conf.host + this._conf.rootpath + "hls/" + this.N + "/" + this._token + "/hls.m3u8",
            this.g.play());
    },
    H5sPlayerHls.prototype.connect = function () {
        this.j(this._token), this.B = 0, this.U = 0, this.g.onended = function (t) {
            console.log("The End")
        },
            this.g.onpause = function (t) {
                console.log("Pause")
            },
            this.g.onplaying = function (t) {
                console.log("Playing")
            },
            this.g.onseeking = function (t) {
                console.log("seeking")
            },
            this.g.onvolumechange = function (t) {
                console.log("volumechange")
            },
            this.g.src = this._conf.protocol + "//" + this._conf.host + this._conf.rootpath + "hls/" + this.N + "/" + this._token + "/hls.m3u8",
            this.g.play(), this.J = setInterval(this.dt.bind(this), 3e3);
    },
    H5sPlayerHls.prototype.disconnect = function () {
        clearInterval(this.J), this.B = 0, this.U = 0, null != this.wsSocket && (this.wsSocket.close(), this.wsSocket = null),
            console.log("disconnect", this);
    },
    H5sPlayerAudio.prototype.q = function (t) {
        var s;
        console.log("H5SWebSocketClient");
        try {
            "http:" == this._conf.protocol && (s = "undefined" != typeof MozWebSocket ? new MozWebSocket("ws://" + this._conf.host + t) : new WebSocket("ws://" + this._conf.host + t)),
                "https:" == this._conf.protocol && (console.log(this._conf.host), s = "undefined" != typeof MozWebSocket ? new MozWebSocket("wss://" + this._conf.host + t) : new WebSocket("wss://" + this._conf.host + t)),
                console.log(this._conf.host)
        }
        catch (err) {
            return void alert("error")
        }
        return s;
    },
    H5sPlayerAudio.prototype.keepAlive = function () {
        try {
            this.wsSocket.send("keepalive")
        }
        catch (err) {
            console.log(err)
        }
    },
    H5sPlayerAudio.prototype.onReceived = function (msg) {
        for (var s = new Int16Array(msg.data), e = s.length, i = this._.createBuffer(1, e, 8e3), o = 0; o < 1; o++) {
            for (var n = i.getChannelData(o), h = 0; h < e; h++) {
                n[h] = s[h] / 16383.5;
            }
        }
        var c = this._.createBufferSource();
        c.buffer = i, c.connect(this._.destination), c.start();
    },
    H5sPlayerAudio.prototype.cleanupWebSocket = function (t) {
        console.log("CleanupWebSocket", t), clearInterval(t.keepAliveTimerId)
    },
    H5sPlayerAudio.prototype.j = function (t) {
        var s = "api/v1/h5saudapi";
        s = this._conf.rootpath + s + "?token=" + t + "&session=" + this._conf.session, console.log(s), this.wsSocket = this.q(s),
            console.log("setupWebSocket for audio", this.wsSocket), this.wsSocket.binaryType = "arraybuffer", (this.wsSocket._player = this).wsSocket.onmessage = this.onReceived.bind(this),
            this.wsSocket.onopen = function () {
                console.log("wsSocket.onopen", this._player), this._player.keepAliveTimerId = setInterval(this._player.keepAlive.bind(this._player), 1e3);
            },
            this.wsSocket.onclose = function () {
                console.log("wsSocket.onclose", this._player), this._player.cleanupWebSocket(this._player)
            }
    },
    H5sPlayerAudio.prototype.connect = function () {
        this.j(this._token)
    },
    H5sPlayerAudio.prototype.disconnect = function () {
        console.log("disconnect", this), null != this.wsSocket && (this.wsSocket.close(), this.wsSocket = null), console.log("disconnect",
            this);
    },
    H5sPlayerAudBack.prototype.q = function (t) {
        var s;
        console.log("H5SWebSocketClient");
        try {
            "http:" == this._conf.protocol && (s = "undefined" != typeof MozWebSocket ? new MozWebSocket("ws://" + this._conf.host + t) : new WebSocket("ws://" + this._conf.host + t)),
                "https:" == this._conf.protocol && (console.log(this._conf.host), s = "undefined" != typeof MozWebSocket ? new MozWebSocket("wss://" + this._conf.host + t) : new WebSocket("wss://" + this._conf.host + t)),
                console.log(this._conf.host)
        }
        catch (err) {
            return void alert("error")
        }
        return s;
    },
    H5sPlayerAudBack.prototype.keepAlive = function () {
        try {
            this.wsSocket.send("keepalive")
        }
        catch (err) {
            console.log(err)
        }
    },
    H5sPlayerAudBack.prototype.onReceived = function (msg) { }, 
    H5sPlayerAudBack.prototype.cleanupWebSocket = function (t) {
        console.log("CleanupWebSocket", t), clearInterval(t.keepAliveTimerId)
    },
    H5sPlayerAudBack.prototype.K = function () {
        console.log("sampleRate", this._.sampleRate), navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.ft;
        try {
            navigator.getUserMedia({
                video: false, audio: true
            },
                this.St.bind(this))
        }
        catch (err) {
            return void alert("Audio back false getUserMedia", err);
        }
    },
    H5sPlayerAudBack.prototype.yt = function () {
        this.G = true
    },
    H5sPlayerAudBack.prototype.j = function (t) {
        var s = "api/v1/h5saudbackapi";
        s = this._conf.rootpath + s + "?token=" + t + "&samplerate=" + this.D + "&session=" + this._conf.session,
            console.log(s), this.wsSocket = this.q(s), console.log("setupWebSocket for audio back", this.wsSocket), this.wsSocket.binaryType = "arraybuffer",
            (this.wsSocket._player = this).wsSocket.onmessage = this.onReceived.bind(this), this.wsSocket.onopen = this.yt.bind(this), this.wsSocket.onclose = function () {
                console.log("wsSocket.onclose", this._player), this._player.cleanupWebSocket(this._player)
            }
    },
    H5sPlayerAudBack.prototype.vt = function (t) {
        var s = float32ToInt16(t.inputBuffer.getChannelData(0));
        true === this.G && this.wsSocket && this.wsSocket.send(s)
    },
    H5sPlayerAudBack.prototype.St = function (t) {
        try {
            var s = this._.createMediaStreamSource(t), e = this._.createScriptProcessor(1024, 1, 1);
            s.connect(e), e.connect(this._.destination), e.onaudioprocess = this.vt.bind(this)
        }
        catch (err) {
            return void alert("Audio intecomm error", err);
        }
    },
    H5sPlayerAudBack.prototype.connect = function () {
        this.j(this._token)
    },
    H5sPlayerAudBack.prototype.disconnect = function () {
        console.log("disconnect", this), null != this.wsSocket && (this.wsSocket.close(), this.wsSocket = null), console.log("disconnect",
            this);
    };

2.创建简单播放视频原型代码

结合前面H5Stream里面的h5splayer.js,实验并成功播放了一个H5Stream的ws视频。

还有一些细节问题。

<html>
    <head>
        <title>WebsocketVideo</title>
        <script src="ws.js"></script>
        <script src="jquery.js"></script>
    </head>
    <body>
        <input style="width:100px;">
        <button id="btnPlay">Play</button>
        <div>
            <video id="video1" autoplay webkit-playsinline playsinline></video>
        </div>
    </body>
    <script>
        $(document).ready(function(){
            var conf={};
            conf.url="ws://localhost:8080/api/v1/h5swsapi?token=token2&profile=main&session=c1782caf-b670-42d8-ba90-2244d0b0ee83";
            conf.videoId='video1';
            var player=new WebSocketPlayer(conf);
            player.openWebSocket();
        });

        function WebSocketPlayer(conf){
            this.conf=conf;
            this.strCodec='';
            this.inited=false;
            this.buffer=[];
            this.openWebSocket=function(){
                console.log('openWebSocket');

                var player=this;
                var url=player.conf.url;
                var wsImp=window.WebSocket || window.MozWebSocket;
                var ws=new wsImp(url);
                ws.binaryType='arraybuffer';
                ws.onopen=function(){
                    console.log('onopen');
                };
                ws.onclose=function(){
                    console.log('onclose');
                }
                ws.onmessage=player.onReceived;
                ws.player=player;
            };
            this.onReceived=function(msg){
                console.log('onmessage',msg.data);
                var ws=this;
                var player=ws.player;

                if(player.inited===false){
                    player.inited=true;
                    player.strCodec=String.fromCharCode.apply(null,new Uint8Array(msg.data));
                    player.initMediaSource(player);
                    console.log(player.strCodec);

                }else{
                    //player.buffer.push(msg.data);
                    //player.readFromBuffer();
                    player.sourceBuffer.appendBuffer(msg.data);

                }
            };

            this.initMediaSource=function(player){
                try {
                    console.log('initMediaSource',player);
                    var msImp=window.MediaSource || window.WebKitMediaSource;
                    var ms=new msImp();
                    ms.player=player;
                    player.ms=ms;

                    var video=document.getElementById(player.conf.videoId);
                    video.src=URL.createObjectURL(ms);
                    video.play();
                    ms.addEventListener('sourceopen',player.msSourceOpen)
                    player.video=video;
                }catch(ex){
                    console.error(ex);
                }

            };

            this.msSourceOpen=function(){
                console.log('msSourceOpen');
                var ms=this;
                var player=ms.player;
                var buffer=ms.addSourceBuffer(player.strCodec);
                ms.duration=Infinity;
                buffer.addEventListener('updateend',player.readFromBuffer)
                player.sourceBuffer=buffer;
            };

            this.readFromBuffer=function(){
                console.log('readFromBuffer1',this);
                //var player=this;
                //var buffer=player.buffer;
                //console.log('readFromBuffer2',buffer);
                //var first=buffer.shift();
                //var sourceBuffer=player.sourceBuffer;
                //sourceBuffer.appendBuffer(first);
            };
        }

    </script>
</html>

 

WebSocket是一种全双工通信协议,而RTSP(Real-Time Streaming Protocol)是一种用于实时流媒体的传输协议。虽然WebSocket原本设计用于在浏览器和服务器之间建立低延迟、高效的实时通信连接,但可以通过WebSocket播放RTSP流。 在使用WebSocket播放RTSP时,可以采取以下步骤: 1. 客户端与服务器建立WebSocket连接。 2. 客户端发送包含RTSP流地址的消息给服务器。 3. 服务器接收到消息后,解析RTSP流地址,并建立与该地址的RTSP连接。 4. 一旦RTSP连接建立成功,服务器开始接收来自RTSP流的数据。 5. 服务器将接收到的RTSP流数据通过WebSocket发送给客户端。 6. 客户端接收到WebSocket消息,解析数据并渲染播放器进行播放。 需要注意的是,WebSocket本身并不支持RTSP协议。因此,在服务器端需要使用一些库或框架来处理RTSP连接,并将数据流转发到WebSocket。类似的实现通常会使用一些第三方库,如Node.js的ws(WebSocket模块)和ffmpeg(用于处理多种媒体流)。 通过WebSocket播放RTSP流能够实现实时的音视频传输,并且相较于传统的RTSP播放方式,不需要使用插件或特定的播放器,而是直接在浏览器端实现。这样,用户可以使用现代浏览器来播放RTSP流,无需额外安装插件或软件。 总结来说,通过WebSocket播放RTSP流可以实现实时的音视频传输,并且可以在现代浏览器直接播放,无需额外插件或软件支持。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值