8

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

shurrok
  • 795
  • 2
  • 13
  • 43
  • 1
    This will help you https://stackoverflow.com/questions/61137244/cameracapturer-must-be-initialized-before-calling-startcapture – Kartheek Apr 15 '20 at 09:29

2 Answers2

16

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.

Andreas2762
  • 326
  • 2
  • 5
  • Yeah I realized this myself but forgot about this question to post the answer... You did nice job, thanks very much! – shurrok May 20 '18 at 15:27
  • Anyone knows where to find some documentation on this change? I can't find anything about `addSink()` – Entreco Aug 11 '18 at 08:46
  • 1
    I can't find the class `org.webrtc.VideoRenderer`. Any idea if this is moved to some other file. Can't find any official (or unofficial) change log regarding this. – Mudassir Aug 14 '18 at 10:07
  • 1
    @Entreco there is no documentation for this library yet - it is still in development phase – shurrok Aug 14 '18 at 10:40
  • 1
    @Mudassir there was like 5 new releases of the `webrtc` library so these can be outdated. The version which I'm using atm and the approach in answer is working: `'org.webrtc:google-webrtc:1.0.23171'` – shurrok Aug 14 '18 at 10:41
  • Yeah. I am using the version 1.0.24180. Seems its having many breaking changes, which are not logged anywhere. – Mudassir Aug 14 '18 at 10:45
  • How about releasing the resources for video. I'm developing a conference app and I am using the same version library 1.0.23546 and what i see is that after like 20 + calls the application crashes with some kind of buffer error, I think, the error is not very specific. Anyone else encountered the same problem? – Player1 Sep 17 '18 at 08:29
  • @lapusanmirel the library behaviour is very specific for different devices. Especially with the hardware based encoders/decoders. – shurrok Dec 04 '18 at 12:02
  • @shurrok I have tested on multiple devices and they all seem to have the same behavior. After you open/close a PeerConnection more than 30 times which is a viable flow for a conference app with 30+ people who can present the application just closes with some weird errors in the logger. I will try to update to the latest version and see how it works but its a hassle without documentation. Might take some time. I have tried to reproduce this in the AppRTCDemo but it crashes from source code long before I get to that point of making multiple connections – Player1 Feb 11 '19 at 14:42
2
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.