onvif Learning Notes 10: Get RTSP Stream Address

Keywords: xml Attribute network

Some netizens bought mine ONVIF Video Course I asked a few questions, one of which is to realize the function of ONVIF server to get RTSP address. This paper sorted out a train of thought, hoping to help you on the way of learning ONVIF.
The video I recorded was very early, and I never took time to record another live video, so all net friends who buy it will give guidance. Of course, limited to ability, not all the questions are answered.

Official WSDL Notes

The ONVIF protocol obtains the stream address through GetStreamUri. Official wsdl Page search for GetStreamUri shows details of the command.
Detailed fields are shown in Figure 1:

GetStreamUri is a client-initiated request with two fields:
The first is ProfileToken, which is the name of the media profile to be retrieved - because different profiles can have different media parameters. In the simplest case, the camera has two video outputs, 720P and 1080P, and there will be two media profiles (represented by different token s), so you need to specify which profile you want to get.
The second is the Stream Setup for flow parameters. The explanation is as follows:

  • Stream: An enumeration type that specifies unicast or multicast.
  • Transport: Specifies the transport protocol.
    GetStreamUriResponse is a response package whose fields are filled by the server. The client just needs to assemble GetStreamUri and send it out, waiting for the response package.
  • Uri: Stream address.
  • InvalidAfterConnect: Indicates whether only the uri after the connection is valid, set to false.
  • InvalidAfterReboot: Indicates whether the uri is valid after restart, set to false.
  • Timeout: The timeout time, set to 0, is permanent, even if the profile changes.

I doubt: InvalidAfterConnect and InvalidAfterReboot seem to be incompatible literally and interpretatively, but they seem to make sense when compared with ValidUntilConnectt ValidUntilReboot in official instructions. I suspect that the inconsistency in the presentation of the update process of the CSS document results in the inconsistency. In the code, be sure to set these two fields to false.

Ideas for Code Implementation

Next, we will talk about the idea of code implementation from the client and server.

Client access code

First, set the _trt__GetStreamUri structure to the specified profile name. —— The profile name is obtained by other functions.
Secondly, the tt_StreamSetup structure is set to unicast, and the enumeration value is tt_StreamType__RTP_Unicast.
Thirdly, set the tt_ Transport structure field and the protocol is tt_ Transport Protocol_ UDP.
Finally, the soap_call__trt__GetStreamUri function is called. MediaUri in _trt_ GetStreamUriResponse carries Uri, which is also the stream address mentioned at the beginning of this article.

Server-side return code

In the function responding to GetStreamUri, the fields of _trt_ GetStreamUri band are judged, such as pointer validity, profile validity, and transmission protocol judgment.
Then set MediaUri of trt__GetStream UriResponse, including Uri, InvalidAfterConnect, InvalidAfterReboot and Timeout. Uri is the RTSP media address.
Regarding RTSP address settings, we can fix a format, fix it in the stream server, and then fix it in the ONVIF server, but this is inconvenient. It can also be generated in the stream server and notified to the ONVIF server through process communication, which is convenient for maintenance.

Code structure

The structure involved in this paper is more complex and has been deleted.

class _trt__GetStreamUri
{ public:
/// <PRE><BLOCKQUOTE>
///   Stream Setup that should be used with the uri
/// </BLOCKQUOTE></PRE>
/// Element "StreamSetup" of XSD type "http://www.onvif.org/ver10/schema":StreamSetup.
    tt__StreamSetup*                     StreamSetup                    1;    ///< Required element.
/// <PRE><BLOCKQUOTE>
///   The ProfileToken element indicates the media profile to use and will define the configuration of the content of the stream.
/// </BLOCKQUOTE></PRE>
/// Element "ProfileToken" of XSD type "http://www.onvif.org/ver10/schema":ReferenceToken.
    tt__ReferenceToken                   ProfileToken                   1;    ///< Required element.
/// A handle to the soap struct context that manages this instance when instantiated by a context or NULL otherwise (automatically set).
    struct soap                         *soap                          ;
};

class tt__StreamSetup
{ public:
/// <PRE><BLOCKQUOTE>
///   Defines if a multicast or unicast stream is requested
/// </BLOCKQUOTE></PRE>
/// Element "Stream" of XSD type "http://www.onvif.org/ver10/schema":StreamType.
    enum tt__StreamType                  Stream                         1;    ///< Required element.
/// Element "Transport" of XSD type "http://www.onvif.org/ver10/schema":Transport.
    tt__Transport*                       Transport                      1;    ///< Required element.
/// @todo <any namespace="##any" minOccurs="0" maxOccurs="unbounded">
/// @todo Schema extensibility is user-definable.
///       Consult the protocol documentation to change or insert declarations.
///       Use wsdl2h option -x to remove this element.
///       Use wsdl2h option -d for xsd__anyType DOM (soap_dom_element).
/// Size of the array of XML or DOM nodes is 0..unbounded.
    std::vector<xsd__anyType           > __any                         0;    ///< Catch any element content in DOM.
/// @todo <anyAttribute namespace="##any">.
/// @todo Schema extensibility is user-definable.
///       Consult the protocol documentation to change or insert declarations.
///       Use wsdl2h option -x to remove this attribute.
///       Use wsdl2h option -d for xsd__anyAttribute DOM (soap_dom_attribute).
   @xsd__anyAttribute                    __anyAttribute                ;    ///< Store anyAttribute content in DOM soap_dom_attribute linked node structure.
/// A handle to the soap struct context that manages this instance when instantiated by a context or NULL otherwise (automatically set).
    struct soap                         *soap                          ;
};

enum tt__StreamType
{
    tt__StreamType__RTP_Unicast,    ///< xs:string value="RTP-Unicast"
    tt__StreamType__RTP_Multicast,    ///< xs:string value="RTP-Multicast"
};

class tt__Transport
{ public:
/// <PRE><BLOCKQUOTE>
///   Defines the network protocol for streaming, either UDP=RTP/UDP, RTSP=RTP/RTSP/TCP or HTTP=RTP/RTSP/HTTP/TCP
/// </BLOCKQUOTE></PRE>
/// Element "Protocol" of XSD type "http://www.onvif.org/ver10/schema":TransportProtocol.
    enum tt__TransportProtocol           Protocol                       1;    ///< Required element.
/// <PRE><BLOCKQUOTE>
///   Optional element to describe further tunnel options. This element is normally not needed
/// </BLOCKQUOTE></PRE>
/// Element "Tunnel" of XSD type "http://www.onvif.org/ver10/schema":Transport.
    tt__Transport*                       Tunnel                         0;    ///< Optional element.
/// A handle to the soap struct context that manages this instance when instantiated by a context or NULL otherwise (automatically set).
    struct soap                         *soap                          ;
};

enum tt__TransportProtocol
{
    tt__TransportProtocol__UDP,    ///< xs:string value="UDP"
    tt__TransportProtocol__TCP,    ///< xs:string value="TCP"
    tt__TransportProtocol__RTSP,    ///< xs:string value="RTSP"
    tt__TransportProtocol__HTTP,    ///< xs:string value="HTTP"
};

Response package structure:

class _trt__GetStreamUriResponse
{ public:

/// </BLOCKQUOTE></PRE>
/// Element "MediaUri" of XSD type "http://www.onvif.org/ver10/schema":MediaUri.
    tt__MediaUri*                        MediaUri                       1;    ///< Required element.
/// A handle to the soap struct context that manages this instance when instantiated by a context or NULL otherwise (automatically set).
    struct soap                         *soap                          ;
};

class tt__MediaUri
{ public:
/// <PRE><BLOCKQUOTE>
///   Stable Uri to be used for requesting the media stream
/// </BLOCKQUOTE></PRE>
/// Element "Uri" of XSD type xs:anyURI.
    xsd__anyURI                          Uri                            1;    ///< Required element.
/// <PRE><BLOCKQUOTE>
///   Indicates if the Uri is only valid until the connection is established. The value shall be set to "false".
/// </BLOCKQUOTE></PRE>
/// Element "InvalidAfterConnect" of XSD type xs:boolean.
    bool                                 InvalidAfterConnect            1;    ///< Required element.
/// <PRE><BLOCKQUOTE>
///   Indicates if the Uri is invalid after a reboot of the device. The value shall be set to "false".
/// </BLOCKQUOTE></PRE>
/// Element "InvalidAfterReboot" of XSD type xs:boolean.
    bool                                 InvalidAfterReboot             1;    ///< Required element.
/// <PRE><BLOCKQUOTE>
///   Duration how long the Uri is valid. This parameter shall be set to PT0S to indicate that this stream URI is indefinitely valid even if the profile changes
/// </BLOCKQUOTE></PRE>
/// Element "Timeout" of XSD type xs:duration.
    xsd__duration                        Timeout                        1;    ///< Required element.
/// @todo <any namespace="##any" minOccurs="0" maxOccurs="unbounded">
/// @todo Schema extensibility is user-definable.
///       Consult the protocol documentation to change or insert declarations.
///       Use wsdl2h option -x to remove this element.
///       Use wsdl2h option -d for xsd__anyType DOM (soap_dom_element).
/// Size of the array of XML or DOM nodes is 0..unbounded.
    std::vector<xsd__anyType           > __any                         0;    ///< Catch any element content in DOM.
/// @todo <anyAttribute namespace="##any">.
/// @todo Schema extensibility is user-definable.
///       Consult the protocol documentation to change or insert declarations.
///       Use wsdl2h option -x to remove this attribute.
///       Use wsdl2h option -d for xsd__anyAttribute DOM (soap_dom_attribute).
   @xsd__anyAttribute                    __anyAttribute                ;    ///< Store anyAttribute content in DOM soap_dom_attribute linked node structure.
/// A handle to the soap struct context that manages this instance when instantiated by a context or NULL otherwise (automatically set).
    struct soap                         *soap                          ;
};

Epilogue

In this paper, the GetStreamUri field is only explained, and the connection of ONVIF and the authentication of ONVIF are not mentioned.
The functions and enumerations presented in this paper are all ONVIF framework codes generated by the author a long time ago, which does not mean that the ONVIF code generated at the time of publication of this article is the same.
The profile mentioned in this article can be used to search for information on the Internet or refer to the articles written by the author before.
ONVIF does not implement RTSP streaming services, but only provides a channel for clients to get stream addresses. In the actual project, live 555 (I have studied for some time, other services are not contacted) can be used to achieve.
As ONVIF has fewer references, there are inevitably some mistakes and omissions in this article. You are welcome to correct them, learn together and make progress together.

Reference material:

onvif GetStreamUri

Li Chi, late Monday, April 15, 2019

Posted by DemonMaestro on Fri, 10 May 2019 14:12:04 -0700