Example #1
0
        private RtpSession Setup(MediaTrack track, RtpChannelSink sink, bool interleaved)
        {
            lock (SourceLock)
            {
                IRtpSource rtpSource = null;
                try
                {
                    TransportHeader transport = null;
                    if (interleaved)
                    {
                        transport = TransportHeader.CreateBuilder()
                                    .Type(Media.RTSP.TransportType.RtspInterleaved)
                                    .InterleavedChannels(0, 1)
                                    .Build();
                    }
                    else
                    {
                        // TODO(frank.lamar): Add multicast support.
                        rtpSource = new RtpUdpSource(track.Address);
                        transport = TransportHeader.CreateBuilder()
                                    .Type(Media.RTSP.TransportType.UdpUnicast)
                                    .ClientPorts(rtpSource.RtpPort, rtpSource.RtcpPort)
                                    .Build();
                    }

                    var response = CheckResponse(_client.Send(RtspRequest.CreateBuilder()
                                                              .Method(RtspRequest.RtspMethod.SETUP)
                                                              .Uri(track.ControlUri)
                                                              .AddHeader(RtspHeaders.Names.TRANSPORT, transport.ToString())
                                                              .Build()), RtspRequest.RtspMethod.SETUP);

                    if (!response.Headers.ContainsKey(RtspHeaders.Names.SESSION))
                    {
                        throw new RtspClientException("Rtsp SETUP response does not contain a session id");
                    }
                    var rtspSession = Session.Parse(response.Headers[RtspHeaders.Names.SESSION]);

                    transport = response.Transport;
                    if (interleaved)
                    {
                        if (transport.Type != Media.RTSP.TransportType.RtspInterleaved)
                        {
                            throw new RtspClientException($"Server does not support interleaved. Response Transport='{transport}'");
                        }

                        var channels = transport.InterleavedChannels != null ? transport.InterleavedChannels : new PortPair(0, 1);
                        sink.Channel = channels.RtpPort; // Ensure that the sink contains the correct Interleaved channel id.

                        rtpSource = new RtpInterleavedSource(_client.GetChannelSource(channels.RtpPort),
                                                             _client.GetChannelSource(channels.RtcpPort));
                    }

                    var pipeline = MediaPipeline.CreateBuilder()
                                   .Source(rtpSource.RtpSource)
                                   .TransformIf(transport.SSRC != null, new SsrcFilter(transport.SSRC))
                                   .Sink(sink)
                                   .Build();

                    var session = new RtpSession(track, rtspSession, rtpSource);
                    session.Pipelines.Add(pipeline);
                    session.Start();

                    CheckAndStartRefreshTimer(session.Session.Timeout);

                    return(session);
                }
                catch (Exception e)
                {
                    if (rtpSource != null)
                    {
                        rtpSource?.Stop();
                    }

                    if (e is RtspClientException)
                    {
                        throw e;
                    }

                    throw new RtspClientException($"Unable to set up media track {track.ID}", e);
                }
            }
        }