Dregu / visio

Ultra fast live streaming raw h264 from Raspberry Pi to multiple browser clients with Node, websockets and Broadway
MIT License
37 stars 13 forks source link

Can you help me to get the proper way to extract the stats from video ? #4

Closed VigibotDev closed 6 years ago

VigibotDev commented 6 years ago

Hello Dregu,

Can you help me to get the proper way to extract the stats from video inside my own code / div ? I have to integrate your information into my own text. / I need to display the bitrate and other on my own page http://www.serveurperso.com:8080/ I will add thanks on the robot page with a link on visio or your custom choice.

Thanks, Pascal

Dregu commented 6 years ago

Well I have a great stats function starting https://github.com/Dregu/visio/blob/master/client.js#L57 (plus other lines matching "debug"), I don't know why you are not using it. It's not really complicated... Most of it only works with broadway though, so jmuxer branch doesn't have any.

VigibotDev commented 6 years ago

I know this function but I need to put the content inside my own div and not the default container div. I this this is a tiny modification of your code.

Dregu commented 6 years ago

The playerId in debugger can be id of any div you want the stats in. The debugger however creates a needed callback using window.player where the actual broadway Player() is.

VigibotDev commented 6 years ago

Hi, now I can pass two params one ID for video and the other for stats:) startStream('video', 'videostats', 'ws://...', true, 'auto', 2000)

I modded your code to get just what I want :

petitrobot

Thanks a lot

VigibotDev commented 6 years ago

I forget to put my modded (and a bit minimized) code :

const FPSMIN = 23;
const PORT = 84;

var port = window.location.port;
if (window.location.protocol == 'https:') {
    var protocol = 'wss:'
    if (!port) port = '443'
} else {
    var protocol = 'ws:'
    if (!port) port = '80'
}

startStream('video', 'videostats', protocol+'//'+window.location.hostname+':'+port+'/'+PORT, true, 'auto', 2000)

function startStream(playerId, debugId, wsUri, useWorker, webgl, reconnectMs) {
    if (!window.player) {
        window.player = new Player({ useWorker: useWorker, workerFile: 'visio/Decoder.js', webgl: webgl, size: { width: 400, height: 300 } })
        var playerElement = document.getElementById(playerId)
        playerElement.appendChild(window.player.canvas)
        window.debugger = new debug(playerId, debugId) //show statistics, you can remove me if you dont need stats
    }

    var separator = new Uint8Array([0, 0, 0, 1])
    function addSeparator(buffer) {
        var tmp = new Uint8Array(4+buffer.byteLength)
        tmp.set(separator, 0)
        tmp.set(new Uint8Array(buffer), 4)
        return tmp.buffer
    }

    var ws = new WebSocket(wsUri)
    ws.binaryType = 'arraybuffer'
    ws.onopen = function (e) {
        console.log('websocket connected')
        ws.onmessage = function (msg) {
            window.player.decode(new Uint8Array(addSeparator(msg.data)))
            if(window.debugger) window.debugger.nal(msg.data.byteLength)
        }
    }
    ws.onclose = function (e) {
        console.log('websocket disconnected')
        if (reconnectMs > 0) {
            setTimeout(function() { startStream(playerId, wsUri, useWorker, webgl, reconnectMs) }, reconnectMs)
        }
    }
}

// debugger stuff
function avgFPS(length) {
    this.index = 0
    this.sum = 0
    this.length = length
    this.buffer = Array.apply(null, Array(length)).map(Number.prototype.valueOf,0);
    this.tick = function(tick) {
        this.sum -= this.buffer[this.index]
        this.sum += tick
        this.buffer[this.index] = tick
        if (++this.index == this.length) this.index = 0
        return Math.floor(this.sum/this.length)
    }
    this.avg = function() {
        return Math.floor(this.sum/this.length)
    }
    return this
}

function debug(playerId, debugId) {
    this.started = +new Date()
    this.fps = new avgFPS(50)
    this.last = +new Date()
    this.nals = 0
    this.total = 0
    this.secondTotal = 0
    this.statsElement = document.getElementById(debugId)
    window.player.onPictureDecoded = function(buffer, width, height, infos) {
        window.debugger.frame(width, height)
    }
    this.nal = function(bytes) {
        this.nals++
        this.total += bytes
        this.secondTotal += bytes
    }
    this.frame = function(w, h) {
        var now = +new Date(), delta = now - window.debugger.last
        this.fps.tick(delta)
        this.last = now
    }
    setInterval(function() {
        var date = new Date(null)
        date.setSeconds((+new Date()-window.debugger.started)/1000)
        var fps = Math.floor(1/window.debugger.fps.avg()*1000)
        var kos = Math.floor(window.debugger.secondTotal/1024)
        if (!isFinite(fps) || kos == 0) fps = 0
        if (fps < FPSMIN) window.debugger.statsElement.style.color = '#ff0000'
        else window.debugger.statsElement.style.color = '#00ff00'
        window.debugger.statsElement.innerHTML = 'Vidéo H.264 | '+fps+' FPS | '+kos+' Ko/s | '+Math.floor(window.debugger.secondTotal/128)+' Kbit/s'
        window.debugger.secondTotal = 0
    }, 1000)
}