How to get observable bitrate from Google ExoPlayer

I am playing an HLS file using ExoPlayer and I am trying to get the actual observed bitrate (not specified bitrate).

I can see the interface now onInFoListener

, but the documentation is sketchy, can anyone help?

+3


source to share


2 answers


After researching, I came up with the following:

Indeed, ExoPlayer comes with an interface InfoListener

that can be used for this purpose. This is the code I wrote.

(my implementation mVideoPlayer

has a var name that contains the ExoPlayer instance)

in the code that prepares the player ...

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

      

Later implementation of InfoListener ...



    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 a helper function that logs how many bytes are loaded in 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;
    }

      

+2


source


The HlsSampleSource has an EventListener with multiple calls to implement. Some of these calls return format objects (com.google.android.exoplayer.chunk.Format) that have a bitrate attribute.

The format is displayed in: onDownstreamFormatChanged onLoadStarted onLoadCompleted



HlsSampleSource.EventListener can be passed during renderer creation as part of the HlsSample source.

http://google.github.io/ExoPlayer/doc/reference/com/google/android/exoplayer/hls/HlsSampleSource.html

+1


source







All Articles