如何从Google的ExoPlayer获得观察到的比特率

时间:2015-08-07 13:31:13

标签: java android hls exoplayer

我正在使用ExoPlayer播放HLS文件,并且我试图获得实际观察到的比特率(而不是指示的比特率)。

我现在有onInFoListener界面,但文档很粗略,任何人都可以帮忙吗?

3 个答案:

答案 0 :(得分:3)

经过研究后,我想出了这个:

确实,ExoPlayer附带了一个InfoListener接口,可用于此目的。这是我写的代码。

(在我的实现mVideoPlayer中是保存我的ExoPlayer实例的var名称)

关于准备播放器的代码......

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

稍后在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;
    }

这是帮助函数记录以秒为单位加载的字节数

    /**
     * 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
                }
            }
        }
    }

最后,我们可以使用所有这些信息来估算观察到的比率...

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

答案 1 :(得分:1)

HlsSampleSource有一个EventListener,有几个要实现的调用。 其中一些调用返回具有“比特率”属性的格式对象(com.google.android.exoplayer.chunk.Format)。

格式显示在: onDownstreamFormatChanged onLoadStarted onLoadCompleted

HlsSampleSource.EventListener可以在渲染器构建期间作为HlsSampleSource的一部分传递。

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

答案 2 :(得分:1)

我知道为时已晚,但这可能会帮助其他人,

Format format = your_exoplayer.getVideoFormat()       //returns Format

现在,一旦获得格式,就可以通过以下代码获取trackName

TrackNameProvider trackNameProvider = new DefaultTrackNameProvider(getResources());
trackNameProvider.getTrackName(format)          //returns track name in string format (Ex:- 640 * 360, 0.50 Mbps)