Order Now AdSolution Sign Up | Login » Bits on the Run Sign Up | Login »

Forums

/

Streamscript and preroll-postroll ads

66 replies [Last post]

Hello,

I am trying to use preroll/postroll ads playlist with streamscript flash var. I used Jeroen's sample xml file. After displaying preroll ads, it stops. My flvstream.php is just reading and streaming local flv file.
I am successfully using streamscript already, I just want to add preroll/postroll/overlay ads function to the player.
Please let me know.
Thanks.

<playlist version="1">
<title>Sample Preroll Ad</title>
<info>http://www.jeroenwijering.com/</info>
<annotation>
Sample playlist for the insertion of a pre-roll advertisement
</annotation>
<trackList>
<track>
<title>Spot a Job</title>
<location>http://www.jeroenwijering.com/extras/spotajob.flv</location>
<info>http://www.spotajob.com/</info>
<album>preroll</album>
</track>

<track>
<title>Afraid of the dark?</title>
<creator>Jeroen Wijering</creator>
<location>http://mysite.com/media/flvstream.php</location>
<image>http://www.jeroenwijering.com/upload/afraid.jpg</image>
</track>
</trackList>
</playlist>

I forgot to mention, I removed streamscript var from js, and used that flvstream.php file in xml playlist as I mentioned before.

Kevin,

Based upon the statement in your second post, "I removed streamscript var from js, and used that flvstream.php file in xml playlist...", you need to specify the file in the playlist. See the example "playlist.xml" below. Normally, when using 'streamscript' the player formulates a request to the server that looks like this: http://mysite.com/media/flvstream.php?file=afraid.flv&pos=0

Since you are not using the 'streamscript' var, you have to formulate that request in the playlist. you can leave off the "&pos=0" because that is the default.

Also, your playlist is missing the required first line, in bold below, and the second line is incomplete. See the XSPF playlist specification at [url=http://xspf.org/xspf-v1.html#rfc.section.1.1]xspf.org[/url]

<strong><?xml version="1.0" encoding="UTF-8"?>
<playlist version="1" xmlns="http://xspf.org/ns/0/"></strong>
<title>Sample Preroll Ad</title>
<info>http://www.jeroenwijering.com/</info>
<annotation>Sample playlist for the insertion of a pre-roll advertisement</annotation>
<trackList>
<track>
<title>Spot a Job</title>
<location>http://www.jeroenwijering.com/extras/spotajob.flv</location>
<info>http://www.spotajob.com/</info>
<album>preroll</album>
</track>
<track>
<title>Afraid of the dark?</title>
<creator>Jeroen Wijering</creator>
<location>http://mysite.com/media/flvstream.php<strong>?file=afraid.flv</strong></location>
<image>http://www.jeroenwijering.com/upload/afraid.jpg</image>
</track>
</trackList>
</playlist>

Thanks a lot! It works. May God bless you and Jeroen.

here's a somewhat related question:

I am wondering if I could simply use this same playlist, but substitute an RSS feed in place of the second item. For example:

<title>Spot a Job</title>
<location>http://www.jeroenwijering.com/extras/spotajob.flv</location>
<info>http://www.spotajob.com/</info>
<album>preroll</album>
</track>
<track>
<title>Afraid of the dark?</title>
<creator>Jeroen Wijering</creator>
<location>http://feeds.feedburner.com/burnthispodcast</location>

I tried that, and it doesn't work. Basically what I am aiming for is allowing someone to click a "play" button, and have it run a brief preroll ad, and then play the feed as normal.

tangentially - how hard would it be to insert ads before every item in a playlist? That is, simply calling an ad (or a random folder of ads) and after playing each item in the feed, it plays a short ad clip?

The first question is more immediate. Thanks!

@digital,

This link:

<location>http://feeds.feedburner.com/burnthispodcast</location>

seems to lead to a page with some links to mp3 files.

If the actual file that you want to play is an mp3 like this:

http://feeds.feedburner.com/~r/BurnThisPodcast/~5/113683429/020-050207-SymphonicGuitars.mp3

with an ".mp3" extension, the player will play that.

You need the additional step of selecting an actual media file of a playable type and then putting that line in the playlist in the <location> element.

This could be accomplished with the proxy scripts that Jeroen has in his "extras" folder with some extra code to parse out the media links.

Or you can use a playlist generator to generate the playlist with the link to the media file already in the <location> element.

It's sort of up to what your selection criteria are.

For your second item, a playlist generator can output a playlist with pre/postroll ads in ANY format acceptable to the JW Players. Again, it's up to you to specify exactly what format you want and where the links will come from. Like, from a list, from selection criteria (latest news), or whatever.

hey there -

not quite it, actually. I'll try to put this another way, with an obvious RSS file. If I had the following code:

<title>Spot a Job</title>
<location>http://www.jeroenwijering.com/extras/spotajob.flv</location>
<info>http://www.spotajob.com/</info>
<album>preroll</album>
</track>
<track>
<title>Afraid of the dark?</title>
<creator>Jeroen Wijering</creator>
<location>http://odeo.com/channel/106927/rss.xml</location>

I would expect that

<location>http://odeo.com/channel/106927/rss.xml</location>

to kick in right after the ad plays. That is, the ad plays, then the playlist with the feed to load and start playing, much in the way that I can simply enter

javascript:loadFile({file:'http://odeo.com/channel/106927/rss.xml'});openPlay(119);

and it will load the RSS feed as a playlist and start playing it.

Hope that clarifies - any ideas?

@digital,

Playlists don't load playlists, it's simply not built into the player code, much as I have wanted to do exactly that myself more than once. Consider that the player is parsing playlist.xml and along comes <location>http://odeo.com/channel/106927/rss.xml</location>, the player doesn't know what to do with that. You could build it into the ActionScript with a lot of effort, but it's not there now. Maybe you could even have <location>javascript:loadFile({file:'http://odeo.com/channel/106927/rss.xml'});openPlay(119);</location> work also.

The way to do it is to play the ad as a single file or a one-track playlist and then load another playlist, which would be your RSS feed.

If you look at andersen's [url=http://home5.inet.tele.dk/nyboe/flash/mediaplayer/]Demos[/url], he shows how to load another file/playlist when the player is finished with the one that is playing.

Will,

I was afraid it wouldn't let me call a playlist within a playlist.

I took a look at andersen's demos. I might be totally blind, but after poring through that thing, I can't find a single example that demonstrates one playlist playing, and then another one picking up immediately after that. Can you point me to the exact one?

@digital,

OUCH! I was afraid you were going to ask me "The Hard Question".

The basic process is to monitor the state of the player in JavaScript. When you get a state 3 (stopped), do a loadFile({file:'path-if-needed/next_playlist.xml'}) to load your second playlist.

At this point, I'm assuming (BIG assumption), that you have the JavaScript API set up and working (the JS code in the <head>, 'enablejs', 'true' 'javascript', 'mpl' var s1 = new SWFObject('mediaplayer.swf', 'mpl', '540', '516', '7'); and son and so forth).

Well, you are right about no specific example on andersen's demo pages. However, if you check this demo [url=http://home5.inet.tele.dk/nyboe/flash/mediaplayer/redirect.htm]redirect[/url] he is using this code to call another link when the player has stopped, so just substitute loadFile there.

function getUpdate(typ,pr1,pr2,pid)
{
if(pid != "null")
{
if((typ == "state")&&(pr1 != undefined))
{
currentState = pr1;
if(currentState=="3")
{
<strong>document.location.href="index.htm";</strong>
}
}
}
};

Will;

That sounds ideal - I can't seem to get the actual code to work, though. Here's what I have:

<p id="player"><a href="http://www.macromedia.com/go/getflashplayer">fail</a></p>
<script type="text/javascript">

var currentState;

function getUpdate(typ,pr1,pr2,pid) {
if(pid != "null") {
if((typ == "state")&&(pr1 != undefined)) {
currentState = pr1;
if(currentState=="3") { document.location.href="http://google.com"; }
}
}
};

^^that first part was basically copied directly from the demo you showed me...

var s = new SWFObject("http://get-a-bar.com/playground/wp-content/plugins/jw_media_player/mediaplayer.swf","mpl","450","312","6");
s.addParam("allowfullscreen","true");
s.addVariable("file","http://home5.inet.tele.dk/nyboe/flash/mediaplayer/video.flv");

s.addVariable("overstretch","fit");
s.addVariable("image","http://home5.inet.tele.dk/nyboe/flash/mediaplayer/startimg.png");

s.addVariable("enablejs", "true");
s.addVariable("shuffle","false");
s.write("player");
</script>

So there we have it. I tried redirecting to www.google.com, and no dice. I figure once I can get that to work, that simple plugging in of the loadFile should be easy enough.

As an aside:

correct me if I'm wrong, but I could just replace the demo file I'm connecting to and simply call an xml file with ads in it (which is easier to update - just one edit rather than changing the code for a few dozen player instances across various blog posts) and after it hits the end of the playlist, it'll call up the new one...correct?

Thanks!

@digital
you also need to set: s.addVariable("javascriptid","mpl");

@digital,

In the <head> you should have:

<head>

<script type="text/javascript" src="swfobject.js"></script>

<script type="text/javascript">

var currentState;

function getUpdate(typ, pr1, pr2, pid)
{
if(pid != "null")
{
if((typ == "state") && (pr1 != undefined))
{
currentState = pr1;
if(currentState == "3")
{
document.location.href = "http://google.com";
}
}
}
};

function createPlayer()
{
var s = new SWFObject('http://get-a-bar.com/playground/wp-content/plugins/jw_media_player/mediaplayer.swf', 'mpl', '450', '312', '6');
s.addParam('allowfullscreen', 'true');
s.addVariable('file', 'http://home5.inet.tele.dk/nyboe/flash/mediaplayer/video.flv');
s.addVariable('width', '450');
s.addVariable('height', '312');
s.addVariable('overstretch', 'fit');
s.addVariable('image','http://home5.inet.tele.dk/nyboe/flash/mediaplayer/startimg.png');
s.addVariable('javascriptid', 'mpl');
s.addVariable('enablejs', 'true');
s.addVariable('shuffle', 'false');
s.write('player');
</script>
}

</script>

</head>

Then in the <body>

<body onLoad="createPlayer();">

<div id="player"><a href="http://www.macromedia.com/go/getflashplayer">fail</a></div>

</body>

correct me if I'm wrong, but I could just replace the demo file I'm connecting to and simply call an xml file with ads in it (which is easier to update - just one edit rather than changing the code for a few dozen player instances across various blog posts) and after it hits the end of the playlist, it'll call up the new one...correct?

Yes.

s.addVariable('file', 'playlist_with_ads.xml');

Then replace:

document.location.href = "http://google.com";

with:

loadFile({file:'path-if-needed/next_playlist.xml'})

I think the code and the syntax is right, but I haven't tested it.

Will,

THANKS. I'll respond to this and add in other information for others who may be curious/find this in the future.

I do believe that you added an extra </script> up there - that is, it should have ended as follows:

...
s.addVariable('enablejs', 'true');
s.addVariable('shuffle', 'false');
s.write('player');
}

</script>

</head>

not as you put it, which was

s.addVariable('enablejs', 'true');
s.addVariable('shuffle', 'false');
s.write('player');
<strong></script></strong>   <-- don't think this belongs!:d
}

</script>

</head>

But I could be wrong.

Aside from that, it worked - like a charm, even. If you add an openPlay command after the loadfile command - e.g.

loadFile({file:'http://odeo.com/channel/34348/rss.xml'});<strong>openPlay(119);</strong>

it will automatically play your playlist (which is what I think most people would want).

Okay, now on to the not so fun stuff.

Oddly enough, it seems that if I call a playlist using the

s.addVariable('file', 'playlist_with_ads.xml');

line, the image called in this line:

s.addVariable('overstretch', 'fit');
<strong>s.addVariable('image','http://home5.inet.tele.dk/nyboe/flash/mediaplayer/startimg.png');</strong>
s.addVariable('javascriptid', 'mpl');

no longer shows up.

So, you have to embed it in the xml file using the <image>tag</image> (bit more information [url=http://www.jeroenwijering.com/extras/readme.html#playlists]hereclick here[/url])

However, I had an issue with setting the preroll ad as a preroll. It wouldn't display the preview image either!

But - if you just set the preroll ad as a postroll - that is, use the following line

<album>postroll</album>

instead of

<album>preroll</album>

it works, and there's no functional difference (for my purpose, anyway). A little quirky, but hey.

---
So, that's my input here.

Hope that last post helps a few lost souls...but...

next - a question! (didn't think I'd let you all get off that easy, did you?)

I have a production blog where I have around 70-80 music or video files. Before each one, I'd like to play an ad/info snippet.

The way I have it working is similar the site linked on my name (above^^).

Basically there's a javascript link that you click on and it loads the video in the right. Fairly basic.

But - I'd like to keep this same ease of use and transparency, but have the player, whenever it is asked to play a file, interrupt that file and inject a preroll snippet before the file plays - disallowing scrubbing is a plus - and then continue with the file.

Or, alternatively (if it is easier), it could play the file, and then immediately play a postroll (e.g. "thanks for watching this video! tell your friends!!") - perhaps set with a link so that people could click on that and view the original author's site.

I ask this because it would be an absolute pain to make a brand new xml playlist for each and every blog post.

I've a notion that this can be done with javascript - but alas, am a mere hack.

Thanks in advance, and in retrospect for the help thus far.

@digital,

Damn, I knew that lost </script> was somewhere and would show up sooner or later. So you found it, thanks. :)

As soon as you start using a playlist, the values for the flashvars: "artist", "title", "image", "file", "type", "link" and whatever I can't think of now, ALL come from the playlist, so that's normal behavior.

Interesting observation about preroll, postroll, and image. I'll have to tuck that away for future use.

I've got to digest your last post and turn it into a sequence of events, with conditions, before I can tell you how to do it. Sure it can be done though.

Will,

on the lost </script>: no problem - only hope it's useful to others!

Right on, I'll watch this thread for updates.

@digital,

For the blog playlists; you could use a little script that chewed up the old playlists and spit out new ones. I helped a professor at the UofMn do that for his v1 JW MP3 Player and he had LOTS of HUGE playlists. Just look through the directories, everytime a playlist is found, read it and write the new one with whatever new format or information is needed. His ran for days!

The other alternative is what you outlined above; use a postroll playlist. With this

perhaps set with a link so that people could click on that and view the original author's site.

it might even be more effective.

Let me know how you want to proceed.

Not sure I quite follow what you did with the mastication and regurgitation of old playlists - perhaps that's what I want, but it's not quiiiite clear to me.

I'll try to elaborate on what I suppose would be the coolest way - assuming that it's possible.

I'd like the player, whenever it is asked to play a file (whether through js command or clicking on the player itself) to check an xml file.

If there is an ad in the xml file, it should play it as a preroll ad - then it moves on and plays the original requested file.

If there's nothing in there, then it simply ignores the xml file and plays the file.

So:

I have a player that, by default, has a podcast feed stored in it. When you click that, it checks the xml file and sees that there is an ad listed in there. It should play the ad, and then start playing the feed, all the way to the end.

I also have javascript links on the blog that link to specific mp3 files from the podcast. If you click on that, it should play the ad, then play the file you wanted.

And I think having the option to simply reverse that and ask the player to, after completing a file request, play a postroll ad, would be cool.

Again, it does seem doable, like you said. Any ideas?

@digital,

Not sure I quite follow what you did with the mastication and regurgitation of old playlists - perhaps that's what I want, but it's not quiiiite clear to me.

The point was that he had a lot of playlists that were not in the format that needed, but did have the title, artist, file info., so we read that and output a new file in the correct format with additional info.

Since you said that you didn't want to re-do lots of old playlists that didn't have ads, I brought that up as a suggestion. Read the old playlist, add the pre/postroll, and write a new playlist.

I'd like the player, whenever it is asked to play a file (whether through js command or clicking on the player itself) to check an xml file.

OK, that would have to be a new format playlist with the pre/postroll ads. My main point in the paragraph above.

I also have javascript links on the blog that link to specific mp3 files from the podcast. If you click on that, it should play the ad, then play the file you wanted.

Unless you are willing to re-do those JavaScript links, they would have to be hi-jacked and re-directed to a playlist that played the pre/postroll ads, then the MP3. May be a bit tricky.

And I think having the option to simply reverse that and ask the player to, after completing a file request, play a postroll ad, would be cool.

Probably the greatest feature of the JW Player is that it is almost infinitely extensible, through JavaScript, through the JavaScript API, and through server-side scripting and AJAX (dirty acronym, I know), but it works.

It really boils down to what you already have, how much you are willing to update/re-do, and what you want to do (pretty clear now).

User clicks on a link, pre/postroll ad plays, MP3 plays, if postroll, some other "stuff" happens.

More??? ;)

you know what - i'm totally willing to re-do any old work I've done - what's a wasted hour or two out of my free afternoon, right? Also, I think it'd be most useful for other people if a basic code exists that isn't some retroactive hack on my accord.

User clicks on a link, pre/postroll ad plays, MP3 plays, if postroll, some other "stuff" happens.

Precisely. Now, if you can just speak that in Javascript (or whatever language is relevant), I'll be happy!

@digital,

OK, so you have a link that's going to call the player and a playlist (with pre/postroll and an MP3). All of this can be done in the URL of the link.

Where does the player appear? On the same page, another page, I wouldn't use a popup because of blockers. The player control bar can be sitting dormant on the same page as a 20x100 control bar, even hidden using CSS if that's the appearance and action that you want.

Will,

on the same page, in a sidebar (using wordpress, actually).

you can click my name to see a very sparse testbed. No content there, but that's the format. Blog posts will be on the left in the main content area, and the player stays on the right side.

You click a link and the whole

ad playlist --> video plays --> (optional postroll) plays.

whoops. here's that link.

@digital,

OK, let me run through this once more to make sure that I've got it right.

You've got a page with some content and a mediaplayer on it.

When the user clicks on a link, you want to:

1) grab your standard, common, current "#1 ad playlist" and play whatever is on it. Preroll, overlay, dancing monkeys, whatever is on it.

2) next, you want to grab the playlist that is specific to the current page and play whatever media is on that playlist, music, commentary, video, images...

3) next, you want to grab your standard, common, current "#2 ad playlist" and play whatever is on it. Preroll, overlay, media, postroll, whatever is on that #2 playlist.

Of course, you can skip 1) or 3) depending on how you want to present the media show. I'm keeping this generic and flexible so that you or other users can choose the format of the media show. I'm thinking that once a package like this is developed, others may want to use it, and I've seen that everyone seems to have their own "best way to do things".

Sound like what you want? Now's the time to make feature requests. :)

Yep - that's basically it. Here's what I use right now:

<a href = "javascript:loadFile({file:'song.mp3', 'picture.jpg'});openPlay(119);">click here to listen</a>

So it could certainly be a playlist, or, as above, a single mp3/flv/whatever. It's like this because I could have 5 posts a day, all with different songs, and being able to just have them all play in one sidebar media player is pretty cool - plus saves quite a bit of page real estate.

Right now, I could probably easily just do it within the link - but if the player knows to check a predefined xml file before/after fulfilling a play request - whether a user clicked on a javascripted link (as above) or the player itself (for the first time) - that would be ideal.

I agree that others would probably be interested in the same package - thus trying to keep it as generic as possible. I'll also do anything I can on my end to help document it so that people can make use of this feature.

Extra feature requests, eh? I think we're good for now :d

(as an aside, I think the ability to insert ads into a player's playlist - e.g. the playlist shows only song 1, song 2, song 3, etc - but after playing each item, the player grabs an ad from ads.xml - would be neat. I don't need that now, but I can see interest in it)

@digital,

OK —— so I'm thinking this should probably be a little JavaScript package with a few vars that you could configure for the playlists and behavior. Since we have to use JS to feed the player, we might as well stay in that language. The default behavior could still be changed by sending JS values in the link (like if you wanted to play an MP3 backwards to listen to the secret messages :d ).

That's what I was thinking, exactly - just don't know how to code it. I figured that it'd probably be similar to the implementation of the currentstate var - in the header, etc.

secret messages, even. sounds good to me! ;)

@digital,

OK, I'm on it. (secret messages too ;))

@digital,

Check this out [url=http://willswonders.myip.org:8085/php/multiple_playlist.html]Multiple Playlist Playback[/url]

It's a little buggy, so reload before you make another selection.

You will probably want to use the 12, 123, and 23 combos in your blog.

Look at the top of the page source; you can see where you specify your ad playlists. The content playlist and the behavior (12, 123, 23) is specified in the link.

Look like what you were after?

Will,

WOW. I think you've basically done it. I do see that making another selection breaks it, but the functionality is certainly there. I think the entire community will certainly get a great deal of use out of this.

In short, brilliant work. Thank you.

A question:

1 - I see that you have playlist_empty.xml preloaded. I'm assuming that it would be possible to have that playlist_multi.xml preloaded, and give it the 123 (or whatever) behavior as well?

As soon as I'm able to test this and give a bit more feedback, I will.

In other news, somebody get this cat a medal.

@digital,

Yes, you can preload any playlist. I made the "playlist_empty.xml" so the player would be "dead" until the user clicked on the link. That may or may not be the behavior/appearance that you want.

I've also been experimenting with the exact composition of the ad playlists. There is a slight "glitch" in them, in that the preroll playlist needs more than one track. Jeroen is aware of this and will probably fix it soon. The postroll playlist functions well with only the one postroll track, but you can also use more than one postroll track or even a media track before the postroll.

I tried to keep my distance from anything limiting the flexibility of the system. There is one thing that I want to change. Quick & dirty, I'm using an <identifier> element value of "lastitem" to detect when the player is done playing all of the content if you have a multi-track content playlist. This is a real NO-NO because the <identifier> element is needed for RTMP streaming, but I didn't want to get side-tracked by that issue until I had the other system running. I'm sure that there's a way to detect the last item in a playlist without mis-using the <identifier> element.

Another issue that you need to think about and decide on a behavior, is what happens if you are going to run a postroll but the user stops or pauses the player while it is still on the media content. Do you just leave things like that, do you run the postroll, do you explode the page? :d

And normally, unless you had multiple links on a page, the player would be re-loaded before another selection was made. But that also raises the question, do you have multiple links on the same page? As I clean up the code and get rid of extraneous actions, that issue shuld go away. Like, the production player probably doesn't need the 1, 2, or 3 behavior. Maybe the 2, but you wouldn't normally run just a pre or postroll.

Anyway, check it out and let me know what you think about how you will normally use it.

Will,
I tried to keep my distance from anything limiting the flexibility of the system.

I agree that making the system as flexible as possible is the best way to go about it.

As far as postrolls, if someone stops/pauses the player - say to make a three minute phonecall - it would be a bit obnoxious to have a timer and say "well, better ditch where you are now and run this postroll ad/information!". I can't think of a situation where that would be appropriate or feasible without being fairly annoying - unless you have any ideas?

I would say that if an ad/announcement needs to be made, it should go in the preroll to make sure it happens - otherwise, you'll have to leave it to the user as to whether they stick around long enough to see the postroll.

I'll try to play with this thing tonight. I'm thinking it might also be interesting to allow for the preroll and postroll playlists to be randomized - i.e. pulling from a random list of ads as some might make use of that - while keeping the main playlist in the predefined order.

And yes, I'd be running this script with multiple links per page. This would be to allow each link the flash player functionality without taking up a whole bunch of room.

For example, there could be seven blog posts on one page, each with a media file set up to run within a sidebar player.

@digital,

I'm thinking it might also be interesting to allow for the preroll and postroll playlists to be randomized - i.e. pulling from a random list of ads as some might make use of that - while keeping the main playlist in the predefined order.

I don't think that you can have a playlist with a bunch of pre/postrolls and select one of them, so they would have to be separate playlists - playlist_ads1.xml, ads2, ads3, etc. The available playlists can be listed in the JS and one of them selected. Or we can always load a list of lists for easier maintenance, so the page would only have a link to the list of lists.

I'm screwing around with page of text with multiple links. Looks OK. I'm only using 12 123 23.

Will,

The separate playlists doesn't sound like a problem. Glad to hear that the multiple links page works as well - hopefully that other version you've got clears up some of the other bugs that the early demo above has (needing to reload the page to try another selection), etc.

@digital,

Yeah, try it here, or better yet, put the code into your demo page.

[url=http://willswonders.myip.org:8085/php/multiple_playlist_text.html]Multiple Playlists w/text[/url]

playlist_empty.xml

<?xml version='1.0' encoding='UTF-8'?>
<playlist version="1" xmlns="http://xspf.org/ns/0/">
  <trackList>
    <track>
      <title></title>
      <creator></creator>
      <location></location>
      <album>preroll</album>
    </track>
  </trackList>
</playlist>

playlist_ads1.xml

<?xml version="1.0" encoding="UTF-8"?>
<playlist version="1" xmlns="http://xspf.org/ns/0/">
  <trackList>
    <track>
      <creator>Advertiser</creator>
      <title>AD</title>
      <location><strong><em>Put content here</em></strong></location>
      <album>preroll</album>
      <identifier>lastitem</identifier>
    </track>
    <track>
      <creator>Please watch this short ad</creator>
      <title>while we load your chosen content.</title>
      <identifier>lastitem</identifier>
    </track>
  </trackList>
</playlist>

playlist_ads2.xml

<?xml version="1.0" encoding="UTF-8"?>
<playlist version="1" xmlns="http://xspf.org/ns/0/">
  <trackList>
    <!-- <track>
      <creator>Thank you for watching</creator>
      <title>we hope you enjoyed this presentation.</title>
      <identifier>blank</identifier>
    </track> -->
    <track>
      <creator>Advertiser</creator>
      <title>Postroll Test</title>
      <location><strong><em>Put content here</em></strong></location>
      <album>postroll</album>
      <identifier>lastitem</identifier>
    </track>
  </trackList>
</playlist>

playlist_multi.xml

<?xml version='1.0' encoding='UTF-8'?>
<playlist version="1" xmlns="http://xspf.org/ns/0/">
  <trackList>
    <track>
      <title>Song 1</title>
      <creator>Artist</creator>
      <location><strong><em>Put content here</em></strong></location>
      <identifier>song1</identifier>
    </track>
    <track>
      <title>Song 2</title>
      <creator>Artist</creator>
      <location><strong><em>Put content here</em></strong></location>
      <identifier>song2</identifier>
    </track>
    <track>
      <title>Song 3</title>
      <creator>Artist</creator>
      <location><strong><em>Put content here</em></strong></location>
      <identifier>lastitem</identifier>
    </track>
  </trackList>
</playlist>

Don't change this element in any of the playlists:

<identifier>lastitem</identifier>

I still have to find a better way to detect the last item... :|

Will,

Just got around to testing this out. Looks good, and I've got it running on my page without a problem. Couple of questions:

1. How might one have an rss feed preloaded in the player, and whenever the player itself is clicked (before any other files are selected), it runs an ad? Is that also possible?

2. If someone clicks the "next / previous track" button on the player while an ad is playing, it restarts that ad. Any way to disable that function at all? Or, we can just leave it to punish the user for trying to skip ads ;)

3. I noticed that you included the following in the player code:

s.addVariable('repeat',        'false'); // MUST be false

In addition to preventing the song from playing over and over again, this also prevents songs in a playlist from automatically playing after the previous cut is finished. Is there any way to allow songs to naturally continue playing down a playlist?

95% there. Great stuff.

@digital,

Thanks for being my beta tester!

I've tweaked the code some, so you might want to grab the JavaScript (not the player code) from multiple_playlist_text.html again. I started putting the date and time as a comment in the JS so users could keep track of updates.

1) I'm not entirely sure what you want here. The player could be pre-loaded with a playlist or an RSS feed, instead of "playlist_empty.xml" — did you have something more in mind?

2) I guess that's a consequence of a single track (with preroll) playlist. Normally, on a multi-track playlist, the user can jump to the next track, but the user can't skip a preroll ad to watch the content of that track. I'll look into what's happening then and see if we can disable the selection of the next track.

3) This caused me a lot of grief. If you have repeat 'list' or 'true', the playlists don't load and start playing. I think it's also the cause of problems when you click on the second or more links on a page without reloading the page. Once I have experimented a bit more, I want to call this to Jeroen's attention, because there is something quirky in the player's behavior. I wanted to have repeat 'list' but it's not possible at this moment, unless I can figure out a way to get the next playlist to load and play. As a temporary workaround, I can probably use JS to play the next song.

So... please elaborate on item 1); meanwhile I'm working on:

1] not restarting the ad,

2] playlist repeat 'list',

3] now that I've got the basic code working, I've got to get andersen's help with starting the player after loading. Right now, I'm using a timeout because I couldn't get his method of checking the state of the player to work. It may just be because of the repeat 'list' problem mentioned earlier. That caused me a lot of grief during development until I realized that it was the cause of the player not starting playing. So a lot of thngs I tried have to be retried now that I know about that.

Will,

Sure, here's what I mean for #1:

Right now, if I have an external feed - let's say, http://site.com/odeofeed.xml, I can have that preloaded into the player. That's good.

However, when a user clicks on the player, by default it plays the feed straightaway.

I'd like to make it possible to have a preroll (or perhaps a postroll, thought that isn't as important) that will run, and then start playing an external feed.

As you (I believe) said above, it isn't possible to reference an external feed from an xml file, so it wouldn't be possible to just make an xml playlist that had two items: one as the ad, and the second as the external feed.

So - how might one configure the player so that when a user clicks directly on it (before loading any other songs via the javascript thing you've implemented), it plays an ad first?

@digital,

Try it now. If you click on the player, it plays the preroll ad, then one of my playlists, which would be your RSS feed. If you click on the links in the text, they work normally, whether or not you have clicked on the player first (I hope!). [url=http://willswonders.myip.org:8085/php/multiple_playlist_text.html]multiple_playlist_text.html[/url]

Will,

Looking good. Is there any way to display the actual feed/playlist in the player (as if there is no ad there) and then "inject" the ad when the player is clicked?

e.g. the playlist is displayed as normal, but when the user clicks it (or clicks an item in the playlist) a preroll plays, and then the playlist resumes.

Too tall of a request?

@digital,

You mean fake it, like replace "Please watch this short ad...", with "John Lennon - Yellow submarine" OR real content pulled from your RSS feed?

The first is easily doable, the second is difficult (use JS to parse the RSS and inject 'author' & 'title' into the player).

Or maybe server-side, create the "playlist_ads1.xml" from the RSS feed on-the-fly, much easier. Needs a PHP script to parse the RSS and create the playlist. I'll have a look. Can I have a link to an example RSS feed?

Nope - the hard way. Faking it would be fairly easy - just replacing the text.

I'm not necessarily going to use this - just throwing it out there as an interesting option that people may be interested in.

Here's an example RSS feed - Merlin's 43 Folders feed (which, by the way, is generally pretty cool).

http://odeo.com/channel/34348/rss.xml

Thanks thus far...as always, I'll be here to beta test!

@digital,

OK, that's easy enough to parse server-side. What do you want, just the titles or more?

<title>Inbox Zero - Google Tech Talk</title>

There's also an author element:

<itunes:author>43 Folders</itunes:author>

Is server-side creation of the initial playlist from the RSS feed an acceptable solution?

@digital,

This:

var initialPlaylist = "playlist_RSS_with_Preroll.php";

Or this:

var initialPlaylist = "playlist_RSS_with_Preroll.php?ad_location=ad.flv&rssfeed='http://some.com/channel/1234567890/rss.xml";

Plus this:

<body onload="createPlayer(initialPlaylist);">

Gets this:

<?xml version='1.0' encoding='UTF-8'?>
<playlist version='1' xmlns='http://xspf.org/ns/0/'>
  <trackList>
    <track>
      <creator>Advertiser</creator>
      <title>AD</title>
      <location>/Movies/CG_chick_avi_mencoder.flv</location>
      <album>preroll</album>
    </track>
    <track>
      <creator>43 Folders</creator>
      <title>Inbox Zero - Google Tech Talk</title>
      <location>http://odeo.com/show/15872233/4/download/InboxZero-GoogleTechTalk.mp3</location>
    </track>
    <track>
      <creator>43 Folders</creator>
      <title>Kung Fu, Meditation, and Sexual Intercourse</title>
      <location>http://odeo.com/show/5961123/4/download/KungFuMeditationAndSexualIntercourse.mp3</location>
    </track>
    <track>
      <creator>43 Folders</creator>
      <title>Macworld: Jason Snell and John Gruber on iPhone applications</title>
      <location>http://odeo.com/show/5593233/4/download/MacworldJasonSnellAndJohnGruberOnIPhoneApplications.mp3</location>
    </track>
    <track>
      <creator>43 Folders</creator>
      <title>Productive Talk Comp.: Episodes 01-08</title>
      <location>http://odeo.com/show/3351643/4/download/ProductiveTalkComp.Episodes01-08.mp3</location>
    </track>
    <track>
      <creator>43 Folders</creator>
      <title>Productive Talk #08: GTD 2.0?</title>
      <location>http://odeo.com/show/2952623/4/download/ProductiveTalk08GTD2.0.mp3</location>
    </track>
    <track>
      <creator>43 Folders</creator>
      <title>Productive Talk #07: Implementing GTD</title>
      <location>http://odeo.com/show/2561503/4/download/ProductiveTalk07ImplementingGTD.mp3</location>
    </track>
    <track>
      <creator>43 Folders</creator>
      <title>Productive Talk #06: Interruptions</title>
      <location>http://odeo.com/show/2353215/4/download/ProductiveTalk06Interruptions.mp3</location>
    </track>
    <track>
      <creator>43 Folders</creator>
      <title>Productive Talk #05: Email</title>
      <location>http://odeo.com/show/2270040/4/download/ProductiveTalk05Email.mp3</location>
    </track>
    <track>
      <creator>43 Folders</creator>
      <title>Productive Talk #04: Teams</title>
      <location>http://odeo.com/show/2214480/4/download/ProductiveTalk04Teams.mp3</location>
    </track>
    <track>
      <creator>43 Folders</creator>
      <title>Ian Shoales: Wasting Time</title>
      <location>http://odeo.com/show/2206256/4/download/IanShoalesWastingTime.mp3</location>
    </track>
  </trackList>
</playlist>

From this:
playlist_RSS_with_Preroll.php

<?php

// number of items in playlist
$items = 10;

// default ad location
$ad_location = 'ad.flv';

// default rss feed:
$rssfeed = 'http://some.com/channel/1234567890/rss.xml';

if (

$_REQUEST['ad_location'])
{
 
$ad_location = $_REQUEST['ad_location'];
}

if (

$_REQUEST['rssfeed'])
{
 
$rssfeed = $_REQUEST['rssfeed'];
}

$rss = file($rssfeed);

if (

$rss)
{
 
$count = 0;
 
$first_item = false;
  foreach(
$rss as $data)
  {
   
$data = trim($data);

   

// look for first item
   
if($data == '<item>')
    {
     
$first_item = true;
    }

   

// can't look for elements until first item has been found
   
if($first_item == true)
    {
     
// look for title
      //           <title>Inbox Zero - Google Tech Talk</title>
      //           <title>(.*?)<\/title>
     
if (preg_match('/<title>(.*?)<\/title>/', $data, $match))
      {
       
$title = $match[1];
      }

     

// look for link
      //           <enclosure url="http://odeo.com/show/15872233/4/download/InboxZero-GoogleTechTalk.mp3" type="audio/mpeg" length="42407776"/>
      //           <enclosure url="(.*?)"(.*?)\/>
     
if (preg_match('/<enclosure url="(.*?)"(.*?)\/>/', $data, $match))
      {
       
$link = $match[1];
       
$feeds[$link]['title']  = $title;
      }

     

// look for author
      //           <itunes:author>43 Folders</itunes:author>
      //           <itunes:author>(.*?)<\/itunes:author>
     
if (preg_match('/<itunes:author>(.*?)<\/itunes:author>/', $data, $match))
      {
       
$author = $match[1];
       
$feeds[$link]['author'] = $author;
       
$count++;
      }

      if (

$count > ($items - 1))
      {
        break;
      }
    }
  }
}

// generate playlist
if ($feeds)
{
 
header("content-type:text/xml;charset=utf-8");

  print <<< END_HEADER

<?xml version='1.0' encoding='UTF-8'?>

<playlist version='1' xmlns='http://xspf.org/ns/0/'>
  <trackList>
    <track>
      <creator>Advertiser</creator>
      <title>AD</title>
      <location>{$ad_location}</location>
      <album>preroll</album>
    </track>

END_HEADER;

  while($things = current($feeds))
  {
    $link = key($feeds);
    print <<< END_TRACK
    <track>
      <creator>{$things['author']}</creator>
      <title>{$things['title']}</title>
      <location>{$link}</location>
    </track>

END_TRACK;

    next($feeds);
  }

  print <<< END_FOOTER
  </trackList>
</playlist>

END_FOOTER;
}

?>

Probably needs to be escaped here:

s.addVariable('file', escape(playlist));

'nuff?+? :)

Package for Multiple Pre/Postroll and Content Playlists
Will - 09-05-07

Anybody who has been following this thread and wants a complete implementation package can get it here: [url=http://willswonders.myip.org:8085/downloads/multiple_playlist.7z]multiple_playlist.7z[/url]

The package consists of:

1) playlist_multi.xml
A sample playlist, nothing special.

2) multiple_playlist_text.html
A sample HTML page showing the use of playlist links to combinations of pre/postroll and content playlists, including an RSS feed with a preroll.

3) playlist_empty.xml
A sample empty playlist if you want to initially load the player with nothing.

4) playlist_ads2.xml
A sample postroll playlist.

5) playlist_ads1.xml
A sample preroll playlist.

6) multiple_playlist.html
A sample HTML page with buttons for playing around with the multiple playlists. Out-of-date.

7) playlist_RSS_with_Preroll.php
A PHP script to request an RSS feed and output a playlist with preroll (could be postroll), ability to limit the number of items in the generated playlist.

Will,

Just got a second to mess around with this. I copied over the code (looks like you updated a few things in the .7z file - a bit different from the post you made).

Check the link in my name to see the problem I'm getting:

Warning: file() [function.file]: URL file-access is disabled in the server configuration in [my server info here] /playground/playlist_rss_with_preroll.php on line 22

Warning: file(http://odeo.com/channel/34348/rss.xml) [function.file]: failed to open stream: no suitable wrapper could be found in [my server info here] /playground/playlist_rss_with_preroll.php on line 22

It doesn't like that I'm trying to link to a file on the very same server? Odd.

var initialPlaylist = "playlist_RSS_with_Preroll.php?ad_location=ad.flv&rssfeed='http://some.com/channel/1234567890/rss.xml";

Seems to be a stray quote mark in there.

Any help is appreciated...looks like I'm almost there!

@digital,

C.R.A.P it's much worse. :|

Because the player parses the 'file' string, looking for a URL that begins with "http://" and for file extensions like ".jpg, .flv, .swf, .mp3" those strings can't be included in the 'file' string.

So if you download: [url=http://willswonders.myip.org:8085/downloads/multiple_playlist.7z] multiple_playlist.7z[/url] there are fixed versions of "playlist_RSS_with_Preroll.php" and "multiple_playlist_text.html" that take care of this issue.

@digital,

If you still get this message with the new code, then there is another problem.

Warning: file() [function.file]: URL file-access is disabled in the server configuration in [my server info here] /playground/playlist_rss_with_preroll.php on line 22

It means that your host has disabled external file access for security reasons. So you can't access an external file from PHP. Some hosts allow cURL access which can be added to the PHP script if you are allowed to access external files through cURL.

It means that your host has disabled external file access for security reasons.

it does indeed look that way. Unfortunately I'm pretty much unable to get my head around the php code necessary to do that. On the off chance that there's another problem, here's the relevant code:

// !!- VERY IMPORTANT -!!
  //   The parameters for "playlist_RSS_with_Preroll.php cannot have file extensions (.flv, .swf)
  //   and the rss feed URL cannot have "http://".
  // "ad.flv" file (you can change "ad" to some other filename)
  //var initialPlaylist = "playlist_RSS_with_Preroll.php?ad_location_flv=ad&feed=some.com/channel/1234567890/rss.xml";
  // "ad.swf" file (you can change "ad" to some other filename)
  var initialPlaylist = "playlist_RSS_with_Preroll.php?ad_location_flv=video&feed=odeo.com/channel/34348/rss.xml";
  // !!- VERY IMPORTANT -!!

and from my playlist rss thing:

// number of items in playlist
$items = 5;

// default ad location
$ad_location = '/home/.caroline/liero116/get-a-bar.com/playground/wp-content/plugins/jw_media_player/video.flv';

// default rss feed:
$rssfeed = 'http://odeo.com/channel/34348/rss.xml';

if ($_REQUEST['ad_location_flv'])
{
  $ad_location = $_REQUEST['ad_location_flv'] . ".flv";
}

if ($_REQUEST['ad_location_swf'])
{
  $ad_location = $_REQUEST['ad_location_swf'] . ".swf";
}

if ($_REQUEST['feed'])
{
  $rssfeed = "http://" . $_REQUEST['feed'];
}

And what I get, as you see in my link, is a player that is functioning, but not listening to the playlist rss file.

Any chance you could code in the curl access with some dummy-proof comments? I know that Wordpress (for example) itself uses curl, so I think users might be comfortable with that if it's built in and explained. Let me know if there's anything I can do on that end.

thanks a million.

@digital,

I think the code is OK. It's functioning on my demo here: [url=http://willswonders.myip.org:8085/php/multiple_playlist_text.html]Multiple Playlist[/url]

Yeah, I can code the cURL access. I've done it for PHP playlist generation somewhere before, so it's just a cut & paste when I find that code.

Have you checked to see if your host allows cURL access to external files?

ok, then it is the code, as I thought.

My host does allow cURL access - I think a lot do (?)

@digital,

ok, then it is the code, as I thought.

Actually, it's your host. :)

My host does allow cURL access - I think a lot do (?)

Most don't. :|

We know how to get around that, but that usually gets the user kicked off the host, so I don't like to encourage that.

hm. well, I suppose that cURL is the way to go. I know that Dreamhost, at any rate, supports it: [url=http://blog.dreamhosters.com/kbase/index.cgi?area=2847]link[/url]

@digital,

Yeah, I'm on it. Should have a cURL option "real soon now". :d

awesome. :d

@digital,

The thing w/cURL.

<?php

// number of items in playlist
$items = 5;

// default ad location
$ad_location = '/Movies/CG_chick_avi_mencoder.flv';

// default rss feed:
$rssfeed = 'http://odeo.com/channel/34348/rss.xml';

// use cURL to retrieve the external RSS feed
$use_cURL = true;

/////////////////////////////// !!- Stay out of here -!! ///////////////////////////////

if ($_REQUEST['ad_location_flv'])
{
 
$ad_location = $_REQUEST['ad_location_flv'] . ".flv";
}

if (

$_REQUEST['ad_location_swf'])
{
 
$ad_location = $_REQUEST['ad_location_swf'] . ".swf";
}

if (

$_REQUEST['feed'])
{
 
$rssfeed = "http://" . $_REQUEST['feed'];
}

if (

$use_cURL)
{
 
$rss = split("\n", getRSS($rssfeed));
}
else
{
 
$rss = file($rssfeed);
}

if (

$rss)
{
 
$count = 0;
 
$first_item = false;
  foreach(
$rss as $data)
  {
   
$data = trim($data);

   

// look for first item
   
if($data == '<item>')
    {
     
$first_item = true;
    }

   

// can't look for elements until first item has been found
   
if($first_item == true)
    {
     
// look for title
      //           <title>Inbox Zero - Google Tech Talk</title>
      //           <title>(.*?)<\/title>
     
if (preg_match('/<title>(.*?)<\/title>/', $data, $match))
      {
       
$title = $match[1];
      }

     

// look for link
      //           <enclosure url="http://odeo.com/show/15872233/4/download/InboxZero-GoogleTechTalk.mp3" type="audio/mpeg" length="42407776"/>
      //           <enclosure url="(.*?)"(.*?)\/>
     
if (preg_match('/<enclosure url="(.*?)"(.*?)\/>/', $data, $match))
      {
       
$link = $match[1];
       
$feeds[$link]['title']  = $title;
      }

     

// look for author
      //           <itunes:author>43 Folders</itunes:author>
      //           <itunes:author>(.*?)<\/itunes:author>
     
if (preg_match('/<itunes:author>(.*?)<\/itunes:author>/', $data, $match))
      {
       
$author = $match[1];
       
$feeds[$link]['author'] = $author;
       
$count++;
      }

      if (

$count > ($items - 1))
      {
        break;
      }
    }
  }
}

// generate playlist
if ($feeds)
{
 
header("content-type:text/xml;charset=utf-8");

  print <<< END_HEADER

<?xml version='1.0' encoding='UTF-8'?>

<playlist version='1' xmlns='http://xspf.org/ns/0/'>
  <trackList>
    <track>
      <creator>Advertiser</creator>
      <title>AD</title>
      <location>{$ad_location}</location>
      <album>preroll</album>
    </track>

END_HEADER;

  while($things = current($feeds))
  {
    $link = key($feeds);
    print <<< END_TRACK
    <track>
      <creator>{$things['author']}</creator>
      <title>{$things['title']}</title>
      <location>{$link}</location>
    </track>

END_TRACK;

    next($feeds);
  }

  print <<< END_FOOTER
  </trackList>
</playlist>

END_FOOTER;
}

function getRSS($rssfeedURL)
  {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $rssfeedURL);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    $rss = curl_exec($ch);

    if (curl_errno($ch))
    {
      trigger_error("cURL Error in playlist_RSS_with_Preroll.php-getRSS: " . curl_error($ch));
      return null;
    }
    curl_close($ch);
    return $rss;
  }

?>

great! it works!

here's a bit of an odd behavior: even with autostart set to false, it seems to autostart sometimes, and not others - completely randomly.

It also doesn't seem to be bringing in the associated image files from the xml feed.

any way of telling it that it's okay to "repeat" (e.g. go onto the next feed item) when it's in this mode, but not when it's playing a single item via javascript?

(oh: if someone wanted to use a .jpg file, or say an .mp3 file for the initial ad, what would be that process? I experimented with a .jpg file by adding the following just before the flv declaration and it didn't seem to like that:

if ($_REQUEST['ad_location_jpg'])
{
$ad_location = $_REQUEST['ad_location_jpg'] . ".jpg";
}

Probably illegal. I do suppose that converting to an .swf would be easy. Not sure why someone would want a .jpg, just envisioning possible extensions of the code. An mp3 file, though, I could see.)

and another oddity - about 1/8 of the time, it'll not load the desired ad+RSS combo, but instead show and play the contents from the preroll feed.

Try hitting my demo site and reloading a few times, you'll see the range of effects.

@digital,

Those aren't bugs, "They're FEATURES !! :d

here's a bit of an odd behavior: even with autostart set to false, it seems to autostart sometimes, and not others - completely randomly.

This, I'll have to check out. ...later

It also doesn't seem to be bringing in the associated image files from the xml feed.

Didn't ask it to; didn't know there were images; can easily be added.

any way of telling it that it's okay to "repeat" (e.g. go onto the next feed item) when it's in this mode, but not when it's playing a single item via javascript?

I can change the player's 'repeat' behavior. How this will affect things is unknown; will have to be tested.

(oh: if someone wanted to use a .jpg file, or say an .mp3 file for the initial ad, what would be that process? I experimented with a .jpg file by adding the following just before the flv declaration and it didn't seem to like that:

The ad playlist system allows three types of <album> elements: preroll, postroll, and overlay. They can be any type of media (with some limitations), so to display an image instead of an SWF, just put it into the playlist in place of the SWF. Same for the MP3. The overlay image stays in the display area (with a close "X" button) while the content plays. The MP3 could have an associated image displayed (haven't tested this combo as a preroll).

Some of the repeat/reload effects (remember, we're thinking FEATURES here :d) come from the way various browsers look in their cache and use old stuff and other malfunctions.

Hello,

I didn't get any output from the preroll and postroll advert in the video player. Could you please tell me more detail regarding this advertisement in the jeoran video player?. If it is possible i would more appriciate for this...

The pre/postroll only worked in the v3.10-v3.12 players.

Hi Youtube,

Can you give me the procedure or step by step installation guide for preroll and postroll in the video player? because it would be helpful to get the final touch in the jeoran FLV player...

Will,

Is there any possible to integrate the advertisement with FLV files in the ASP .NET platform?
can you please tell me more details regaring this?

@Suresh,

Jeroen has removed the preroll/postroll functionality from the latest players. He is working on a new version that will be available mid-march according to his estimates. Until we see the new player, there is no point in putting any effort into preroll/postroll advertising solutions.