AAC Shoutcast Restream and Adaptive Multiple bitrates

Hi Guys

I’m planning on setting up a radio station with multiple bitrates. The stream sources would be 32k AAC and 64k AAC and they will be sent to two shoutcast servers.

I want to know if Wowza allows multi-bitrate/dynamic streaming for audio only and is there a process to set it up?

Thanks for any help!

Hi

So your set-up would be as follows :

Encoder sending Audio(64k) --> Shoutcast <-- Wowza --> Clients

Encoder sending Audio(32k) --> Shoutcast <-- Wowza --> Clients

(Only one Wowza server)

You can find the setup for the application here,

https://www.wowza.com/docs/how-to-re-stream-audio-from-shoutcast-icecast

There’s an example of how to set-up a .smil file here,

https://www.wowza.com/docs/how-to-set-up-live-streaming-using-an-rtmp-based-encoder

Jason

I have used netlimter

Richard

There is not a way to to ABR switching with SHOUTcast streams as far as I know

Richard

Sorry, there isn’t as far as I know. ABR streaming in Wowza depends on video key frame alignment, and there none in audio only stream.

Richard

Hi Cadymaritz.

Did you find a any way to stream HLS audio only for IOS (keyframe and TC not included in shoutcast streams)

shoutcast - wowza - smil file - to IOS.

thank you.

Hi Richard, thank you for answer.

How can i do ABR for audio only live stream ?

thank you.

Thank you Jason. I will attempt it forthwith.

You arent perhaps aware of an app that throttles bandwidth so I can validate that the bandwidth switches?

Hi Guys

I have been trying this and have had moderate success using flowplayer and RTMP. I haven’t been able to verify the bandwidth switching but that should be fairly quick to do. What I am struggling with however is getting this stream to come through as http traffic so as to bypass most firewalls that would block anything RTMP.

I have used the OSMF generator here: http://www.osmf.org/dev/2.0gm/setup.html

I have started the streams using stream manager and have had the stream work and bandwidth switch! The stream does stop/buffer endlessly every now and again, which leads me to believe that I need to set a timeout setting somewhere so the stream will reconnect? Please advise?

The problem now is flowplayer and http. I am trying to hack together code from what I can see on the flowplayer site and what I used for RTMP but I am struggling. The player fails to load but everything does still seem in order. this is so weird…

Anyone had any luck with Flowplayer, SMIL, shoutcast (aac) and http streaming?

Cady

Doh! Nevermind, I had the wrong application specified.

So, for future reference to anyone who needs to setup something like this, use the following:

OSMF Audio Only Player with dynamic stream switching and delivered over http:

	<object width="400" height="125"> <param name="movie" value="StrobeMediaPlayback.swf"></param>
	<param name="flashvars" value="src=http://<wowza server IP>/<application name>/smil:<smil file>.smil/manifest.f4m&poster=images/image.jpg&posterScaleMode=stretch&autoPlay=true&playButtonOverlay=false&controlBarAutoHide=false&verbose=true"></param>
	<param name="allowFullScreen" value="true"></param>
	<param name="allowscriptaccess" value="always"></param>
	<param name="wmode" value="transparent"></param>
	<embed src="StrobeMediaPlayback.swf" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true"  wmode="transparent"  width="400" height="125" flashvars="src=http://<wowza server IP>/<application name>/smil:<smil file>.smil/manifest.f4m&poster=images/image.jpg&posterScaleMode=stretch&autoPlay=true&playButtonOverlay=false&enableStageVideo=false&controlBarAutoHide=false&backgroundColor=FF0000&verbose=true&urlIncludesFMSApplicationInstance=true"></embed>
	</object>

Flowplayer Audio Only Player with dynamic stream switching and delivered over http:

 
 
 
 
<!doctype html>
<html>
<head>
    
    <title>Bandwidth detection for HTTP Streaming : Flowplayer</title>
 
    <link rel="shortcut icon" href="/media/favicon.png">
    <!-- standalone page styling. can be removed -->
    <style>
        body{
            width:400px;
            margin:50px auto;
            font-family:sans-serif;
        }
        a:active {
            outline:none;
        }
        :focus { -moz-outline-style:none; }
 
        .palert {
            padding: 12px;
            color: black;
            background-color: #ededed;
            box-shadow: none;
        }
    </style>
 
    
    
    <!-- flowplayer javascript component -->
    <script src="http://releases.flowplayer.org/js/flowplayer-3.2.11.min.js"></script>
 
    </head>
 
<body>
    <!-- set up player container named "httpstreaming-dynamic" -->
<a class="player" id="httpstreaming-dynamic" style="display:block;width:400px;height:100px;"></a>
 
<!-- this script block will install Flowplayer inside previous A tag -->
<script> 
flowplayer('httpstreaming-dynamic', 'flowplayer/flowplayer-3.2.12.swf', {
    clip: {
        // the manifest file
        url: 'smil:<smil file>.smil/manifest.f4m',
 
        // we need 2 urlResolvers
        urlResolvers: ['f4m','bwcheck'],
 
        // use the httpstreaming plugin
        provider: 'httpstreaming',
 
        // directory where the manifest and video fragments are stored
        baseUrl: 'http://<wowza server IP>/<application name>',
 
        autoPlay: true
    },
    plugins: {
        f4m: {
            url: 'flowplayer/flowplayer.f4m-3.2.9.swf'
        },
        httpstreaming: {
            url: 'flowplayer/flowplayer.httpstreaming-3.2.8.swf'
        },
        controls: {
            // the 'tube' skin
            url: 'flowplayer/flowplayer.controls-tube-3.2.12.swf'
        },
 		smil: {
			url: 'flowplayer.smil-3.2.8.swf'
		},
        bwcheck: {
            url: 'flowplayer/flowplayer.bwcheck-httpstreaming-3.2.9.swf',
            dynamic: true,
            // show the selected file in the content box
            // usually omitted in production
            onStreamSwitchBegin: function (newItem, currentItem) {
                var content = $f('httpstreaming-dynamic').getPlugin('content');
                var message = 'Will switch to: ' +
                               newItem.streamName +
                                ' from ' +
                                currentItem.streamName;
                content.setHtml(message);
            },
            onStreamSwitch: function (newItem) {
                var content = $f('httpstreaming-dynamic').getPlugin('content');
                var message = 'Switched to: ' + newItem.streamName;
                content.setHtml(message);
            }
        },
 
        // a content box to display the selected bitrate
        // usually omitted in production
        content: {
            url: 'flowplayer/flowplayer.content-3.2.8.swf',
            bottom: 30,
            left: 0,
            width: 400,
            height: 40,
            backgroundColor: 'transparent',
            backgroundGradient: 'none',
            border: 0,
            textDecoration: 'outline',
            style: {
                body: {
                    fontSize: 14,
                    fontFamily: 'Arial',
                    textAlign: 'center',
                    color: '#ffffff'
                }
            }
        }
    }
});
</script>
</body>
 
</html>

note that you will need the following for this to work for both OSMF and Flowplayer:

The shoutcast setup as follows:

Encoder sending Audio(64k) --> Shoutcast <-- Wowza --> Clients

Encoder sending Audio(32k) --> Shoutcast <-- Wowza --> Clients

(Only one Wowza server)

a standard SHOUTCAST application created from the examples folder: https://www.wowza.com/docs/how-to-re-stream-audio-from-shoutcast-icecast

a more detailed SMIL file created from the tutorial: https://www.wowza.com/docs/how-to-create-and-play-smil-files-with-streams-created-by-wowza-transcoder

because of this forum post: iOS Adaptive Bit Rate streaming using Smil file problems

for an explanation of each variable in the more detailed SMIL file, go here: https://www.wowza.com/docs/how-to-add-resolution-and-codec-metadata-to-ios-streams

it will help with specifying the right codecs depending on your stream.

the streams need to be started by either the StreamManager or startupstreams.xml and a mechanism put in place to ensure the stream resets if it becomes unstable etc

You will need the necessary flowplayer plugins:

flowplayer-3.2.11.min.js

flowplayer-3.2.12.swf

flowplayer.bwcheck-3.2.10.swf

flowplayer.bwcheck-httpstreaming-3.2.9.swf

flowplayer.content-3.2.8.swf

flowplayer.controls-3.2.12.swf

flowplayer.controls-tube-3.2.12.swf

flowplayer.f4m-3.2.9.swf

flowplayer.httpstreaming-3.2.8.swf

flowplayer.ipad-3.2.10.js

flowplayer.rtmp-3.2.10.swf

flowplayer.smil

flowplayer.smil-3.2.8.swf

You will need to have either a reference to the OSMF swf or capture/download the SWF by some means.

You can generate an OSMF player here: http://www.osmf.org/dev/2.0gm/setup.html

Both these solutions should work for audio and video however. You will need to change the application to live and forget about shoutcast however.

And that should be that I would think.

Thank you to Jason and Richard for their input here. Thanks to all the other forum members I can think of that all had some input.

Thanks also to Flowplayer for all their snippets and demos.

I do not claim to have invented this merely put alot of brilliant minds’ work together.

Cady

I have managed to update the Flowplayer part of this to support iDevice failover. Here is the code:

<!doctype html>
<html>
<head>
    
    <title>Flowplayer HTTP Streaming with iDevice fallback</title>
    <link rel="shortcut icon" href="images/favicon.png">
    <!-- standalone page styling. can be removed -->
    <style>
        body{
            width:400px;
            margin:50px auto;
            font-family:sans-serif;
        }
        a:active {
            outline:none;
        }
        :focus { -moz-outline-style:none; }
 
        .palert {
            padding: 12px;
            color: black;
            background-color: #ededed;
            box-shadow: none;
        }
    </style>
 
    
    
    <!-- flowplayer javascript component -->
    <script src="flowplayer/flowplayer-3.2.11.min.js"></script>
 
    </head>
 
<body>
<script src="flowplayer/flowplayer.ipad-3.2.10.min.js" type="text/javascript" charset="utf-8"></script>
 
<style> 
#player {
    text-align:center;
    display:block;
    height:60px;
    margin:0 auto;
    background-color:#123;
}
 
#player img {
    margin-top:100px;
}
 
#player h3 {
    margin:0;
    color:#fff;
}
 
</style>
<!-- import Apple look and feel -->
<!-- black box and a nested player -->
<a id="player">
</a>
 
<!-- HTML-based controlbar -->
 
<!-- this script block will install Flowplayer inside previous A tag -->
<script> 
window.onload = function() {
$f("player", "flowplayer/flowplayer-3.2.12.swf", {
    
    clip: {
        // the manifest file
        url: 'smil:abs-live.smil/manifest.f4m',
 
        // we need 2 urlResolvers
        urlResolvers: ['f4m','bwcheck'],
 
        // use the httpstreaming plugin
        provider: 'httpstreaming',
 
        // directory where the manifest and video fragments are stored
        baseUrl: 'http://216.246.37.52/abs-shout',
		ipadUrl: 'http://216.246.37.52/abs-shout/smil:abs-live.smil/playlist.m3u8',
 
        autoPlay: true
    },
    plugins: {
        f4m: {
            url: 'flowplayer/flowplayer.f4m-3.2.9.swf'
        },
        httpstreaming: {
            url: 'flowplayer/flowplayer.httpstreaming-3.2.8.swf'
        },
        controls: {
            // the 'tube' skin
            url: 'flowplayer/flowplayer.controls-tube-3.2.12.swf'
        },
 		smil: {
			url: 'flowplayer.smil-3.2.8.swf'
		},        
		bwcheck: {
            url: 'flowplayer/flowplayer.bwcheck-httpstreaming-3.2.9.swf',
            dynamic: true,
            // show the selected file in the content box
            // usually omitted in production
            onStreamSwitchBegin: function (newItem, currentItem) {
                var content = $f('player').getPlugin('content');
                var message = 'Will switch to: ' +
                               newItem.streamName +
                                ' from ' +
                                currentItem.streamName;
                content.setHtml(message);
            },
            onStreamSwitch: function (newItem) {
                var content = $f('player').getPlugin('content');
                var message = 'Switched to: ' + newItem.streamName;
                content.setHtml(message);
            }
        },
        // a content box to display the selected bitrate
        // usually omitted in production
		content: {
            url: 'flowplayer/flowplayer.content-3.2.8.swf',
            bottom: 30,
            left: 0,
            width: 400,
            height: 40,
            backgroundColor: 'transparent',
            backgroundGradient: 'none',
            border: 0,
            textDecoration: 'outline',
            style: {
                body: {
                    fontSize: 14,
                    fontFamily: 'Arial',
                    textAlign: 'center',
                    color: '#ffffff'
                }
            }
        }
    }
}).ipad({ simulateiDevice: false, controls: true });
};
</script>
</body>
 
</html>

Hi Guys

I used this as a research project but we have now come to a practical application and I’ve come into a bit of an issue. Using the smil setup on iOS devices and after a while in flowplayer, when switching streams bitrates, there is an audible stop in the stream. This is obviously not great for stream delivery as the experience is very abrupt and interrupted. Do you have any suggestions as to why this might be the case?

Server setup I tried is:

Shoutcast type Application.xml with standard configs as per examples folder (Shoutcast)

live type Application.xml with standard configs as per examples folder (LiveVideoStreaming)

Using stream manager, receive the stream as a shoutcast type stream specifying smil:.smil

if you want to take a listen to the stream let me know so I can PM it to you.

Tx

Cady

Hi there,

What are the audio settings of the stream? Also can you confirm that each rendition of the streams are key frame aligned?

IOS is very picky about audio settings, and key frame alignment is crucial for multi-bitrate switching to work.

Salvadore

Hi Salvadore

Thanks for the response. I didn’t think keyframes were of importance because it is audio only (AAC+v2 32k and 64k) being restreamed via shoutcast. But now that you mention it it makes sense. I use Oddcast to encode multiple bitrates and I don’t think it is keyframe aligned. I have not been able to find any information regarding that.

This is most probably where the issue stems from. Do you know of an audio encoder that is keyframe aligned?

Hi Cady,

I subconsciously thought you had a live stream with video as well when I saw your “live type Application.xml with standard configs as per examples folder (LiveVideoStreaming)”, that is why I mentioned key frame alignment. But no, there is no need for key frame alignment with audio only.

I am not sure what your issue is, but I am curious so I will look into it further, in the mean time are you seeing anything in the logs when it switches bitrates?

I will post back here as soon as I find out something useful.

Salvadore

Hi Salvadore

I just realised I was using Shoutcast v1 and two different shoutcast servers would obviously have buffers that aren’t quite filled up the same way not so? I saw shoutcast v2 allows two streams to be sent to one server, I also noted that it allows you to transcode more than one bitrate. This might be ideal for what I want to do. I will also feed back with my findings.

Awaiting your response.

Cady

Hi

Thanks for your input, this will help others who may want to use this kind of set-up the detail is much appreciated.

Jason

Hi there,

What are the audio settings of the stream? Also can you confirm that each rendition of the streams are key frame aligned?

IOS is very picky about audio settings, and key frame alignment is crucial for multi-bitrate switching to work.

Salvadore

Hi Cady,

I subconsciously thought you had a live stream with video as well when I saw your “live type Application.xml with standard configs as per examples folder (LiveVideoStreaming)”, that is why I mentioned key frame alignment. But no, there is no need for key frame alignment with audio only.

I am not sure what your issue is, but I am curious so I will look into it further, in the mean time are you seeing anything in the logs when it switches bitrates?

I will post back here as soon as I find out something useful.

Salvadore