Application exists for RTMP but not RTSP?

Hello, me again.

I have the exact same code in my plugin for authenticating both RTMP & RTSP links, but when I try an RTSP stream it says my application does not exist (or something to that effect), whereas RTMP streams fine.

	/*
	 * Triggered for RT-M-P streams
	 */
	public void onConnect(IClient client, RequestFunction function, AMFDataList param) {
		getLogger().info("AuthorizationModule -- onConnect");
		try {
			if (!validateRequest(client.getUri(), client.getQueryStr(), client.getIp())) {
				client.rejectConnection();
			}
		} catch (Exception e) {
			getLogger().error("Exception getting key from URI " +e.getClass()+" : "+ e.getMessage());
			sendClientOnStatusError(client, "Error", "Sorry, an error occured, please verify the link.");
			client.rejectConnection();
		}
	}
	/*
	 * Triggered for RT-S-P streams
	 */
	public void onRTPSessionCreate(RTPSession rtpSession) {
		getLogger().info("AuthorizationModule -- onRTPSessionCreate");
		try {
			if (!validateRequest(rtpSession.getUri(), rtpSession.getQueryStr(), rtpSession.getIp())) {
				rtpSession.rejectSession();
			}
		} catch (Exception e) {
			getLogger().error("Exception getting key from URI " +e.getClass()+" : "+ e.getMessage());
			sendStreamOnStatusError(new MediaStreamBase(), "NetStream.Play.Failed",
					"Sorry, an error occured, please verify the link.");
			rtpSession.rejectSession();
		}
	}
	// common for all requests independent of protocol
	private boolean validateRequest(String URI, String qs, String ip) throws Exception {
		WowzaSession newSession = new WowzaSession(ip, URI);
		getLogger().info("play URI: " + URI);
		getLogger().info("params: " + qs);
		int contentIndex = qs.indexOf("contentId=");
		String key = qs.substring(qs.indexOf("key=") + 4, contentIndex);
		String contentId = (qs.lastIndexOf('/') < contentIndex + 10) ? qs.substring(contentIndex + 10) : qs.substring(
				contentIndex + 10, qs.lastIndexOf('/')); // last "/" not always
		// present
		if (validatePcLink(URI+qs, contentId,ip)) {
				getLogger().info("Access granted!");
		} else {
			getLogger().info("Access denied - invalid streaming link or RDMLShield error: " + URI);
			return false;
		}
		return true;
	}

So I can successfully stream:

rtmp://localhost:1935/vod?key=MSExMjkwNzcxMzM5ITNoIVghRXh0cmVtaXN0cyExMjcuMC4wLjFKcNJuGYmq0sQ2efphifY4contentId=Extremists/Extremists_1.flv

Logging is:

INFO session connect-pending 127.0.0.1 -

INFO server comment - AuthorizationModule – onConnect

INFO server comment - play URI: rtmp://localhost:1935/vod

INFO server comment - params: key=MSExMjkwNzcxMzM5ITNoIVghRXh0cmVtaXN0cyExMjcuMC4wLjFKcNJuGYmq0sQ2efphifY4contentId=Extremists/

INFO server comment - Validating:http://localhost:8081/validatePcLink?name=rtmp://localhost:1935/vodkey=MSExMjkwNzcxMzM5ITNoIVghRXh0cmVtaXN0cyExMjcuMC4wLjFKcNJuGYmq0sQ2efphifY4contentId=Extremists/&contentId=Extremists&clientIp=127.0.0.1

INFO server comment - Got response from RDMLShield: true

INFO server comment - Access granted!

INFO session connect 127.0.0.1 -

INFO stream create - -

INFO stream play Extremists_1 -

NOW… If I try the exact same thing, except for RTSP:

rtsp://localhost:1935/vod?key=MCExMjg2MzY4MDAyITIwaCFYIUV4dHJlbWlzdHMhMTI3LjAuMC4xcj0TwivcmyDx3KjxMIqMyg…contentId=sample/sample_1.mp4

Then I get this little bundle of joy:

WARN server comment - Application folder ([install-location]/applications/defapp) is missing

I’ve had so many problems getting the parameters successfully, intercepting the requests successfully, and now it seems in some cases my plugin does not even exist. To a lay observer it looks like Wowza has a mind of its own, and just randomly does stuff like this.

I have not changed my application.xml.

I have not updated Wowza.

Playmethod is still none.

sample_1.mp4 exists in the same place as extremists_1.flv, in the vod folder under content, and in the content folder too.

<Root>
	<Application>
		<!-- Uncomment to set application level timeout values
		<ApplicationTimeout>60000</ApplicationTimeout>
		<PingTimeout>12000</PingTimeout>
		<ValidationFrequency>8000</ValidationFrequency>
		<MaximumPendingWriteBytes>0</MaximumPendingWriteBytes>
		<MaximumSetBufferTime>60000</MaximumSetBufferTime>
		<MaximumStorageDirDepth>25</MaximumStorageDirDepth>
		-->
		<Connections>
			<AutoAccept>true</AutoAccept>
			<AllowDomains></AllowDomains>
		</Connections>
		<!--
			StorageDir path variables
			
			${com.wowza.wms.AppHome} - Application home directory
			${com.wowza.wms.ConfigHome} - Configuration home directory
			${com.wowza.wms.context.VHost} - Virtual host name
			${com.wowza.wms.context.VHostConfigHome} - Virtual host config directory
			${com.wowza.wms.context.Application} - Application name
			${com.wowza.wms.context.ApplicationInstance} - Application instance name
			
		-->
		<Streams>
			<StreamType>default</StreamType>
			<StorageDir>${com.wowza.wms.context.VHostConfigHome}/content</StorageDir>
			<KeyDir>${com.wowza.wms.context.VHostConfigHome}/keys</KeyDir>
			<!-- LiveStreamPacketizers (separate with commas): cupertinostreamingpacketizer, smoothstreamingpacketizer, cupertinostreamingrepeater, smoothstreamingrepeater -->
			<LiveStreamPacketizers></LiveStreamPacketizers>			
			<!-- Properties defined here will override any properties defined in conf/Streams.xml for any streams types loaded by this application -->
			<Properties>
			</Properties>
		</Streams>
		<!-- HTTPStreamers (separate with commas): cupertinostreaming, smoothstreaming -->
		<HTTPStreamers>cupertinostreaming,smoothstreaming</HTTPStreamers>			
		<SharedObjects>
			<StorageDir></StorageDir>
		</SharedObjects>
		<Client>
			<IdleFrequency>-1</IdleFrequency>
			<Access>
				<StreamReadAccess>*</StreamReadAccess>
				<StreamWriteAccess>*</StreamWriteAccess>
				<StreamAudioSampleAccess></StreamAudioSampleAccess>
				<StreamVideoSampleAccess></StreamVideoSampleAccess>
				<SharedObjectReadAccess>*</SharedObjectReadAccess>
				<SharedObjectWriteAccess>*</SharedObjectWriteAccess>
			</Access>
		</Client>
		<RTP>
			<!-- RTP/Authentication/[type]Methods defined in Authentication.xml. Default setup includes; none, basic, digest -->
			<Authentication>
				<PublishMethod>digest</PublishMethod>
				<PlayMethod>none</PlayMethod>
			</Authentication>
			<!-- RTP/AVSyncMethod. Valid values are: senderreport, systemclock, rtptimecode -->
			<AVSyncMethod>senderreport</AVSyncMethod>
			<MaxRTCPWaitTime>12000</MaxRTCPWaitTime>
			<IdleFrequency>75</IdleFrequency>
			<RTSPSessionTimeout>90000</RTSPSessionTimeout>
			<RTSPMaximumPendingWriteBytes>0</RTSPMaximumPendingWriteBytes>
			<RTSPBindIpAddress></RTSPBindIpAddress>
			<RTSPConnectionIpAddress>0.0.0.0</RTSPConnectionIpAddress>
			<RTSPOriginIpAddress>127.0.0.1</RTSPOriginIpAddress>
			<IncomingDatagramPortRanges>*</IncomingDatagramPortRanges>
			<!-- Properties defined here will override any properties defined in conf/RTP.xml for any depacketizers loaded by this application -->
			<Properties>
			</Properties>
		</RTP>
		<MediaCaster>
			<!-- Properties defined here will override any properties defined in conf/MediaCasters.xml for any MediaCasters loaded by this applications -->
			<Properties>
			</Properties>
		</MediaCaster>
		<MediaReader>
			<!-- Properties defined here will override any properties defined in conf/MediaReaders.xml for any MediaReaders loaded by this applications -->
			<Properties>
			</Properties>
		</MediaReader>
		<MediaWriter>
			<!-- Properties defined here will override any properties defined in conf/MediaWriter.xml for any MediaWriter loaded by this applications -->
			<Properties>
			</Properties>
		</MediaWriter>
		<LiveStreamPacketizer>
			<!-- Properties defined here will override any properties defined in conf/LiveStreamPacketizers.xml for any LiveStreamPacketizers loaded by this applications -->
			<Properties>
			</Properties>
		</LiveStreamPacketizer>
		<HTTPStreamer>
			<!-- Properties defined here will override any properties defined in conf/HTTPStreamers.xml for any HTTPStreamer loaded by this applications -->
			<Properties>
			</Properties>
		</HTTPStreamer>
		<Repeater>
			<OriginURL></OriginURL>
			<QueryString><![CDATA[]]></QueryString>
		</Repeater> 
		<Modules>
			<Module>
				<Name>base</Name>
				<Description>Base</Description>
				<Class>com.wowza.wms.module.ModuleCore</Class>
			</Module>
			<Module>
				<Name>properties</Name>
				<Description>Properties</Description>
				<Class>com.wowza.wms.module.ModuleProperties</Class>
			</Module>
			<Module>
				<Name>logging</Name>
				<Description>Client Logging</Description>
				<Class>com.wowza.wms.module.ModuleClientLogging</Class>
			</Module>
			<Module>
				<Name>flvplayback</Name>
				<Description>FLVPlayback</Description>
				<Class>com.wowza.wms.module.ModuleFLVPlayback</Class>
			</Module> 
			<Module>
				<Name>AuthorizationModule</Name>
				<Description>AuthorizationModule</Description>
				<Class>com.rdml.wms.authplugin.AuthorizationModule</Class>
			</Module> 
		</Modules>
		<!-- Properties defined here will be added to the IApplication.getProperties() and IApplicationInstance.getProperties() collections -->
		<Properties>
		</Properties>
	</Application>
</Root>

RTSP/RTP is invoked using a single URL. So the server URL and stream name are combined. The format of an RTSP/RTP URL is:

rstp://[wowza-ip-address]/[application]/[appInstance]/[stream-path-name]

You are missing the stream name part.

Charlie

You URL is going to break down to:

rtsp://localhost:1935/vod?key=MCExMjg2MzY4MDAyITIwaCFYIUV4dHJlbWlzdHMhMT I3LjAuMC4xcj0TwivcmyDx3KjxMIqMyg…contentId=sample/sample_1.mp4

URL: rtsp://localhost:1935/vod

Query String: key=MCExMjg2MzY4MDAyITIwaCFYIUV4dHJlbWlzdHMhMT I3LjAuMC4xcj0TwivcmyDx3KjxMIqMyg…contentId=sample/sample_1.mp4

So the URL only contains the application name. Everything after the ? is treated as a query string.

Charlie

For RTMP the connection URL and stream name are separate items. To connect using RTMP you call:

NetConnection.connect(connectionURL).

and you play a stream by calling:

NetStream.play(streamName);

Sometime these are combined. My guess in your case is that they are not. In your player code you are most likely calling NetStream.play(streamName). So the fact that the stream name is in the query parameters in the connection URL is separate from the call to NetStream.play(streamName).

For RTSP/RTP these two things are not separate and there is not separate call to the play the stream. So your RSTP/RTP URL will be broken into pieces as I suggested earlier.

So to answer this question directly “Do RTMP and RTSP links have to be formatted differently?” Yes, they are different. In Flash the connection URL and stream name are separate. In RTSP/RTP they are combined in the format:

RTMP:

Connection URL: rtmp://[wowza-ip-address]/[application]/[appInstance]

Stream: [stream-path-name]

RTSP/RTP:

URL: rstp://[wowza-ip-address]/[application]/[appInstance]/[stream-path-name]

Charlie

I am missing [stream-path-name] ?

No, I have sample_1.mp4 for that. Exactly the way I did for RTMP.

So the format of a wowza RTSP link is different from a RTMP link? How so? What is the difference? What should my link look like?

What is this appInstance part? I did not need that for RTMP.

[application]: vod + all my paramters

[stream-path-name]: sample_1.mp4 for RTSP, and Extremists_1.flv for RTMP.

Again, this works for RTMP, but not RTSP.

I’m sorry, but that does not answer my question.

This is my RTMP link that works: rtmp://localhost:1935/vod?key=MSExMjkwNzcxMzM5ITNoIVghRXh0cmVtaXN0cyExMj cuMC4wLjFKcNJuGYmq0sQ2efphifY4contentId=Extremists/Extremists_1.flv

My question is this: How come it works fine for RTMP with the link formatted like this, but fails for RTSP?

getLogger().info("play URI: " + client.getUri());

getLogger().info("params: " + client.getQueryStr());

gives the following output when called with the link above:

INFO server comment - play URI: rtmp://localhost:1935/vod

INFO server comment - params: key=MSExMjkwNzcxMzM5ITNoIVghRXh0cmVtaXN0cyExMjcuMC 4wLjFKcNJuGYmq0sQ2efphifY4contentId=Extremists/

So for RTMP at least, what you said is incorrect. Everything after the ? is not treated as the querystring, at least not for the RTMP link above. If only it would act like this with RTSP links, then I could move on.

My main question is this: Do RTMP and RTSP links have to be formatted differently? How come my RTMP link works in this exact same format, which you say is incorrect. Could this be a bug or something?

I am absolutely positive that the RTMP link above works.

Thanks, I think I got it now.