安卓自采集屏幕共享清晰度不高

android

#1

在安卓端上使用屏幕共享,于是按照声网demo使用自采集的方式自定义了TextureSource,然后通过engine.setVideoSource(source);设置给sdk。
:point_down:是自定义的TextureSource的代码

public class ScreenSource extends TextureSource {

private static final String TAG = ScreenSource.class.getSimpleName();
private int mDpi;
private int mRotation = 0;
/**
 * 虚拟显示设备,视频内容的提供者
 */
private VirtualDisplay mVirtualDisplay;
private MediaProjection mMediaProjection;

public ScreenSource(int width, int height, int dpi, MediaProjection mediaProjection) {
    super(null, width, height);
    Log.d(TAG, "ScreenSource construct, width:" + width + ", height:" + height + ", dpi:" + dpi);
    mDpi = dpi;
    mMediaProjection = mediaProjection;
}

@Override
public void onTextureFrameAvailable(int oesTextureId, float[] transformMatrix, long timestampNs) {
    super.onTextureFrameAvailable(oesTextureId, transformMatrix, timestampNs);
    if (mConsumer != null && mConsumer.get() != null) {
        mConsumer.get().consumeTextureFrame(oesTextureId, TEXTURE_OES.intValue(), mWidth, mHeight, mRotation, System.currentTimeMillis(), transformMatrix);
    }
}

@Override
protected boolean onCapturerOpened() {
    Log.d(TAG, "onCapturerOpened");
    createVirtualDisplay();
    return true;
}

@Override
protected boolean onCapturerStarted() {
    Log.i(TAG, "onCapturerStarted");
    return true;
}

@Override
protected void onCapturerStopped() {
    Log.i(TAG, "onCapturerStopped");
}

@Override
protected void onCapturerClosed() {
    Log.i(TAG, "onCapturerClosed");
}

public void releaseSource() {
    Log.d(TAG, "onReleaseSource");
    releaseVirtualDisplay();
    release();
}

private void createVirtualDisplay() {
    Log.d(TAG, "onCreateVirtualDisplay");
    //通过声网sdk获取的surface,将屏幕内容传到surface中
    Surface surface = new Surface(getSurfaceTexture());
    if (mVirtualDisplay == null) {
        mVirtualDisplay = mMediaProjection.createVirtualDisplay("EachMeeting", mWidth, mHeight, mDpi,
                DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, surface, null, null);
    }
}

private void releaseVirtualDisplay() {
    Log.d(TAG, "releaseVirtualDisplay");
    if (mVirtualDisplay != null) {
        mVirtualDisplay.release();
    }
    mVirtualDisplay = null;
}

}

效果如视频所示,在画面静止时画质是不错的,但是当画面快速变动时就会出现模糊,当画面在此静止后就逐渐清晰,如何才能够一直都维持清晰的状态,视频中的内容为远端用户使用共享屏幕显示的内容,链接:https://pan.baidu.com/s/1-gwTao3rNg5VqvANEZV8Mw


#2

清晰度一般和设置的分辨率、码率、实际带宽等因素有关。出现模糊现象,有可能是因为你设置的码率过高 带宽却过低,或者码率设置得过低。
如果画面不变动时,关键帧不变;而画面快速变动时,视频帧快速变动,此时对码率和带宽的要求较高。
你可以用稍微复杂一些的频道号测试一下,提交工单。