add RtspSession
This commit is contained in:
parent
edd9ad6d63
commit
fa841e8610
|
@ -0,0 +1,681 @@
|
|||
/*
|
||||
Copyright (C) <2007-2016> <Kay Diefenthal>
|
||||
|
||||
SatIp.RtspSample is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
SatIp.RtspSample is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with SatIp.RtspSample. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Net.Sockets;
|
||||
using System.Text.RegularExpressions;
|
||||
using MediaBrowser.Model.Logging;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp.SatIp
|
||||
{
|
||||
public class RtspSession : IDisposable
|
||||
{
|
||||
#region Private Fields
|
||||
private static readonly Regex RegexRtspSessionHeader = new Regex(@"\s*([^\s;]+)(;timeout=(\d+))?");
|
||||
private const int DefaultRtspSessionTimeout = 30; // unit = s
|
||||
private static readonly Regex RegexDescribeResponseSignalInfo = new Regex(@";tuner=\d+,(\d+),(\d+),(\d+),", RegexOptions.Singleline | RegexOptions.IgnoreCase);
|
||||
private string _address;
|
||||
private string _rtspSessionId;
|
||||
|
||||
public string RtspSessionId
|
||||
{
|
||||
get { return _rtspSessionId; }
|
||||
set { _rtspSessionId = value; }
|
||||
}
|
||||
private int _rtspSessionTimeToLive = 0;
|
||||
private string _rtspStreamId;
|
||||
private int _clientRtpPort;
|
||||
private int _clientRtcpPort;
|
||||
private int _serverRtpPort;
|
||||
private int _serverRtcpPort;
|
||||
private int _rtpPort;
|
||||
private int _rtcpPort;
|
||||
private string _rtspStreamUrl;
|
||||
private string _destination;
|
||||
private string _source;
|
||||
private string _transport;
|
||||
private int _signalLevel;
|
||||
private int _signalQuality;
|
||||
private Socket _rtspSocket;
|
||||
private int _rtspSequenceNum = 1;
|
||||
private bool _disposed = false;
|
||||
private ILogger _logger;
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
|
||||
public RtspSession(string address, ILogger logger)
|
||||
{
|
||||
_address = address;
|
||||
_logger = logger;
|
||||
}
|
||||
~RtspSession()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
#region Rtsp
|
||||
|
||||
public string RtspStreamId
|
||||
{
|
||||
get { return _rtspStreamId; }
|
||||
set { if (_rtspStreamId != value) { _rtspStreamId = value; OnPropertyChanged("RtspStreamId"); } }
|
||||
}
|
||||
public string RtspStreamUrl
|
||||
{
|
||||
get { return _rtspStreamUrl; }
|
||||
set { if (_rtspStreamUrl != value) { _rtspStreamUrl = value; OnPropertyChanged("RtspStreamUrl"); } }
|
||||
}
|
||||
|
||||
public int RtspSessionTimeToLive
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_rtspSessionTimeToLive == 0)
|
||||
_rtspSessionTimeToLive = DefaultRtspSessionTimeout;
|
||||
return _rtspSessionTimeToLive * 1000 - 20;
|
||||
}
|
||||
set { if (_rtspSessionTimeToLive != value) { _rtspSessionTimeToLive = value; OnPropertyChanged("RtspSessionTimeToLive"); } }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Rtp Rtcp
|
||||
|
||||
/// <summary>
|
||||
/// The LocalEndPoint Address
|
||||
/// </summary>
|
||||
public string Destination
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(_destination))
|
||||
{
|
||||
var result = "";
|
||||
var host = Dns.GetHostName();
|
||||
var hostentry = Dns.GetHostEntry(host);
|
||||
foreach (var ip in hostentry.AddressList.Where(ip => ip.AddressFamily == AddressFamily.InterNetwork))
|
||||
{
|
||||
result = ip.ToString();
|
||||
}
|
||||
|
||||
_destination = result;
|
||||
}
|
||||
return _destination;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (_destination != value)
|
||||
{
|
||||
_destination = value;
|
||||
OnPropertyChanged("Destination");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The RemoteEndPoint Address
|
||||
/// </summary>
|
||||
public string Source
|
||||
{
|
||||
get { return _source; }
|
||||
set
|
||||
{
|
||||
if (_source != value)
|
||||
{
|
||||
_source = value;
|
||||
OnPropertyChanged("Source");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The Media Data Delivery RemoteEndPoint Port if we use Unicast
|
||||
/// </summary>
|
||||
public int ServerRtpPort
|
||||
{
|
||||
get
|
||||
{
|
||||
return _serverRtpPort;
|
||||
}
|
||||
set { if (_serverRtpPort != value) { _serverRtpPort = value; OnPropertyChanged("ServerRtpPort"); } }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The Media Metadata Delivery RemoteEndPoint Port if we use Unicast
|
||||
/// </summary>
|
||||
public int ServerRtcpPort
|
||||
{
|
||||
get { return _serverRtcpPort; }
|
||||
set { if (_serverRtcpPort != value) { _serverRtcpPort = value; OnPropertyChanged("ServerRtcpPort"); } }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The Media Data Delivery LocalEndPoint Port if we use Unicast
|
||||
/// </summary>
|
||||
public int ClientRtpPort
|
||||
{
|
||||
get { return _clientRtpPort; }
|
||||
set { if (_clientRtpPort != value) { _clientRtpPort = value; OnPropertyChanged("ClientRtpPort"); } }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The Media Metadata Delivery LocalEndPoint Port if we use Unicast
|
||||
/// </summary>
|
||||
public int ClientRtcpPort
|
||||
{
|
||||
get { return _clientRtcpPort; }
|
||||
set { if (_clientRtcpPort != value) { _clientRtcpPort = value; OnPropertyChanged("ClientRtcpPort"); } }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The Media Data Delivery RemoteEndPoint Port if we use Multicast
|
||||
/// </summary>
|
||||
public int RtpPort
|
||||
{
|
||||
get { return _rtpPort; }
|
||||
set { if (_rtpPort != value) { _rtpPort = value; OnPropertyChanged("RtpPort"); } }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The Media Meta Delivery RemoteEndPoint Port if we use Multicast
|
||||
/// </summary>
|
||||
public int RtcpPort
|
||||
{
|
||||
get { return _rtcpPort; }
|
||||
set { if (_rtcpPort != value) { _rtcpPort = value; OnPropertyChanged("RtcpPort"); } }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public string Transport
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(_transport))
|
||||
{
|
||||
_transport = "unicast";
|
||||
}
|
||||
return _transport;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (_transport != value)
|
||||
{
|
||||
_transport = value;
|
||||
OnPropertyChanged("Transport");
|
||||
}
|
||||
}
|
||||
}
|
||||
public int SignalLevel
|
||||
{
|
||||
get { return _signalLevel; }
|
||||
set { if (_signalLevel != value) { _signalLevel = value; OnPropertyChanged("SignalLevel"); } }
|
||||
}
|
||||
public int SignalQuality
|
||||
{
|
||||
get { return _signalQuality; }
|
||||
set { if (_signalQuality != value) { _signalQuality = value; OnPropertyChanged("SignalQuality"); } }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Methods
|
||||
|
||||
private void ProcessSessionHeader(string sessionHeader, string response)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(sessionHeader))
|
||||
{
|
||||
var m = RegexRtspSessionHeader.Match(sessionHeader);
|
||||
if (!m.Success)
|
||||
{
|
||||
_logger.Error("Failed to tune, RTSP {0} response session header {1} format not recognised", response, sessionHeader);
|
||||
}
|
||||
_rtspSessionId = m.Groups[1].Captures[0].Value;
|
||||
_rtspSessionTimeToLive = m.Groups[3].Captures.Count == 1 ? int.Parse(m.Groups[3].Captures[0].Value) : DefaultRtspSessionTimeout;
|
||||
}
|
||||
}
|
||||
private void ProcessTransportHeader(string transportHeader)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(transportHeader))
|
||||
{
|
||||
var transports = transportHeader.Split(',');
|
||||
foreach (var transport in transports)
|
||||
{
|
||||
if (transport.Trim().StartsWith("RTP/AVP"))
|
||||
{
|
||||
var sections = transport.Split(';');
|
||||
foreach (var section in sections)
|
||||
{
|
||||
var parts = section.Split('=');
|
||||
if (parts[0].Equals("server_port"))
|
||||
{
|
||||
var ports = parts[1].Split('-');
|
||||
_serverRtpPort = int.Parse(ports[0]);
|
||||
_serverRtcpPort = int.Parse(ports[1]);
|
||||
}
|
||||
else if (parts[0].Equals("destination"))
|
||||
{
|
||||
_destination = parts[1];
|
||||
}
|
||||
else if (parts[0].Equals("port"))
|
||||
{
|
||||
var ports = parts[1].Split('-');
|
||||
_rtpPort = int.Parse(ports[0]);
|
||||
_rtcpPort = int.Parse(ports[1]);
|
||||
}
|
||||
else if (parts[0].Equals("ttl"))
|
||||
{
|
||||
_rtspSessionTimeToLive = int.Parse(parts[1]);
|
||||
}
|
||||
else if (parts[0].Equals("source"))
|
||||
{
|
||||
_source = parts[1];
|
||||
}
|
||||
else if (parts[0].Equals("client_port"))
|
||||
{
|
||||
var ports = parts[1].Split('-');
|
||||
var rtp = int.Parse(ports[0]);
|
||||
var rtcp = int.Parse(ports[1]);
|
||||
//if (!rtp.Equals(_rtpPort))
|
||||
//{
|
||||
// Logger.Error("SAT>IP base: server specified RTP client port {0} instead of {1}", rtp, _rtpPort);
|
||||
//}
|
||||
//if (!rtcp.Equals(_rtcpPort))
|
||||
//{
|
||||
// Logger.Error("SAT>IP base: server specified RTCP client port {0} instead of {1}", rtcp, _rtcpPort);
|
||||
//}
|
||||
_rtpPort = rtp;
|
||||
_rtcpPort = rtcp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private void Connect()
|
||||
{
|
||||
_rtspSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||
var ip = IPAddress.Parse(_address);
|
||||
var rtspEndpoint = new IPEndPoint(ip, 554);
|
||||
_rtspSocket.Connect(rtspEndpoint);
|
||||
}
|
||||
private void Disconnect()
|
||||
{
|
||||
if (_rtspSocket != null && _rtspSocket.Connected)
|
||||
{
|
||||
_rtspSocket.Shutdown(SocketShutdown.Both);
|
||||
_rtspSocket.Close();
|
||||
}
|
||||
}
|
||||
private void SendRequest(RtspRequest request)
|
||||
{
|
||||
if (_rtspSocket == null)
|
||||
{
|
||||
Connect();
|
||||
}
|
||||
try
|
||||
{
|
||||
request.Headers.Add("CSeq", _rtspSequenceNum.ToString());
|
||||
_rtspSequenceNum++;
|
||||
byte[] requestBytes = request.Serialise();
|
||||
if (_rtspSocket != null)
|
||||
{
|
||||
var requestBytesCount = _rtspSocket.Send(requestBytes, requestBytes.Length, SocketFlags.None);
|
||||
if (requestBytesCount < 1)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.Error(e.Message);
|
||||
}
|
||||
}
|
||||
private void ReceiveResponse(out RtspResponse response)
|
||||
{
|
||||
response = null;
|
||||
var responseBytesCount = 0;
|
||||
byte[] responseBytes = new byte[1024];
|
||||
try
|
||||
{
|
||||
responseBytesCount = _rtspSocket.Receive(responseBytes, responseBytes.Length, SocketFlags.None);
|
||||
response = RtspResponse.Deserialise(responseBytes, responseBytesCount);
|
||||
string contentLengthString;
|
||||
int contentLength = 0;
|
||||
if (response.Headers.TryGetValue("Content-Length", out contentLengthString))
|
||||
{
|
||||
contentLength = int.Parse(contentLengthString);
|
||||
if ((string.IsNullOrEmpty(response.Body) && contentLength > 0) || response.Body.Length < contentLength)
|
||||
{
|
||||
if (response.Body == null)
|
||||
{
|
||||
response.Body = string.Empty;
|
||||
}
|
||||
while (responseBytesCount > 0 && response.Body.Length < contentLength)
|
||||
{
|
||||
responseBytesCount = _rtspSocket.Receive(responseBytes, responseBytes.Length, SocketFlags.None);
|
||||
response.Body += System.Text.Encoding.UTF8.GetString(responseBytes, 0, responseBytesCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (SocketException)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Methods
|
||||
|
||||
public RtspStatusCode Setup(string query, string transporttype)
|
||||
{
|
||||
|
||||
RtspRequest request;
|
||||
RtspResponse response;
|
||||
//_rtspClient = new RtspClient(_rtspDevice.ServerAddress);
|
||||
if ((_rtspSocket == null))
|
||||
{
|
||||
Connect();
|
||||
}
|
||||
if (string.IsNullOrEmpty(_rtspSessionId))
|
||||
{
|
||||
request = new RtspRequest(RtspMethod.Setup, string.Format("rtsp://{0}:{1}/?{2}", _address, 554, query), 1, 0);
|
||||
switch (transporttype)
|
||||
{
|
||||
case "multicast":
|
||||
request.Headers.Add("Transport", string.Format("RTP/AVP;multicast"));
|
||||
break;
|
||||
case "unicast":
|
||||
var activeTcpConnections = IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpConnections();
|
||||
var usedPorts = new HashSet<int>();
|
||||
foreach (var connection in activeTcpConnections)
|
||||
{
|
||||
usedPorts.Add(connection.LocalEndPoint.Port);
|
||||
}
|
||||
for (var port = 40000; port <= 65534; port += 2)
|
||||
{
|
||||
if (!usedPorts.Contains(port) && !usedPorts.Contains(port + 1))
|
||||
{
|
||||
|
||||
_clientRtpPort = port;
|
||||
_clientRtcpPort = port + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
request.Headers.Add("Transport", string.Format("RTP/AVP;unicast;client_port={0}-{1}", _clientRtpPort, _clientRtcpPort));
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
request = new RtspRequest(RtspMethod.Setup, string.Format("rtsp://{0}:{1}/?{2}", _address, 554, query), 1, 0);
|
||||
switch (transporttype)
|
||||
{
|
||||
case "multicast":
|
||||
request.Headers.Add("Transport", string.Format("RTP/AVP;multicast"));
|
||||
break;
|
||||
case "unicast":
|
||||
request.Headers.Add("Transport", string.Format("RTP/AVP;unicast;client_port={0}-{1}", _clientRtpPort, _clientRtcpPort));
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
SendRequest(request);
|
||||
ReceiveResponse(out response);
|
||||
|
||||
//if (_rtspClient.SendRequest(request, out response) != RtspStatusCode.Ok)
|
||||
//{
|
||||
// Logger.Error("Failed to tune, non-OK RTSP SETUP status code {0} {1}", response.StatusCode, response.ReasonPhrase);
|
||||
//}
|
||||
if (!response.Headers.TryGetValue("com.ses.streamID", out _rtspStreamId))
|
||||
{
|
||||
_logger.Error(string.Format("Failed to tune, not able to locate Stream ID header in RTSP SETUP response"));
|
||||
}
|
||||
string sessionHeader;
|
||||
if (!response.Headers.TryGetValue("Session", out sessionHeader))
|
||||
{
|
||||
_logger.Error(string.Format("Failed to tune, not able to locate Session header in RTSP SETUP response"));
|
||||
}
|
||||
ProcessSessionHeader(sessionHeader, "Setup");
|
||||
string transportHeader;
|
||||
if (!response.Headers.TryGetValue("Transport", out transportHeader))
|
||||
{
|
||||
_logger.Error(string.Format("Failed to tune, not able to locate Transport header in RTSP SETUP response"));
|
||||
}
|
||||
ProcessTransportHeader(transportHeader);
|
||||
return response.StatusCode;
|
||||
}
|
||||
|
||||
public RtspStatusCode Play(string query)
|
||||
{
|
||||
if ((_rtspSocket == null))
|
||||
{
|
||||
Connect();
|
||||
}
|
||||
//_rtspClient = new RtspClient(_rtspDevice.ServerAddress);
|
||||
RtspResponse response;
|
||||
string data;
|
||||
if (string.IsNullOrEmpty(query))
|
||||
{
|
||||
data = string.Format("rtsp://{0}:{1}/stream={2}", _address,
|
||||
554, _rtspStreamId);
|
||||
}
|
||||
else
|
||||
{
|
||||
data = string.Format("rtsp://{0}:{1}/stream={2}?{3}", _address,
|
||||
554, _rtspStreamId, query);
|
||||
}
|
||||
var request = new RtspRequest(RtspMethod.Play, data, 1, 0);
|
||||
request.Headers.Add("Session", _rtspSessionId);
|
||||
SendRequest(request);
|
||||
ReceiveResponse(out response);
|
||||
//if (_rtspClient.SendRequest(request, out response) != RtspStatusCode.Ok)
|
||||
//{
|
||||
// Logger.Error("Failed to tune, non-OK RTSP SETUP status code {0} {1}", response.StatusCode, response.ReasonPhrase);
|
||||
//}
|
||||
//Logger.Info("RtspSession-Play : \r\n {0}", response);
|
||||
string sessionHeader;
|
||||
if (!response.Headers.TryGetValue("Session", out sessionHeader))
|
||||
{
|
||||
_logger.Error(string.Format("Failed to tune, not able to locate Session header in RTSP Play response"));
|
||||
}
|
||||
ProcessSessionHeader(sessionHeader, "Play");
|
||||
string rtpinfoHeader;
|
||||
if (!response.Headers.TryGetValue("RTP-Info", out rtpinfoHeader))
|
||||
{
|
||||
_logger.Error(string.Format("Failed to tune, not able to locate Rtp-Info header in RTSP Play response"));
|
||||
}
|
||||
return response.StatusCode;
|
||||
}
|
||||
|
||||
public RtspStatusCode Options()
|
||||
{
|
||||
if ((_rtspSocket == null))
|
||||
{
|
||||
Connect();
|
||||
}
|
||||
//_rtspClient = new RtspClient(_rtspDevice.ServerAddress);
|
||||
RtspRequest request;
|
||||
RtspResponse response;
|
||||
|
||||
|
||||
if (string.IsNullOrEmpty(_rtspSessionId))
|
||||
{
|
||||
request = new RtspRequest(RtspMethod.Options, string.Format("rtsp://{0}:{1}/", _address, 554), 1, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
request = new RtspRequest(RtspMethod.Options, string.Format("rtsp://{0}:{1}/", _address, 554), 1, 0);
|
||||
request.Headers.Add("Session", _rtspSessionId);
|
||||
}
|
||||
SendRequest(request);
|
||||
ReceiveResponse(out response);
|
||||
//if (_rtspClient.SendRequest(request, out response) != RtspStatusCode.Ok)
|
||||
//{
|
||||
// Logger.Error("Failed to tune, non-OK RTSP SETUP status code {0} {1}", response.StatusCode, response.ReasonPhrase);
|
||||
//}
|
||||
//Logger.Info("RtspSession-Options : \r\n {0}", response);
|
||||
string sessionHeader;
|
||||
if (!response.Headers.TryGetValue("Session", out sessionHeader))
|
||||
{
|
||||
_logger.Error(string.Format("Failed to tune, not able to locate session header in RTSP Options response"));
|
||||
}
|
||||
ProcessSessionHeader(sessionHeader, "Options");
|
||||
string optionsHeader;
|
||||
if (!response.Headers.TryGetValue("Public", out optionsHeader))
|
||||
{
|
||||
_logger.Error(string.Format("Failed to tune, not able to Options header in RTSP Options response"));
|
||||
}
|
||||
return response.StatusCode;
|
||||
}
|
||||
|
||||
public RtspStatusCode Describe(out int level, out int quality)
|
||||
{
|
||||
if ((_rtspSocket == null))
|
||||
{
|
||||
Connect();
|
||||
}
|
||||
//_rtspClient = new RtspClient(_rtspDevice.ServerAddress);
|
||||
RtspRequest request;
|
||||
RtspResponse response;
|
||||
level = 0;
|
||||
quality = 0;
|
||||
|
||||
if (string.IsNullOrEmpty(_rtspSessionId))
|
||||
{
|
||||
request = new RtspRequest(RtspMethod.Describe, string.Format("rtsp://{0}:{1}/", _address, 554), 1, 0);
|
||||
request.Headers.Add("Accept", "application/sdp");
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
request = new RtspRequest(RtspMethod.Describe, string.Format("rtsp://{0}:{1}/stream={2}", _address, 554, _rtspStreamId), 1, 0);
|
||||
request.Headers.Add("Accept", "application/sdp");
|
||||
request.Headers.Add("Session", _rtspSessionId);
|
||||
}
|
||||
SendRequest(request);
|
||||
ReceiveResponse(out response);
|
||||
//if (_rtspClient.SendRequest(request, out response) != RtspStatusCode.Ok)
|
||||
//{
|
||||
// Logger.Error("Failed to tune, non-OK RTSP Describe status code {0} {1}", response.StatusCode, response.ReasonPhrase);
|
||||
//}
|
||||
//Logger.Info("RtspSession-Describe : \r\n {0}", response);
|
||||
string sessionHeader;
|
||||
if (!response.Headers.TryGetValue("Session", out sessionHeader))
|
||||
{
|
||||
_logger.Error(string.Format("Failed to tune, not able to locate session header in RTSP Describe response"));
|
||||
}
|
||||
ProcessSessionHeader(sessionHeader, "Describe");
|
||||
var m = RegexDescribeResponseSignalInfo.Match(response.Body);
|
||||
if (m.Success)
|
||||
{
|
||||
|
||||
//isSignalLocked = m.Groups[2].Captures[0].Value.Equals("1");
|
||||
level = int.Parse(m.Groups[1].Captures[0].Value) * 100 / 255; // level: 0..255 => 0..100
|
||||
quality = int.Parse(m.Groups[3].Captures[0].Value) * 100 / 15; // quality: 0..15 => 0..100
|
||||
|
||||
}
|
||||
/*
|
||||
v=0
|
||||
o=- 1378633020884883 1 IN IP4 192.168.2.108
|
||||
s=SatIPServer:1 4
|
||||
t=0 0
|
||||
a=tool:idl4k
|
||||
m=video 52780 RTP/AVP 33
|
||||
c=IN IP4 0.0.0.0
|
||||
b=AS:5000
|
||||
a=control:stream=4
|
||||
a=fmtp:33 ver=1.0;tuner=1,0,0,0,12344,h,dvbs2,,off,,22000,34;pids=0,100,101,102,103,106
|
||||
=sendonly
|
||||
*/
|
||||
|
||||
|
||||
return response.StatusCode;
|
||||
}
|
||||
|
||||
public RtspStatusCode TearDown()
|
||||
{
|
||||
if ((_rtspSocket == null))
|
||||
{
|
||||
Connect();
|
||||
}
|
||||
//_rtspClient = new RtspClient(_rtspDevice.ServerAddress);
|
||||
RtspResponse response;
|
||||
|
||||
var request = new RtspRequest(RtspMethod.Teardown, string.Format("rtsp://{0}:{1}/stream={2}", _address, 554, _rtspStreamId), 1, 0);
|
||||
request.Headers.Add("Session", _rtspSessionId);
|
||||
SendRequest(request);
|
||||
ReceiveResponse(out response);
|
||||
//if (_rtspClient.SendRequest(request, out response) != RtspStatusCode.Ok)
|
||||
//{
|
||||
// Logger.Error("Failed to tune, non-OK RTSP Teardown status code {0} {1}", response.StatusCode, response.ReasonPhrase);
|
||||
//}
|
||||
return response.StatusCode;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Events
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
protected void OnPropertyChanged(string name)
|
||||
{
|
||||
//var handler = PropertyChanged;
|
||||
//if (handler != null)
|
||||
//{
|
||||
// handler(this, new PropertyChangedEventArgs(name));
|
||||
//}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);//Disconnect();
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!_disposed)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
TearDown();
|
||||
Disconnect();
|
||||
}
|
||||
}
|
||||
_disposed = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -251,6 +251,7 @@
|
|||
<Compile Include="LiveTv\TunerHosts\SatIp\Rtsp\RtspMethod.cs" />
|
||||
<Compile Include="LiveTv\TunerHosts\SatIp\Rtsp\RtspRequest.cs" />
|
||||
<Compile Include="LiveTv\TunerHosts\SatIp\Rtsp\RtspResponse.cs" />
|
||||
<Compile Include="LiveTv\TunerHosts\SatIp\Rtsp\RtspSession.cs" />
|
||||
<Compile Include="LiveTv\TunerHosts\SatIp\Rtsp\RtspStatusCode.cs" />
|
||||
<Compile Include="LiveTv\TunerHosts\SatIp\SatIpHost.cs" />
|
||||
<Compile Include="LiveTv\TunerHosts\SatIp\SatIpDiscovery.cs" />
|
||||
|
|
Loading…
Reference in New Issue
Block a user