Локальный видео рендерер в Android WebRTC

Я использую эту библиотеку: https://bintray.com/google/webrtc/google-webrtc

То, чего я хочу достичь (по крайней мере, в начале моего проекта), это сделать видео локально. Я использую этот учебник (который является единственным в Интернете) https://vivekc.xyz/getting-started-with-webrtc-for-android-daab1e268ff4. К сожалению, последняя строка кода больше не актуальна. Конструктор нуждается в обратном вызове, который я понятия не имею, как реализовать:

localVideoTrack.addRenderer(new VideoRenderer(i420Frame -> { // no idea what to put here }));

Мой код точно такой же, как в опубликованном уроке. Это самый первый шаг к ознакомлению с технологией WebRTC в Android, которую я не могу понять. Моя камера захватывает видео, потому что я вижу его в своем журнале:

I/org.webrtc.Logging: CameraStatistics: Camera fps: 28.

Основная проблема в том, что я понятия не имею, как передать его моему SurfaceViewRenderer через обратный звонок. Кто-нибудь сталкивался с этой проблемой? Я буду очень признателен за любую помощь или предложения.

Вот официальный пример приложения, которое является единственным источником, но оно сделано не так, как в учебнике, оно намного сложнее: https://webrtc.googlesource.com/src/+/master/examples/androidapp/src/org/appspot/apprtc

1 ответ

Решение

Вы правы, API больше не соответствует этому в учебнике, но он близок.

VideoTrack, имеет addRenderer(VideoRenderer renderer) метод, который требует создания VideoRenderer с параметром SurfaceViewRenderer. Но это больше невозможно, поэтому вместо этого вы должны использовать addSink(VideoSink sink) метод VideoTrack. Объект SurfaceViewRenderer реализует VideoSink onFrame(VideoFrame frame) способ сделать эту работу.

VideoTrack videoTrack = utility.createVideoTrack();
videoTrack.addSink(this.localSurfaceViewRenderer);

Я использовал тот же официальный пример приложения в качестве ссылки, чтобы прийти к такому выводу, и он прекрасно работает для меня.

private static class ProxyVideoSink implements VideoSink {
    private VideoSink target;

    @Override
    synchronized public void onFrame(VideoFrame frame) {
        if (target == null) {
            Logging.d("TAG", "Dropping frame in proxy because target is null.");
            return;
        }

        target.onFrame(frame);
    }

    synchronized public void setTarget(VideoSink target) {
        this.target = target;
    }
}

ProxyVideoSink localVideoSink = new ProxyVideoSink();
videoTrack.addSink(localVideoSink);
localVideoSink.setTarget(localSurfaceView);

попробуйте этот код как прямое назначение videoTrack.addSink(localSurfaceView) может произойти сбой при следующей инициализации.

Другие вопросы по тегам