Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get observed bitrate from Google's ExoPlayer

I'm playing an HLS file using ExoPlayer and i'm trying to get the actual observed bitrate (not the indicated bitrate).

I now there is the onInFoListener interface but documentation is sketchy, can anyone help?

like image 353
Juan Carlos Ospina Gonzalez Avatar asked Aug 07 '15 13:08

Juan Carlos Ospina Gonzalez


1 Answers

After doing research i came up with this:

Indeed ExoPlayer comes with a InfoListener interface that can be used for this purpose. This is the code i wrote.

(in my implementation mVideoPlayer is the var name that holds my ExoPlayer instance)

on the code that prepares the player...

   ...
   // assigns this as InfoListener for ExoPlayer
   mVideoPlayer.setInfoListener(this);
   ...

Later on the InfoListener implementation ...

    private long mBytesLoaded = 0;
    private long mBytesLoadedSeconds = 0;
    private long mLastBytesLoadedTime = 0;

    @Override
    public void onLoadStarted(int sourceId, long length, int type, int trigger, Format format, int mediaStartTimeMs, int mediaEndTimeMs) {
        Log.d(TAG, "onLoadStarted sourceId " + sourceId + " length " + length + " type " + type + " format " + format + " mediaStartTimeMs " + mediaStartTimeMs + " mediaEndTimeMs " + mediaEndTimeMs);
        if(mLastBytesLoadedTime == 0) mLastBytesLoadedTime = System.currentTimeMillis();
    }

    @Override
    public void onLoadCompleted(int sourceId, long bytesLoaded, int type, int trigger, Format format, int mediaStartTimeMs, int mediaEndTimeMs, long elapsedRealtimeMs, long loadDurationMs) {
        Log.d(TAG, "onLoadCompleted sourceId " + sourceId + " bytesLoaded " + bytesLoaded + " type " + type + " format " + format + " mediaStartTimeMs " + mediaStartTimeMs + " mediaEndTimeMs " + mediaEndTimeMs);

        // log... logBytesLoadedInSeconds
        long now = System.currentTimeMillis();
        float diffInSeconds = (now - mLastBytesLoadedTime) / 1000;
        this.logBytesLoadedInSeconds(bytesLoaded, diffInSeconds); // helper function, explain bellow
        mLastBytesLoadedTime = now;
    }

This is that helper function that is logging how many bytes are loaded in an amount of seconds

    /**
     * Logs an amount of bytes loaded in an amount of seconds
     *
     * @param bytes amount of bytes loaded
     * @param seconds time in seconds that it took to load those bytes
     */
    private void logBytesLoadedInSeconds(long bytes, float seconds){
        mBytesLoaded += bytes;
        mBytesLoadedSeconds += seconds;
        if(mBytesLoadedSeconds > 0){
            double bytesPerSecond = mBytesLoaded / mBytesLoadedSeconds;
            double bitsPerSecond = bytesPerSecond * 8; // (8 bits in a byte)
            if(bitsPerSecond < mIndicatedBitrate){
                // buffer is falling behind!
                mBufferWarned = true;
            }else{
                if(mBufferWarned){
                    // buffer caught up
                }
            }
        }
    }

Finally, we can use all of this information to get an estimate of the observed birate...

    public int getObservedBitrate(){
        if(mBytesLoadedSeconds != 0){
            double bytesPerSecond = mBytesLoaded / mBytesLoadedSeconds;
            double bitsPerSecond = bytesPerSecond * 8; // (8 bits in a byte)
            Log.d(TAG," mBytesLoaded " + mBytesLoaded + " in "+mBytesLoadedSeconds+" seconds ("+(int)bitsPerSecond+" b/s indicated "+mIndicatedBitrate+" b/s) ");
            return (int)bitsPerSecond;
        }
        return 0;
    }
like image 97
Juan Carlos Ospina Gonzalez Avatar answered Sep 18 '22 15:09

Juan Carlos Ospina Gonzalez