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

How to get observed bitrate from Google's ExoPlayer

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

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

HlsSampleSource 有一个 EventListener,需要执行几个调用。 其中一些调用 return 具有属性 'bitrate'.

的格式对象 (com.google.android.exoplayer.chunk.Format)

格式出现在: onDownstreamFormat 已更改 onLoadStarted onLoadCompleted

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

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

经过研究我想出了这个:

确实,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;
    }

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

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

现在获取格式后,您可以通过以下代码获取曲目名称

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