It’s the code snippet that just won’t go away. I’ve updated the code for some additional functionality. This version takes server, port, and stream parameters via the URL, parses them in javascript, and then queries a streamcheck HTTPProvider on the server to see if a stream by that name is currently published. If it is, it will load the player, otherwise load a message, and check periodically to see if the stream is published, and load the player if the state changes to true, and unload it if it changes to false, returning to the message. The player is designed to scale to fit whatever window it’s in, so make an IFRAME of whatever size you want the player, and you’re off and running
<IFRAME SRC="player.html?streamer=wowza.nhicdn.net&port=1935&app=live&stream=livestream" WIDTH="640" HEIGHT="360" SCROLLING="NO" />
Without further ado, here’s the code:
<body style="margin: 0px; background: black; color: white; font-family: sans-serif;"> <div id="videoframe" style="text-align: center;font-size: 14;">The video stream is currently offline. Playback will resume as soon as a stream is available.</div> <script type="text/javascript" src="/assets/jw5/jwplayer.js"></script> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script> <script type='text/javascript' src='https://www.google.com/jsapi'></script> <SCRIPT type="text/javascript"> // Browser-aware video player for JW Player and Wowza plwd=self.innerWidth; plht=self.innerHeight; // var debugwindow=document.getElementById("debug") // debugwindow.innerHTML='<P>Dimensions: '+plwd+'x'+plht+'</P>'; var streamer=getUrlVars()["streamer"]; var app=getUrlVars()["app"]; var port=getUrlVars()["port"]; var stream=getUrlVars()["stream"]; var server=streamer+':'+port+'/'+app; var agent=navigator.userAgent.toLowerCase(); var is_iphone = (agent.indexOf('iphone')!=-1); var is_ipad = (agent.indexOf('ipad')!=-1); var is_ipod = (agent.indexOf('ipod')!=-1); var is_playstation = (agent.indexOf('playstation')!=-1); var is_safari = (agent.indexOf('safari')!=-1); var is_blackberry = (agent.indexOf('blackberry')!=-1); var is_android = (agent.indexOf('android')!=-1); var streamstatus = false; var prevstatus = false; var curstatus = false; streamcheck(); setInterval(function(){streamcheck()},10000); function streamcheck() { $.ajax({ type: "GET", url: "http://"+streamer+":8086/streamcheck?stream="+stream, dataType: "json", success: function(result){ curstatus = Boolean(result); //if (result === "true") { curstatus = true;} //if (result === "false") { curstatus = false;} if (curstatus == prevstatus) { } else { if (curstatus) { if (is_iphone || is_ipad || is_ipod) { iOSPlayer("videoframe",plwd,plht,server,stream);} else if (is_blackberry) { rtspPlayer("videoframe",plwd,plht,server,stream);} else { flashPlayer("videoframe",plwd,plht,server,stream); } console.log("Changed from false to true"); } else { var vframe=document.getElementById("videoframe") if (is_iphone || is_ipad || is_ipod || is_blackberry) { } else { jwplayer("videoframe").remove(); } vframe.innerHTML = 'The video stream is currently offline. Playback will resume as soon as a stream is available.'; console.log("Changed from true to false"); } } prevstatus = curstatus; } }); } function getUrlVars() { var vars = {}; var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) { vars[key] = value; }); return vars; } function iOSPlayer(container,width,height,server,stream) { var player=document.getElementById(container) player.innerHTML='<VIDEO controls '+ 'HEIGHT="'+height+'" '+ 'WIDTH="'+width+'" '+ 'title="Live Stream">'+ '<SOURCE SRC="http://'+server+'/'+stream+'/playlist.m3u8"> '+ '</video>'; } function rtspPlayer(container,width,height,server,stream) { var player=document.getElementById(container) player.innerHTML='<A HREF="rtsp://'+server+'/'+stream+'">'+ '<IMG SRC="poster-play.png" '+ 'ALT="Start Mobile Video" '+ 'BORDER="0" '+ 'HEIGHT="'+height+'" '+ 'WIDTH="'+width+'">'+ '</A>'; } function flashPlayer(container,wide,high,server,stream) { jwplayer(container).setup({ height: high, width: wide, streamer: 'rtmp://'+server, file: stream, autostart: true, stretching: 'uniform' }); } </SCRIPT> </BODY>
The code for the streamcheck module is as follows:
package net.nerdherd.wms.http; import java.io.*; import java.util.Iterator; import java.util.List; import java.util.Map; import com.wowza.wms.application.IApplicationInstance; import com.wowza.wms.http.*; import com.wowza.wms.logging.*; import com.wowza.wms.vhost.*; public class StreamCheck extends HTTProvider2Base { public void onHTTPRequest(IVHost vhost, IHTTPRequest req, IHTTPResponse resp) { StringBuffer report = new StringBuffer(); StringBuffer streamlist = new StringBuffer(); if (!doHTTPAuthentication(vhost, req, resp)) return; Map<String, List<String>> params = req.getParameterMap(); String stream = ""; boolean status = false; boolean listing = false; if (req.getMethod().equalsIgnoreCase("post")) { req.parseBodyForParams(true); } if (params.containsKey("stream")) stream = params.get("stream").get(0); try { if (vhost != null) { List<String> appNames = vhost.getApplicationNames(); Iterator<String> appNameIterator = appNames.iterator(); while (appNameIterator.hasNext()) { try { String Name = appNameIterator.next(); IApplicationInstance NowApp = vhost.getApplication(Name).getAppInstance("_definst_"); List<String> PublishedNames = NowApp.getPublishStreamNames(); Iterator<String> ThisPublished = PublishedNames.iterator(); if ( PublishedNames.size()>0 ) { while ( ThisPublished.hasNext() ) { try { String NowPublished = ThisPublished.next(); if (NowPublished.equals(stream)){ status = true; } } catch (Exception e) {} } } } catch (Exception e) {report.append(e.toString()); } } } } catch (Exception e) { WMSLoggerFactory.getLogger(HTTPServerVersion.class).error("StreamCheck: " + e.toString()); e.printStackTrace(); } if (!listing) { if (status){ report.append("true"); } else { report.append("false"); } } try { resp.setHeader("Content-Type", "text/plain"); resp.setHeader("Access-Control-Allow-Origin","*"); OutputStream out = resp.getOutputStream(); byte[] outBytes = report.toString().getBytes(); out.write(outBytes); } catch (Exception e) { WMSLoggerFactory.getLogger(null).error( "MediaCasterHTTP: " + e.toString()); } } }
Could I substitute the .innerHTML in the stream check function with say an image rotator, or a countdown, or some other html elements besides just text? I’ve been trying to hack together a way to check the status of the stream and automate what shows up on the page, but I’m not that good at js.
You bet. It could be anything you want.
Hello Ian, Is hard to me to compile streamcheck, do you have some link to download it? 🙂
I’ll try and put together a jar file for download soon.
Yes a download of the compiled JAR would be most helpful. For some reason the Wowza IDE doesn’t work well on my computer.
Hello Ian, I compiled StreamCheck but is not working. Where I have to define the HTTT Provider? as a Module in my Application or in Vhost.xml?
In the page http://server:8086/srteamcheck you see the name of “stream” online?
Syntax is http://server:8086/streamcheck?stream=streamname and it will return either “true” or “false”
mmm ok… it doesn’t work.. i have the “Wowza Media Server 3…. 3.5.0 build2989”
All HTTPProviders are defined in VHost.xml.
How to make a wowza module ?
Does this script runs all the time or when requested only ?
What’s the impact of this script on resources, CPU and RAM ?
How does it work ?
Thanks in advance for your great script
hello lan, now i have streamcheck compiled, but I have this error:
ERROR server comment – loadHTTPProvider: error parsing HTTPProvider properties: java.lang.ClassNotFoundException: net.nerdherd.wms.http
java.lang.ClassNotFoundException: net.nerdherd.wms.http
have you any suggestions?
Pingback: streamNerd » Browser-Aware Player Code: Episode V, IE Strikes Back
Hello Ian, thanks for sharing the nice feature , i have it working fin on ios devices but on my pc it says “error loading player: no playable sources found” i use the hosted version of jwplayer premium.
Also i wonder if there´s a way to hide the player if status is “false” using something like jwplayer() .remove()
Our player is responsive and with html5 fallback we insert it using
//
And for those of you looking through this thread , remeber when adding httpprovider in VHost.xml to put it above the HTTPserverversion *
so it could look like this
net.nerdherd.wms.http.StreamCheck
streamcheck*
none
com.wowza.wms.http.HTTPServerVersion
*
none