Gstreamer rtph264pay pipeline to RtpEndpoint connection problem.

465 views
Skip to first unread message

Andoni Galdos

unread,
Jun 28, 2016, 5:20:04 AM6/28/16
to kurento
Hi to all,

I'm trying to connect Kurento with an Gstreamer pipeline so that I can use video tag to stream RTP video streaming.

From one side I have a Gstreamer pipeline creating a RTP stream:
gst-launch-1.0 -v videotestsrc ! x264enc ! rtph264pay config-interval=1 pt=96 ! udpsink host=127.0.0.1 port=5000

I can connect via VLC with a SDP file and video is reproduced perfectly:
v=0
o=- 12345 12345 IN IP4 127.0.0.1
s=-
c=IN IP4 127.0.0.1
t=0 0
m=video 5000 RTP/AVP 96 97 98
a=rtpmap:96 H264/90000
a=rtpmap:97 MP4V-ES/90000
a=rtpmap:98 H263-1998/90000
a=recvonly
b=AS:384


Trying to get the pipeline in Kurento, I start developing taking as example kurento-player of the kurento-tutorial-java tutorial. What I have done is to create a RtpEndpoint and included between WebRtcEndpoint and PlayerEndpoint. Afterwards I generate and SDP string and process the offer:

  private void start(final WebSocketSession session, JsonObject jsonMessage)
 
{
   
// 1. Media pipeline
   
final UserSession user = new UserSession();

   
MediaPipeline pipeline = kurento.createMediaPipeline();
    user
.setMediaPipeline(pipeline);

   
WebRtcEndpoint webRtcEndpoint = new WebRtcEndpoint.Builder(pipeline).build();
    user
.setWebRtcEndpoint(webRtcEndpoint);

   
RtpEndpoint rtpEndpoint = new RtpEndpoint.Builder(pipeline).build();
    user
.setRtpEndpoint(rtpEndpoint);

   
//String videourl = jsonMessage.get("videourl").getAsString();
   
final PlayerEndpoint playerEndpoint = new PlayerEndpoint.Builder(pipeline, URL_BARCODES/*videourl*/).build();
    user
.setPlayerEndpoint(playerEndpoint);
   
    users
.put(session.getId(), user);

   
String requestSdp = "v=0\r\n"
       
+ "o=- 12345 12345 IN IP4 127.0.0.1\r\n"
       
+ "s=-\r\n"
       
+ "c=IN IP4 127.0.0.01r\n"
       
+ "t=0 0\r\n"
       
+ "m=video 5000 RTP/AVP 96 97 98\r\n"
       
+ "a=rtpmap:96 H264/90000\r\n"
       
+ "a=rtpmap:97 MP4V-ES/90000\r\n"
       
+ "a=rtpmap:98 H263-1998/90000\r\n"
       
+ "a=recvonly\r\n"
       
+ "b=AS:384\r\n";

    rtpEndpoint
.processOffer(requestSdp);

    rtpEndpoint
.connect(webRtcEndpoint);
    playerEndpoint
.connect(rtpEndpoint, MediaType.VIDEO);

   
// 2. WebRtcEndpoint
   
// ICE candidates
    webRtcEndpoint
.addOnIceCandidateListener(new EventListener<OnIceCandidateEvent>() {
     
@Override
     
public void onEvent(OnIceCandidateEvent event) {
       
JsonObject response = new JsonObject();
        response
.addProperty("id", "iceCandidate");
        response
.add("candidate", JsonUtils.toJsonObject(event.getCandidate()));
       
try {
         
synchronized (session) {
            session
.sendMessage(new TextMessage(response.toString()));
         
}
       
} catch (IOException e) {
          log
.debug(e.getMessage());
       
}
     
}
   
});

   
String sdpOffer = jsonMessage.get("sdpOffer").getAsString();
   
String sdpAnswer = webRtcEndpoint.processOffer(sdpOffer);

   
JsonObject response = new JsonObject();
    response
.addProperty("id", "startResponse");
    response
.addProperty("sdpAnswer", sdpAnswer);
    sendMessage
(session, response.toString());

    webRtcEndpoint
.addMediaStateChangedListener(new EventListener<MediaStateChangedEvent>() {
     
@Override
     
public void onEvent(MediaStateChangedEvent event) {

       
if (event.getNewState() == MediaState.CONNECTED) {
         
VideoInfo videoInfo = playerEndpoint.getVideoInfo();

         
JsonObject response = new JsonObject();
          response
.addProperty("id", "videoInfo");
          response
.addProperty("isSeekable", videoInfo.getIsSeekable());
          response
.addProperty("initSeekable", videoInfo.getSeekableInit());
          response
.addProperty("endSeekable", videoInfo.getSeekableEnd());
          response
.addProperty("videoDuration", videoInfo.getDuration());
          sendMessage
(session, response.toString());
       
}
     
}
   
});

    webRtcEndpoint
.gatherCandidates();

   
// 3. RtpEndpoint
    rtpEndpoint
.addErrorListener(new EventListener<ErrorEvent>() {
     
@Override
     
public void onEvent(ErrorEvent event) {
        log
.info("ErrorEvent: {}", event.getDescription());
        sendRtpEvent
(session);
     
}
   
});

   
// 3. PlayEndpoint
    playerEndpoint
.addErrorListener(new EventListener<ErrorEvent>() {
     
@Override
     
public void onEvent(ErrorEvent event) {
        log
.info("ErrorEvent: {}", event.getDescription());
        sendPlayErr
(session);
     
}
   
});

    playerEndpoint
.addEndOfStreamListener(new EventListener<EndOfStreamEvent>() {
     
@Override
     
public void onEvent(EndOfStreamEvent event) {
        log
.info("EndOfStreamEvent: {}", event.getTimestamp());
        sendPlayEnd
(session);
     
}
   
});

    playerEndpoint
.play();
 
}


When running the example, once I try to play stream is waits for several seconds and then an end stream message arrives from kurento.

What I'm doing wrong? Why doesn't work? Can someone give me any clue to get this working?

Thanks for all.

Jose Antonio Santos Cadenas

unread,
Jun 28, 2016, 6:06:25 AM6/28/16
to kurento
The problem is that kms is opening the port randomly and then this port is set on the offer or answer. You should change your gstreamer pipeline to send to the port that kms prepared for this stream. Vlc does exactly the opposite, it opens the port that your are instructing it to open.

Cheers.

--
You received this message because you are subscribed to the Google Groups "kurento" group.
To unsubscribe from this group and stop receiving emails from it, send an email to kurento+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Andoni Galdos

unread,
Jun 28, 2016, 9:46:35 AM6/28/16
to kurento
Hi Jose Antonio,

Thanks for your help. I managed to solve it with your advise.
Reply all
Reply to author
Forward
0 new messages