Player-Side Ad Insertion with ID3 Tags

Learn how to insert ads into live streams by configuring player-side ad insertion with ID3 tags.


In this video, we talk about player-side ad insertion with ID3 tags, which is a way to insert ads into live streams.


We cover:

How to trigger an ad to be inserted into a commercial break for a live stream
The three pieces of code you need to insert ads 
Examples of when player-side ad insertion is beneficial


Ryan: Hi guys, and welcome to today's stream talk where we're going to talk about JW Player and Wowza working together. And in today's session we're going to talk about player-side ad insertion with ID3 tags. And Eric, thanks again for joining us and I know that this is a big point for both of our customers trying to do ad insertion. What do you see on your end as far as JW customers needing this for their player technology? 

Eric: Hi, Ryan. Yeah, this is really an interesting way to get ads to be inserted into livestreams. You really don't have a full stack set up to gets ads directly inserted into the livestream on the server side. So you're able to just very easily just put in a signal into the livestream. And on the client side that signal can be picked up and then the JW player will be able to trigger a client-side ad to be requested and then inserted into the stream. 

So this adds a benefit of being able to get ads put in a livestream where traditionally you're only able to get them in with client-side insertion as a pre-roll slot. So we've see a lot of customers being able to just add these in as like maybe an overlay ad at some point in the livestream, or if you know if there's an actual commercial break you can trigger the ID3 tag to be inserted a little bit before that break. Then the client-side ad insertion process can be triggered off of that signal.

Ryan: Scott, this is exactly what we're going to be showing in today's demo, is literally how to trigger this using a big red button, send that command to Wowza Streaming and then of course, relay that back to the player. Maybe give us a quick overview and then we'll jump into a demo where we can see this in action. 

Scott: Sure. Yeah there's really just three little pieces of code that we need in order to do this. So the first is what we call the big red button. What that means is if you're streaming some content and you go to a time out in a sporting event or some point in your live event where you would like an ad, the idea is that you would hit a button and it would tell Wowza Streaming Engine, "I need an ad at this point in time."

And then the second little piece of functionality that we need to do is we need to detect that piece of meta data, and then we need to convert that into an ID3 tag so the HLS stream going out the other side to JW player actually has an ad break in it that JW player can detect. 

And then the third piece is, there's a little bit of custom code that needs to happen in your HTML on the JW Player side that detects that ID3 tag and then makes the bass call [SP] and the bass call serves up the ad to the JW Player and adds the ad. So I'll do a really quick demo of that. 

Ryan: Perfect.

Scott: Yeah, in this demo the big red button, which is neither big nor red, says "insert ad." That actually would not be something your clients see. But in this demo we have the video of what your clients see, and then also what would happen on the broadcast side. 

So I'm going to hit the button. When I hit the button it makes and HTTP post call to Wowza Streaming Engine. It says insert an ad now. When we get to that point in the video, you'll see it made the bass call and it inserted the ad. When the ad resumes, or when the ad finishes, the livestream will resume. And that's what I'm gonna show, I'm gonna show the bits of code to put this together. 

Ryan: Perfect, and in today's demo we're doing this in kind of a local environment on your local machine. But of course you can implement this on your own web server, implement that on your own JavaScript and HTML, and then of course run this on Wowza Streaming Engine out on the cloud or on your own hosted machine as well. 

Scott: Yes, and I know we're going to provide the code snippets in a zip file, accessible to folks. It should be very easy for people to put this together. 

Ryan: Perfect.

Scott: So the first part I want to talk about is the big red button. And there are markers in livestreams, in some livestreams already, like SCTE 35 markers. There are ways with different encoders to actually inject this data into the stream at the encoder.

But a lot of people don't have either of those options, and so the way that we're going to do it is we're going to just send a post command to Wowza Streaming Engine that says "insert that now." And we do that with an HTTP provider. And so the code that I have on the screen is an HTTP provider. We have articles on how to write these. Very simple set of code. 

Essentially, we configure Wowza's server to receive the HTTP post command and then we break that command apart. And then we inject an AMF data event into the stream. So the first method, if you look, starts at line 23. This just intercepts the HTTP request that we sent when we hit the insert ad button. 

And so in this code, we pull the parameters from the HTTP post command and then we actually use those parameters to have the application in the stream name to actually find the application stream name in our running Wowza server. And that's what happens down here, around line 49. 

And then the last bit is, once we find that we just want to send a little ad break message. I'm gonna scroll down to that code. So this method, "send ad break," creates an AMF data object that's in action script message format and it creates this object. It puts the ad ID in. The ad ID is just the URL that we are going to use to talk to the ad network to request the vast XML file. I don't know if, Eric, if you want to talk a little bit more about what what that would mean to someone using an ad network and talking to, making a vast request?

Eric: So the way that you have this set up here, is it just actually grabbing as an ad ID, as the vast tag URL? 

Scott: That's right, yeah. It's running on a local server for the purposes of the demo. 

Eric: Yeah, that's a perfect use case. The ad ID is really just exactly what JW Player needs to request when it needs to make the ad request. So it's a, here we have it as a vast tag URL. You could also just do it as a signal that would say if the tag is already on your page. You could just have that be a signal to just say okay, now request the tag that's already on your page. 

But this is also actually a neat idea, because it doesn't just have to be for ads. You could also have this be any generic amount of meta data for what's happening in the stream for this at that point in time. 

Scott: Yeah.

Eric: And then the page could just display that information.

Scott: Yeah, exactly, yeah. So this is the first part of the puzzle. So we are able to make a HTTP post request to the server, and then we inject a piece of meta data into our inject screen. And the next part of the puzzle is detecting that that piece of meta data, which is not in a format that Apple HLS handles. We're streaming HLS to JW Player, so we need to intercept that event and convert it to an ID3 tag. 

And so this is another module that we're going to add to the Wowza Streaming Engine. This particular module listens for the data that, as we're filling up our chunks for HLS streaming, every time we add a packet this method, "on fill chunk data packet" gets called. And what we do is we look at each of those data packets and we see if they have any AMF data in them, and if they have any AMF data and it is the "on ad break" that we just inserted, then we create an ID3 tag. 

And that gets placed into the chunk that we are sending out via HLS. So this code again is, there's not a lot of code here to do this. The bottom part of this class actually just wires up our data handler, so when the application starts, which is down here at the very bottom we register to listen for any livestream packetizers [SP] being created or destroyed. 

When our packetizer is created, we set ourselves as the data handler. And then that causes us to be called every time a packet gets added to the HLS stream. And then this last bit of codes detects that the AMF data even that says there's an ad break and converts it to an ID3 tag that says there's an ad break. And then that will get passed along to JW Player as its playing the HLS stream. 

So the last part is to detect the ID3 ad break on the JW Player side. So I'm going to show this in HTML. And so the HTML itself, there's not very much here. There's the part where it loads the JW platform libraries, the button we had previously to show the ad, and then a div that is going to hold our JW Player. As we get into the script, this is all JavaScript, we have some variables at the top that define where the IP of our Wowza server and our ad server...these are local hosts currently. 

The ad URL determines the HTTP post that we make to insert the ad markers that we talked about earlier. And then this is the Wowza application and the stream name we're actually going to insert the ad into. Applications live in the stream is my stream. 

This is fairly standard code to insert JW Player into the div above. One difference here is that we have an advertising section and we've set the client to be vast, and that is what actually does the playing of the ad, the request for the vast asset and playing back the ad. This is currently set to primary of Flash. Eric, I understand you guys have some changes in that area currently?

Eric: Yeah, it's actually a good reason to make sure that you either stick to a cloud-hosted player that's constantly being updated or you just keep checking out our release notes. Because actually in JW 7.3, we updated the player so that ID3 tags could be detected in output and HTML5 mode when you're in Safari.

So previously you had to lock the player into Flash to get ID3 out, but we've since updated it so that you can actually get them out in HTML5 mode. And as of JW Player 7.4, we are actually going to be doing HLS in HTML5 mode in Chrome. So this way your players can just be automatically updated to that version and you will get HTML5 playback on the HLS almost everywhere. We're really excited about that.

Scott: That's really nice. So I'll continue with the demo of the code. The piece of this code is this little bit that detects the ID3 tag. And so when the ID3 tag comes across in the stream, on meta data gets called, we look for the ad ID that has a URL of the vast XML file. And the vast XML file just tells us where to go get the ad. 

The last part of this is we just tell JW Player, play the ad and use this vast XML to find the ad. And as you saw, that just plays it. There's a little bit of code here at the bottom. This was the big red button part to insert the ad and to send the post. As I said before, all this code is combined into a single set of HTML, but this shows you how to actually make that call to insert the ad in step number one in the process. And a little utility class to actually do an HTTP post. 

So that's all the pieces that are needed on the Java server. Then what happens is you need to compile that Java code into a jar file, and the jar file gets put into the streaming engine lib folder. And that way when streaming engine starts up, it can detect those jar files, and I'll quickly show you how to configure so the streaming engine knows to run those classes that we just wrote. 

The first part is the HTTP provider we wrote, and that's the big red button part. You cannot configure this through Streaming Engine Manager. You actually have to go into the V host of that the XML file. So that's what I am showing here on the screen. The highlighted code is the HTTP provider. So you can see we have the actual fully qualified path of our HTTP provider that we wrote. 

The second part is insert ad marker. When we make the post to Wowza, it walks through all its HTTP providers and it looks for ones that match. So you can see the one above it is set up for livestream record. So if we wanted to control livestream record, we would send a post and at the very end of the URL it would have had livestream record, followed by some query parameters. 

Similarly for insert ad marker, ours ends with insert ad marker query param, the app name, the stream name. So this goes in the V host, it's saved and then we'll have to restart the server. And then that HTTP provider will be running. As you can see in here there are different host ports. We put this HTTP provider under 8086. So when we send that post we need to specify that port.

I'll go into streaming manager to show you how to configure the other module. So our application we're using is the live application, and when we're in advanced mode we can see what modules there are. And you can see I have already added the module ad ID3 tags, and I will edit it so that you can see the actual values of it. So it has a name, a description, and then key part which is this last part which is again the fully qualified name of that class. And so when this application starts up, the jar file is loaded and this class is loaded and then everything is wired up as I explained earlier. 

So I can show this one last time now that we've seen the parts. So part one was the big red button. We click it, it sends the AMF data to streaming engine. Part two, streaming engine converts that into ID3 tags. That gets passed to JW Player. JW Player detects that ID3 tag and makes the vast call, and then the ad appears in your player. And when it's done JW Player resumes with the livestream.

Ryan: Awesome, Scott. Now I think there's a lot of people who are joining this series who maybe aren't coders, and the minute they look at code their eyes glaze over. But the reality is is that a lot of the Java code that you showed is already, we're going to provide these examples. 

People can download them, and as long as they load them into the server and then of course update the V host, really the only place they need to update code is in that JavaScript itself that you showed. Where they can reference their own IP address or their own server, and then reference their own license key. And apart from those parameters that's the only coding, "coding" you need to really get this working on your own. 

Scott: Yeah, that's true. It's pretty boilerplate code. Even with just a little bit of coding experience I think people can take it. Of course, an advanced programmer's going to be able to take it very far, but I think most people are going to be able to get this up and running with no problem. 

Ryan: Absolutely. And for ID3 tags, Eric do you see...what are other kind of use cases that people are using this for? I know we touched on that at the beginning of this session. 

Eric: Yeah, I've seen it as like ticker tape reel at the bottom of like a live sporting event, being able to pull out meta data for when a major event happens. And obviously the original use case for ID3 is still very prevalent today, where it's title and artist information for our audio streams. We see that quite a bit as well.

Ryan: Perfect. Well thanks guys. Scott, I appreciate you walking us through that that demo. And I think we'll go ahead and take questions now.