RTMP dynamic streaming use nrgp thru Edge/Origin

This is a extension of the post.

to make RTMP dynamic streaming(by JW player) thru Edge/Origin, I would like to use nrgp because I try to avoid creating single smil file on edge for each new incoming stream from origin dynamically. If it’s possible, please help to prompt how to achieve it .

Thank you

The ngrp: prefix (Wowza Transcoder StreamNameGroups) does not work on edges, because the edge is just re-streaming each stream. You have to have a smil or other form of MediaList on each edge. There are two ways to do that:

You can generate a smil on the origin/Transcoder. The generated .smil file may have to be adjusted to use .stream names or alias names if you are using either of those, but this convenience method generates all the encoding details that are useful in HLS streaming.

Or you can generate an amlst MediaList using IMediaListProvider API

Richard

Andy,

On the edge, create a .stream file in the /content folder that contains the full rtmp url of the origin stream. Call it origin.stream for this example.

File:

/content/origin.stream

Contents:

rtmp://[wowza-origin-address]:1935/liveorigin/myStream

Then use origin.stream as the stream name.

Flash Player

Server: rtmp://[wowza-edge-address]:1935/liveedge

Stream: origin.stream

base on this usage (i.e. origin server location keeps in client side rather than edge server), could you prompt more on :

  1. how to configure the jw player client-side xml to thru edge/origin in this 2 solutions (smil/ IMediaListProvider API)?
<script type="text/javascript">
jwplayer("player").setup({
    playlist: [{
        sources: [
            { file: "http://[wowza-edge-address]:1935/liveedge/origin.stream", },
        ],
    }],
    sources: [{
            file: "http://[wowza-edge-address]:1935/liveedge/origin.stream"
        }]
});
</script>

For ABR on the edge you have to start each rendition in a different .stream file. For example:

<smil>
	<head>
	</head>
	<body>
		<switch>
			<video src="origin_low.stream" system-bitrate="250000"/>
			<video src="origin_high.stream" system-bitrate="450000"/>
		</switch>
	</body>
</smil>

For ABR to work correctly on edge servers, you should start and loc them with the MediaCaster system following this guide.

Richard

Hi Andy,

While it is not possible to use ngrp directly on the edge, it is possible to specify an alternate protocol, domain name & port when making the request to the origin server to get the jwplayer.smil url.

http://<transcoder-ip>:1935/live/ngrp:mySteam_all/jwplayer.smil?protocol=rtmp&domain=<edge-ip>

The application name cannot be changed so must match on both the origin & edge. The edge application should be configured as a normal edge application.

This will return a JW Player smil file with the edge rtmp address set in the smil.

A similar approach will not work for http ABR so you still need the smil file on the edge for this to work. With the smil on the edge, it makes sense to just use that instead of the above example.

For dynamic startup on the edge, you should use a slightly different approach to what Richard linked to. That approach is really for when you need the streams locked on the edge for some reason (such as recording or push publish etc) rather than for normal playback.

For dynamic startup, you need to configure the origin server to do the http packetizing.

Step 2 in the example.

<LiveStreamPacketizers>cupertinostreamingpacketizer,smoothstreamingpacketizer,sanjosestreamingpacketizer</LiveStreamPacketizers>

On the edges, you do need the stream type set to liverepeater-edge so that the edges will automatically connect to the origin(s) when the stream is requested.

Step 3 in the example.

<StreamType>liverepeater-edge</StreamType>

So that the http streams on the edge will work, you need to configure the edge LiveStreamPacketizers as repeaters.

Step 4 in the example.

<LiveStreamPacketizers>cupertinostreamingrepeater,smoothstreamingrepeater,sanjosestreamingrepeater</LiveStreamPacketizers>

Steps 5 is still the same. You do need to create the stream files that map to the appropriate origin streams. The .stream files can reference multiple origin servers by separating each server url with a pipe | character. You can also use the Stream Name Alias AddOn or api here in place of stream files.

Step 6 is the same. You do need a local smil file. The smil file only needs to be created once and only needs updating if the source streams on the origin change settings.

Step 7 is not needed as the edge streams will be started dynamically on request.

Step 8. When you start the origin and start transcoding, the http packetizers will run and the streams will be packetized. When a stream is started on the edge, a mediaCaster will be started to connect to the same stream on the origin. If the edge stream is a http stream, it will connect to the origin and retrieve the packetized chunks.

If the stream request is an http smil request then each stream in the smil will be connected and locked on so that the packetized chunks are available when they are requested without having to start the mediacaster at that time.

For similar requests with RTMP streams, the player must make a request to FCSubscribe for each stream in the smil. This will lock them on. It makes a similar request to FCUnSubscribe when it has finished. JW Player will do this automatically by setting rtmp.subscribe in the player configuration.

This method of Origin /Edge configuration is outlined in How to configure a live stream repeater.https://www.wowza.com/docs/how-to-configure-a-live-stream-repeater

Roger.

Hi Andy,

It looks like you may have gotten a bit lost here. I think it would be best to step back a bit and start again from the beginning.

Get single stream origin / edge streaming working first.

  • On the origin, edit the Application.xml and set the stream type to liverepeater-origin and set the LiveStreamPacketizers to the ones that you want to packetize.

    		<Streams>
    			<StreamType>liverepeater-origin</StreamType>
    			. . .
    			<LiveStreamPacketizers>cupertinostreamingpacketizer, smoothstreamingpacketizer, sanjosestreamingpacketizer</LiveStreamPacketizers>
    			. . .
    		</Streams>
    
    
  • Save Application.xml and Start Wowza on the origin and start publishing your stream.

  • On the edge, edit the Application.xml and set the stream type to liverepeater-edge and set the LiveStreamPacketizers to the ones that you want to repeat from the origin.

    		<Streams>
    			<StreamType>liverepeater-edge</StreamType>
    			. . .
    			<LiveStreamPacketizers>cupertinostreamingrepeater, smoothstreamingrepeater, sanjosestreamingrepeater</LiveStreamPacketizers>
    			. . .
    		</Streams>
    
    
  • On the edge, you need to tell it where the origin is. You can do this one of 4 ways. Which one you chose depends on your workflow. If servers are pre Wowza 3.5.0 then use rtmp:// where I have wowz:// below.

  • Use the Repeater / OriginURL setting in the Application.xml. This is the easiest if you just have a single origin or a pair of origins in a primary / backup configuration.

    Single Origin:

    		<Repeater>
    			<OriginURL>wowz://<origin-ip:1935/liveorigin/</OriginURL>
    			<QueryString><![CDATA[]]></QueryString>
    		</Repeater> 
    
    

    Primary / Backup Origins:

    		<Repeater>
    			<OriginURL>wowz://<primary-origin-ip:1935/liveorigin/|wowz://<backup-origin-ip:1935/liveorigin/</OriginURL>
    			<QueryString><![CDATA[]]></QueryString>
    		</Repeater> 
    
    

    The stream name you use on the player is the same name that is published to the origin server. eg. myStream

  • Use Stream Files in your content folder. Each origin stream has a Stream File on the edge which must be created before the edge can connect to the origin stream. The Stream File contains the full url to the origin stream. You can have primary / backup as above and each stream file can point to different origins.

    If the origin stream is called myStream then create a stream file called myStream.stream

    Single Origin:

    wowz://<origin-ip:1935/liveorigin/myStream
    

    Primary / Backup Origins:

    wowz://<primary-origin-ip:1935/liveorigin/myStream|wowz://<backup-origin-ip:1935/liveorigin/myStream
    

    The stream name you use in the player is the name of the Stream File. EG. myStream.stream

  • Use the StreamNameAlias AddOn. The StreamNameAlias AddOn replaces the Stream Files and provides more flexability for mapping stream names to origin urls. With a single rule in the aliasmap.stream.txt file, you can map all edge streams to your origin(s).

    The map file have a [pattern]=[alias] format. The [pattern] is the name requested and the [alias] is what it resolves to. You can use wildcards, *, in the [pattern] side and variables in the [alias] side to do some fairly powerful mapping.

    Single Origin:

    *=wowz://<origin-ip:1935/liveorigin/${Stream.Name}
    

    If the player requests myStream then it will resolve to wowz://<origin-ip:1935/liveorigin/myStream.

    Primary / Backup Origins:

    *=wowz://<primary-origin-ip:1935/liveorigin/${Stream.Name}|wowz://<backup-origin-ip:1935/liveorigin/${Stream.Name}
    

    If the player requests myStream then it will resolve to wowz://<primary-origin-ip:1935/liveorigin/myStream|wowz://<backup-origin-ip:1935/liveorigin/myStream.

  • Use the IMediaStreamNameAliasProvider api. The IMediaStreamNameAliasProvider api can be used to do your own custom mapping of stream names to urls. It is the api that each of the above methods is built on. Using the api, you can dynamically set the stream urls on a per-connection basis.

  • Save your files and start the edge server. Confirm that you can connect to the edge server and can play each of the origin streams separately in the players that you want to support.

  • Configure ABR Streaming. To do this, the edge server must have a smil file in the content folder that describes each of the renditions in the ABR Stream group. You can create these smil files manually or if using the transcoder on the origin, use the HTTPProvider method to retrieve the smil from the origin and save it on the edge server in the content folder.

    The video names in the smil file must be the names that the player would use to connect to each of the separate streams. eg. myStream_xxx if using Repeater / OriginUrl or one of the Alias methods and myStream_xxx.stream if using Stream Flies.

    myStream_low and myStream_hi are being published to the origin server as bitrate aligned streams.

    Repeater / OriginUrl or Alias:

    <smil>
    	<head>
    	</head>
    	<body>
    		<switch>
    			<video src="mp4:myStream_low" system-bitrate="250000" width="284" height="160" />
    			<video src="mp4:myStream_hi" system-bitrate="450000" width="640" height="360" />
    		</switch>
    	</body>
    </smil>
    
    

    Stream Files:

    <smil>
    	<head>
    	</head>
    	<body>
    		<switch>
    			<video src="mp4:myStream_low.stream" system-bitrate="250000" width="284" height="160" />
    			<video src="mp4:myStream_hi.stream" system-bitrate="450000" width="640" height="360" />
    		</switch>
    	</body>
    </smil>
    
    

    In the players, you use the name of the smil file with a smil: prefix. eg. smil:myStream.smil. When a HTTP player requests an ABR stream on the edge, the edge server will lock on each of the renditions from the origin. If the request is from an RTMP player, the player must also call FCSubscribe for each rendition so that they are locked on. JW Player does this with the rtmp.subscribe setting.

    To configure ABR streaming with JW Player, the player requires a smil file with a slightly different format. This can either reside on the web server local to the player or can be retrieved from the edge server. If retrieving from the edge server. it will use the smil file that is already on the edge and return the correct format smil for JW Player. The edge server must already have the original smil file.

    To request the smil file from the edge server, use the jwplayer.smil url in your player.

    http://<edge-ip>:1935/liveedge/smil:myStream.smil/jwplayer.smil
    
    

    This will return the following for the first example above.

    <smil>
    	<head>
    		<meta base="rtmp://<edge-ip>:1935/liveedge/_definst_" />
    	</head>
    	<body>
    		<switch>
    			<video src="mp4:myStream_low" system-bitrate="250000" width="284" height="160" />
    			<video src="mp4:myStream_hi" system-bitrate="450000" width="640" height="360" />
    		</switch>
    	</body>
    </smil>
    
    

    I did mention before that you can request the smil file for JW Player directly from the origin and pass it the edge ip address. This will only work if both the edge and origin have the same application and streams names. In any other case, you must use a smil file on the edge.

    Roger.

Hi Andy,

You can make the smil request directly to the origin and pass it the edge address but with the default http provider, you need to have the same application name on your origin as you do on the edge.

You can use a liverepeater: prefix in front of the origin url to tell the edge that it must start up a liverepeater stream. This is not generally used, mainly because some players cannot handle special characters needed for the url and secondly because it reveals your origin url to anyone that wants to look at your web page source code, allowing them to bypass your edges completely. This is the reason why we have stream files and aliasing options.

I do not know enough about how jw player handles stream names internally to know how it would handle a complex url.

I sort of have an idea what you are trying to achieve but I think that you will encounter more problems than you solve.

The player needs to know which origin the stream is on. When the player page loads up, this can be found out relatively easily but the information is out of date as soon as the page is loaded. The only way the player can get any updates if the origin changes between when the page is loaded and play is pressed is to refresh the page. You could have some automated process that is constantly making calls to a back end to get updates but then this would be from every player.

By having the player connect to the pool of edges, possibly through a load balancer, they do not need to know which origin has the stream, they just need to know the address of one of the edges and the stream name. In your back end, you could have the origins update the edges when they have the stream published or you could have the edges locate the streams when the players connect. Either way would put a lot less load on the backend system.

Using static smil files on the edges, one per ABR stream, you could use the alias api to do what you want. resolvePlayAlias is called first and in this call, you could locate the origin streams and save the details. resolveStreamAlias is called once the connection to the origin is to be made and you would already have the information to hand.

Roger.

Richard

Thank you for the 2 suggestions. Sorry it’s still unclear enough for me to realize that, in my current origin/edge usage, player would bring origin server location on stream name rather than set OriginURL or make edge side .stream to include origin server location:

Flash Player

Server: rtmp://[wowza-edge-address]:1935/liveedge

Stream: rtmp://[wowza-origin-address]:1935/liveorigin/myStream

base on this usage (i.e. origin server location keeps in client side rather than edge server), could you prompt more on :

  1. how to configure the jw player client-side xml to thru edge/origin in this 2 solutions (smil/ IMediaListProvider API)?
<script type="text/javascript">
jwplayer("player").setup({
    playlist: [{
        sources: [
            { file: "http://[wowza-edge-address]:1935/liveedge/[COLOR="#FF0000"]???[/COLOR]", },
        ],
    }],
    sources: [{
            file: "http://[wowza-edge-address]:1935/liveedge/[COLOR="#FF0000"]???[/COLOR]"
        }]
});
</script>

  1. What is the best timing (or notification api) for edge to generate smil file? smil is supposed to be needed and created only when player requests for live out, rather than publisher starts to live in

  2. How to fill the video src in edge smil file’s content :

<smil>
	<head>
	</head>
	<body>
		<switch>
			<video src="[COLOR="#FF0000"]???[/COLOR]" system-bitrate="250000"/>
			<video src="[COLOR="#FF0000"]???[/COLOR]" system-bitrate="450000"/>
		</switch>
	</body>
</smil>

Thank your help

Please help to prompt it

Thanks

Richard, thank your reply. Your suggestion needs to pre-define the stream name and origin address on each edge server’s .stream files and StartUpStreams.xml, maybe it’s a hard mission for dynamic upstream usage .

In my case each upstream would be assigned to one of origin servers base on server loading, the amount of upstream is always varying also the timing of upstream is uncontrollable. That’s why I hope edge server do not pre-defined the stream name and origin address.

I know I could achieve it by keeping the stream name and origin address on client side before importing RTMP dynamic streaming to Edge/Origin:

Flash Player

Server: rtmp://[wowza-edge-address]:1935/liveedge

Stream: rtmp://[wowza-origin-address]:1935/liveorigin/myStream

Base on ABR thru Edge/Origin usage, is there any solution could keep stream name and origin address on client side rather than edge server as my previous case?

If it’s not, is it possible to dynamic generate edge server .stream files and StartUpStreams.xml only when player request it?

Thank you Roger, it’s a really detail explanation, very clear for newbie like me.

Here I have to please more about the step5 and step6 for my real usage. Both the steps are hard coding the content in toturial but I would have problem there, because the amount of upstream is varying once our productions are turn on/off by different customers. Therefore it almost impossible to hard code all the smil and .stream in each edge. I expect some dynamic ways to generate them once the edge streams start their request, could you prompt that?

In a total different thinking, would it be workable to :

  1. JW player uses the following address to get playlist
http://<transcoder-ip>:1935/live/amlst:mySteam_all/jwplayer.smil?protocol=rtmp&domain=<edge-ip> 
  1. origin server implements the IMediaListProvider API.
  • check if the url has parameter ‘domain’ to describe edge address,

  • if it is, try to generate the return as the following smil

    <smil>
       <head>
          <meta base="rtmp://[edge-addr]:1935/liveedge/_definst_"/>
       </head>
       <body>
          <switch>
             <video src="rtmp://[wowza-origin-address]:1935/liveorigin/myStream_360p" system-bitrate="850000" width="640" height="360"/>
             <video src="rtmp://[wowza-origin-address]:1935/liveorigin/myStream_160p" system-bitrate="200000" width="284" height="160"/>
          </switch>
       </body>
    </smil>
    
    
    1. then edge server does not need to generate the smil and .stream file

Thanks Roger.

About point 6, if I request the smil file for JW Player directly from the origin and pass it the edge ip address, do I still need to generate smil file in the content folder of edge? What would be the best moment(notificaiton api) to do that?

About point 4, I remember there is another way to tell edge where the origin is by client’s request :

Flash Player

Server: rtmp://[wowza-edge-address]:1935/liveedge

Stream: rtmp://[wowza-origin-address]:1935/liveorigin/myStream

if we design a special http provider on origin so that when I request the smil file for JW Player directly from the origin it can return a special smil with video src that include the origin server path,

Thanks Roger, Your explanation help me to understand more of WMS and streaming behavior. Now I could almost approach my target with your suggestion ways. I really appreciate your great help