Page 1 of 2 12 LastLast
Results 1 to 10 of 17

Thread: maximum bitrate control

  1. #1
    Join Date
    May 2013
    Posts
    18

    Question maximum bitrate control

    Hello,

    we have a vod setup (wowza3 + jwplayer) with some amount of mobile customers. since mobile customers are very sensitive to the data traffic volumes, we would like to introduce an option for them to be able to limit their maximum bitrate. a typical smil file would contain links to 7-8 different files encoded with bitrates up to 4-5 Mbits/s. However typical mobile customer might be fine with 1 Mbit/s bitrate for some type of the content.

    One of the ways to solve this problem would be to create different smil-files each containing increased number of links to the vod files. So,
    a1.smil will contain link to the 1st lowest bitrate file
    a2.smil will contain link to the 1st lowest bitrate file and the second lowest bitrate file
    etc

    However this approach creates other difficulties with other setup. Due to some technical reasons we cannot use wowza-generated jwplayer rss files, but generate them on our own. Our content is usually having 3-4 different audio-streams, so we generally have b0.rss pointing to the smil file with audioindex=0, b1.rss point to the smil file with audioindex=1 etc

    as soon as we combine those 2 approaches we will end up with huge amount of rss and smil files pointing to different bitrates and audioindexes, which is hard to manage in the end.

    So, my question is - how is it possible to control maximum bitrate which can be played back with specific url arguments to the vod url? i.e. audioindex argument provides a way to select correct audio stream, is there something like maxbitrate argument which will limit playback to the specified bitrate or is there any other solution which can be used in our setup which will not generate few dozens of smil and rss files?

  2. #2

    Default

    Hi,

    There is no built in method but you could probably do this using a custom module.

    One approach would be to create a custom MediaList implementation that would return the smil based on what the player requests.

    Please see the following article for information.

    How to use Java API calls to resolve SMIL file requests (AMLST)

    Roger.

  3. #3
    Join Date
    May 2013
    Posts
    18

    Default

    Thank you Roger,

    this is what we were looking for.
    Just another question - is it possible to customize the code responsible for jwplayer rss generation by means of creating custom module?

  4. #4

    Default

    Hi,

    Wowza is able to automatically generate the JW Player rss file using the information generated by the MediaList API.

    You would use the following url format in your player.

    http://<wowza-ip>:1935/<app-name>/amlst:<stream-name>/jwplayer.rss
    When this is called, it will call the resolveMediaList method and your code would return the required renditions.

    There is also a jwplayer.smil url for JW Player 6 and a medialist.smil url that returns a regular smil file.

    Roger.

  5. #5
    Join Date
    May 2013
    Posts
    18

    Thumbs up

    Quote Originally Posted by roger_l View Post
    Hi,

    There is no built in method but you could probably do this using a custom module.

    One approach would be to create a custom MediaList implementation that would return the smil based on what the player requests.

    Please see the following article for information.

    How to use Java API calls to resolve SMIL file requests (AMLST)

    Roger.
    Roger, one more question here.

    Basically to achieve dynamic smil generation for our case, we still need to read reference smil file, get http request params and according to this generate chunklist reply with segment available only for this particular customer.
    this article provides good example of handling http request params: http://www.wowza.com/forums/content....tify-interface

    however I couldn't find any example on smil file reading and manipulation. can you help with any example or a link?

  6. #6

    Default

    Hi,

    Take a look at the following article.

    Source code for HTTPProviderMediaList in Wowza Media Server

    It is the source code for the MediaList HTTP Provider that I referred to earlier. It shows how to load an existing smil file into a MediaList structure that you can then modify and return the modified media list.

    MediaList mediaList = MediaListUtils.parseMediaList(appInstance, streamName, streamExt, null);
    This line loads an existing smil file referenced by streamName and streamExt. You could use this method in the AMLST resolveMediaList method to load an existing smil instead of creating a new one from scratch.

    The resolveMediaList method gets called for every request so you can customise the response to each player by using query variables.

    Roger.

  7. #7
    Join Date
    May 2013
    Posts
    18

    Default

    Quote Originally Posted by roger_l View Post
    Hi,

    Take a look at the following article.

    Source code for HTTPProviderMediaList in Wowza Media Server

    It is the source code for the MediaList HTTP Provider that I referred to earlier. It shows how to load an existing smil file into a MediaList structure that you can then modify and return the modified media list.

    MediaList mediaList = MediaListUtils.parseMediaList(appInstance, streamName, streamExt, null);
    This line loads an existing smil file referenced by streamName and streamExt. You could use this method in the AMLST resolveMediaList method to load an existing smil instead of creating a new one from scratch.

    The resolveMediaList method gets called for every request so you can customise the response to each player by using query variables.

    Roger.
    Thanks a lot, Roger!
    This example answers all my questions.

  8. #8
    Join Date
    May 2013
    Posts
    18

    Default

    I tried to incorporate the code from HTTPProviderMediaList to the ResolveMediaList

    I unded up with the following package:

    package com.wowza.wms.plugin.test.module;
    
    import com.wowza.wms.httpstreamer.model.IHTTPStreamerSession;
    import com.wowza.wms.medialist.*;
    import com.wowza.wms.module.*;
    import com.wowza.wms.stream.*;
    import com.wowza.wms.util.MediaListUtils;
    import com.wowza.wms.vhost.IVHost;
    import com.wowza.wms.application.*;
    
    public class ModuleAMLSTTest extends ModuleBase 
    {
    	class MyMediaListProvider implements IMediaListProvider
    	{
    		public MediaList resolveMediaList(IMediaListReader mediaListReader, IMediaStream stream, String streamName)
    		{
    			/*
    			MediaList mediaList = new MediaList();
    			
    			MediaListSegment segment = new MediaListSegment();
    			mediaList.addSegment(segment);
    
    			MediaListRendition rendition1 = new MediaListRendition();
    			segment.addRendition(rendition1);
    			
    			rendition1.setName("mp4:"+streamName+"_400k.mp4");
    			rendition1.setBitrateAudio(128000);
    			rendition1.setBitrateVideo(400000);
    			rendition1.setWidth(320);
    			rendition1.setHeight(240);
    			rendition1.setAudioCodecId("mp4a.40.2");
    			rendition1.setVideoCodecId("avc1.66.12");
    					
    			MediaListRendition rendition2 = new MediaListRendition();
    			segment.addRendition(rendition2);
    			
    			rendition2.setName("mp4:"+streamName+"_800k.mp4");
    			rendition2.setBitrateAudio(128000);
    			rendition2.setBitrateVideo(800000);
    			rendition2.setWidth(640);
    			rendition2.setHeight(480);
    			rendition2.setAudioCodecId("mp4a.40.2");
    			rendition2.setVideoCodecId("avc1.77.31");
    			*/
    			//MediaList mediaList = new MediaList();
    			IHTTPStreamerSession  	HTTPClient = null;
    			try { HTTPClient = stream.getHTTPStreamerSession(); } catch (Exception client) {}
    			
    			IVHost vhost = HTTPClient.getVHost();
    			
    			String comboAppStr = null;
    
    			String applicationStr = comboAppStr;
    	        String appInstanceStr = IApplicationInstance.DEFAULT_APPINSTANCE_NAME;
    	        
    	        int cindex = applicationStr.indexOf("/");
    	        if (cindex > 0)
    	        {
    	        	appInstanceStr = applicationStr.substring(cindex+1);
    	        	applicationStr = applicationStr.substring(0, cindex);
    	        }
    	        
    	        
    			IApplication applicationLoc = vhost.getApplication(applicationStr);
    			
    			IApplicationInstance appInstance = applicationLoc.getAppInstance(appInstanceStr);
    			
    			String streamExt = "smil";
    			MediaList mediaList = MediaListUtils.parseMediaList(appInstance, streamName, streamExt, null);
    
    			return mediaList;
    		}
    	}
    	
    	public void onAppStart(IApplicationInstance appInstance)
    	{
    		appInstance.setMediaListProvider(new MyMediaListProvider());
    	}
    	
    }
    it's compiled without errors, however trying to get request http://127.0.0.1:1935/vod/amlst:sample/playlist.m3u8

    gives ERROR server comment - HTTPStreamerCupertinoIndexPlaylist.indexFile[vod/_definst_/amlst:sample]: java.lang.NullPointerException

    Looks like the problem is related to incorrect mediaList initialization due to incorrect appInstance initialization.

    I tried to play around with getAppInstance() also
    IClient client;
    IApplicationInstance appInstance = client.getAppInstance();

    but cannot find correct way of getting client structure.

    plz help.
    Last edited by roger_l; 10-23-2013 at 04:01 PM.

  9. #9
    Join Date
    May 2013
    Posts
    18

    Default

    btw,

    do you have any kind of simplified workflow of wowza request processing with mapping to the core components - i.e. http request is coming to the system via classA.functionB, afterwards dispatched by classC.functionD based on XX to YY or ZZ etc etc?
    API document contains only api calls details but doesn't provide any 'big map' of system workflow.

  10. #10

    Default

    Hi,

    The reason you are getting an error is because you are passing a null appInstance to the parseMediaList method.

    There are a number of ways you can get the appInstance but in this case, because you are creating a module that is linked to a single appInstance, the easiest is to create a instance level field and reference it with this.appInstance.

    In onAppStart, add the following line.

    this.appInstance = appInstance;

    You will also have to add a field to the class and the ide will most likely prompt you to do so.

    You do not need this bit that you copied from the HTTPProvider.

    			IHTTPStreamerSession  	HTTPClient = null;
    			try { HTTPClient = stream.getHTTPStreamerSession(); } catch (Exception client) {}
    			
    			IVHost vhost = HTTPClient.getVHost();
    			
    			String comboAppStr = null;
    
    			String applicationStr = comboAppStr;
    	        String appInstanceStr = IApplicationInstance.DEFAULT_APPINSTANCE_NAME;
    	        
    	        int cindex = applicationStr.indexOf("/");
    	        if (cindex > 0)
    	        {
    	        	appInstanceStr = applicationStr.substring(cindex+1);
    	        	applicationStr = applicationStr.substring(0, cindex);
    	        }
    	        
    	        
    			IApplication applicationLoc = vhost.getApplication(applicationStr);
    			
    			IApplicationInstance appInstance = applicationLoc.getAppInstance(appInstanceStr);
    The reason the HTTP Provider does it this way is because it does not already have an appInstance reference and also, it is running at a VHost level so can be used on all appInstances.

    There currently isn't any high level documentation that provides component mapping. but the following rules generally apply.

    There is one Server.
    There can be multiple VHosts.
    Each VHost can run multiple Applications.
    Each Application can have multiple AppInstances but there generally is just one.
    Almost everything else is related to the AppInstance.
    Clients are only related to RTMP connections.
    HTTP & RTP connections have sessions, not clients.
    Streams can have one of Client or httpSession or rtpSession or none of the above if it is an internal stream.

    The best place to look is in the Server API documentation at each of the main interfaces and at the example code on the forum for different implementations.

    By all means, if you are not sure then please do ask.

    Roger.

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •