Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Local Video Renderer in Android WebRTC

I am using this library: https://bintray.com/google/webrtc/google-webrtc

What I want to achieve (at least, at the beginning of my project) is render video locally. I am using this tutorial (which is the only one around the Internet) https://vivekc.xyz/getting-started-with-webrtc-for-android-daab1e268ff4. Unfortunately, the last line of code is not up-to-date anymore. The constructor needs a callback which I have no idea how to implement:

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

My code is exactly the same as in the posted tutorial. This is the very first step to make familiar with WebRTC technology in Android which I cannot figure out. My camera is capturing the video because I can see it in my log:

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

The main issue is that I have no idea how to pass it to my SurfaceViewRenderer through a callback. Did anyone meet that problem? I'll really appreciate any help or suggestions.

Here is the official example app which is the only source but it is done differently than one in the tutorial, it's much more complicated: https://webrtc.googlesource.com/src/+/master/examples/androidapp/src/org/appspot/apprtc

like image 498
shurrok Avatar asked May 11 '18 11:05

shurrok


2 Answers

You are right, the API no longer matches that in the tutorial, but it's close.

The VideoTrack, has an addRenderer(VideoRenderer renderer) method, that requires you to create a VideoRenderer, with the SurfaceViewRenderer as parameter. But that is not possible anymore, so instead you should use the addSink(VideoSink sink) method, of the VideoTrack. The SurfaceViewRenderer object implement the VideoSink onFrame(VideoFrame frame) method to make this work.

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

I used the same official example app as reference to get to this conclusion, and it works fine for me.

like image 54
Andreas2762 Avatar answered Nov 15 '22 12:11

Andreas2762


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

try this code as directly assigning videoTrack.addSink(localSurfaceView) might crash on next initialization.

like image 38
Prasanth Perumal Avatar answered Nov 15 '22 12:11

Prasanth Perumal