[This is preliminary documentation and is subject to change]
Introduction
Playlist Templates are what instruct the OtsAV Advanced Playlist Generator in creating playlists or playlist segments.
A playlist is a list of items and/or directives in a specific ordered sequence. The items normally represent items from Ots Album files which exist within your Media Library. Directives may be any valid playlist directives.
A playlist segment is really just a playlist, but it is usually of a very specific length -- often one hour exactly -- and is used as a basic building block for creating larger playlists or daily programming of a radio station.
The Playlist Generator is able to create playlist segments that are exactly one hour (or some other duration) in length. This time is perfectly accurate to within one second of the target time you specify! The way in which OtsAV mixes items is fully taken into account with this technology.
If you have not enabled Scheduling & Logging, then you will not be able to create playlist segments of a very specific time, but will still be able to benefit from Playlist Templates and the power of OMQL and the Media Library.
Basic format
A Playlist Template file is a plain text (ASCII) file that ends with the extension .OTM. Any lines which are blank or which begin with a '#' character are ignored. You can use the '#' to add lines with general comments to the file, without causing any harm to what is interpreted by the Playlist Generator.
Playlist Templates can consist of both global and iteration based options and keywords. A global option is one that is usually specified near the top of the template and applies to the entire template. An iteration-based option is one which forms part of the basic iteration of the template.
Iterations
An iteration is a cycle or loop which is repeated (usually) many times in order to achieve a specifc result. In Ots Playlist Templates, the iteration is an important concept and one that you should try hard to understand.
When the Playlist Generator is generating a playlist, it obeys the format specified within the iteration. When it reaches the end of the iteration, it starts again at the beginning, and continues. The Playlist Generator will not stop adding items to the playlist until it has satisfied the goal it was instructed to achieve, which is specified at the beginning of the template using a global option.
Global options
Option: ~length
The ~length option is specified near the top of a template, before any iteration options are used. The ~length option tells the generator how long it has to keep adding to the playlist. This duration (which equates to playlist time, not actual physical time that it takes to create the playlist) can be specified in items, iterations, hours or minutes. Examples are:
~length items=150
The generated playlist will contain 150 items (directives count as items).
~length minutes=90
The generated playlist will have a playing time of 90 minutes (one and a half hours), or slightly longer, since you can't have half a song.
~length hours=4
As above, but duration is specified in hours instead of minutes.
~length iterations=3
This is similar to 'items=' except that it is based on the iteration within the template rather than an absolute number of items. If your iteration consists of 10 items, and you ask for 3 iterations, then you will end up with a playlist of 30 items.
~length iterations=1, target=60
This is a special mode. In this mode, you get the number of iterations you ask for, as in the last mode. The huge difference is that you are able to specify that you want each iteration to last for the number of minutes specified with the "target=" keyword. One hour (60 minutes) is the usual iteration length that radio stations work with. This mode is extremely powerful because it guarantees (within some constraints) that the songs selected will last for exactly one hour, even taking into account the way OtsAV mixes music, and without having to do any premature fade outs of songs at the end of the hour to make the target time! This allows you to sound just a like a huge commercial station with playlists that have the exact variety and diversity you require, professional sounding mixing, while still timing exactly into the top of the hour for the news, all without you having to manually mess around building playlists, or pulling the calculator out!
Iteration-based options
Option: ~iq
This is the most powerful iteration-based option. ~iq, which stands for "item query" is an option that will expand into a literal item when the playlist is generated. The text that follows the "~iq" is evaluated as an OMQL query. This allows you to unleash the full power of OMQL within the playlist generator. The possibilities are endless!
It is also possible to specify and equals sign (=) and a value immediately after the "~iq" which will result in multiple items being queried against this option / OMQL expression. Some examples:
~iq avail & rating > 0 & (pop | dance) & lastplay > 12 hours & itemsep artist > 20
This will expand into an item from your Media Library which satisfies the specified OMQL query -- that is, it will be "available and have a rating of greater than 0 and be in the pop or dance categories and will not have been played for 12 hours and no other item by the same artist will have been played within the last 20 items"!
~iq=5 avail & rating >= 5
This will expand into 5 items, each of which satisfy the OMQL query, which is that the items will be "available and have a rating which is greater then or equal to 5".
Of course you should read the full OMQL reference for comprehensive details about this powerful query language.
Option: ~priority
This is always in the format of:
~priority lastplay=x, rating=y, random=z
where x, y & z are percentage values between 0 and 100 that represent how much influence is given to the three respective priority areas of item "Last Play" information, item "Rating", and a randomness factor.
This option affects all item queries (IQs) which follow it. Although item queries will always satisfy the hard rules set by the OMQL query itself, there is still a lot of scope for influencing which items are selected. If you use lastplay=100 and rating=10, then the time that an item was last played will have more influence on it being played again than that of its rating. Some examples:
~priority lastplay=80, rating=20, random=100
Very random, but with still a significant chance that items selected will be ones which have not been played for awhile. Rating also exerts a far bit of influence, but no where near that of lastplay information.
~priority lastplay=100, rating=2, random=10
Useful for spots/station IDs. Makes it very unlikely that the same station ID will play twice in a row, while still having some randomness in the selection, and giving some credence to assigned ratings. Note that although the rating and random values seem very low here compared to the lastplay value, that is because the lastplay value is internally scaled over a one month period, and station IDs typically play every hour or so, so we need to boost the lastplay factor by a lot in order for it to come even close to the influence exerted by the other two factors. In fact, we probably should change to rating=1 and random=2, while leaving lastplay=100 !
Option: ~optional
This is always in the format of:
~optional group=x
where x is the number of items which can be skipped in order to help obtain the target length for the iteration.
This option is only relevant if you are using the ~length iterations=x, target=y length mode.
This option allows you to make it possible for the playlist generator to be able to reach a set target length. Assuming your target length is one hour, then it is a good rule of thumb that 15 or 16 songs normally fill an hour. If you made an iteration with 15 IQs (item queries) in it, and were asking the playlist generator to produce iterations which were exactly one hour, then it would probably have no trouble achieving this, provided that you have a decent library of music (more than 2000 songs), and are not being too restrictive with your OMQL queries. However, with having 15 songs hard-scheduled in to the template, you are not leaving the generator with much scope, should it happen to schedule a long song such as Stairway To Heaven, which lasts for almost 8 minutes. If it did schedule this song, and some of the other songs it selects naturally are more on the long side, then it may have trouble squeezing the 15 songs in the hour that you have forced.
This is why you use the ~optional group option. It allows you to mark particular item queries or item references as optional. You are giving the generator permission to drop some or even all of those items completely if it feels it needs to in order to reach the target goal you have set for it.
Normally you would simply precede each optional item with an ~optional group=1, however you may have two or more items which need to remain as a group. For example, you may have a song item that comes after a particular station ID, and if the generator skips the song item, then you need it to skip the preceding station ID as well. When you have an optional group of more than one item, the generator treats those items as a logical group, and will either skip the entire group or include it.
Since an hour normally can contain about 15 songs, you would noramlly have 18 songs in your iteration, with 6 of them set to be optional. This means that you are giving the generator a range of 6 songs to work with, ie. it can generate as few as as 12 and as many as 18. This is a nice range, and means that long songs like Stairway To Heaven are just as able to be accommodated (at the expense of another song possibly being dropped). The playlist segment will still be perfectly timed into one full hour, with to-the-second accuracy!
Direct Ots Album file references
You can include specific items within a template. If you do this, then the specified item will always appear within the position of the iteration that you have referenced it at. This is useful for when you want to play a constant in each iteration, and therefore do not need to use an item query. For example, you may need to play a 10 second news intro jingle each hour at 10 seconds to the hour. You can achieve this by directly referencing the news jingle file. Example:
M:\OtsFiles\Spots\NewsIntro.ots|2
This will play item 2 of the referenced file.
Directives
Directives may also be included within a playlist template, and will result in the specified directive appearing in the generated playlist.
For information on the syntax of specifying directives, create a playlist of directives and export it to an Ots File List (.OFL) file. Right-click on this file and choose Edit. You will then be able to see the syntax for each directive. This exact same syntax is used for specifying directives within a playlist template file. Remember that directives always begin with an at (@) symbol. An example is:
@TimeSync=*:59:50
This will produce a Time Sync directive which matches with every hour at 59 minutes and 50 seconds.
Note: When using the length "target" keyword, for accurately targeted playlist segments, you will want to start each segment (therefore your iteration), with a Time Sync directive. Even though the time of the playlist will be within one second of one hour, having the Time Sync directive allows OtsAV to "clean-up", and remain perfectly in sync with time, rather than having half-a-second here or there accumulating into a larger error. Having the Time Sync will seem unnecessary, as it will always seem to fire at the point when the next song would have naturally played anyway (due to the accurately targeted playlist generation), but as stated, it will stop small errors from accumulating into larger descrepancies.
Conclusion
By harnessing the Media Library, OMQL, Playlist Templates, and Scheduling & Logging, you have a powerful set of tools that allow for anything from the creation of some well-balanced playlists, to full-scale 24/7 intelligent automation!
Playlist Template example:
The following template is a real-life example that has been used in a commercial environment. Of course the category names will probably be different to your own, but the principals remain the same. This example makes use of the Scheduling & Logging functionality, and the "target" keyword and "optional group" options.
# Generate a playlist segment of exactly 1 hour
:-
~length iterations=1, target=60
# Main iteration :-
# sync to top of hour
@TimeSync=*:59:57
# hourly beep
M:\OtsFiles\Main\Spots\HourBeep.ots|1
# news!
@LiveInput=on
@Pause=300
@LiveInput=off
# general spot
~iq avail & spot_gen & lastplay > 30 minutes
# 2 general songs
~iq=2 avail & !spot & rating > 0 & (1970s|1980s|1990s|classic|double)
& itemsep artist > 40 & itemsep title > 40
# 1 optional general song
~optional group=1
~iq avail & !spot & rating > 0 & (1970s|1980s|1990s|classic|double)
& itemsep artist > 40 & itemsep title > 40
# classic spot & song
M:\OtsFiles\Main\Spots\Spots.ots|5
~iq avail & !spot & classic & rating > 0 & itemsep artist
> 40 & itemsep title > 40
# 2 general songs
~iq=2 avail & !spot & rating > 0 & (1970s|1980s|1990s|classic|double)
& itemsep artist > 40 & itemsep title > 40
# 1 optional general song
~optional group=1
~iq avail & !spot & rating > 0 & (1970s|1980s|1990s|classic|double)
& itemsep artist > 40 & itemsep title > 40
# general spot
~iq avail & spot_gen & lastplay > 30 minutes
# 1 general song
~iq avail & !spot & rating > 0 & (1970s|1980s|1990s|classic|double)
& itemsep artist > 40 & itemsep title > 40
# double play, separate by spot
~iq avail & !spot & double & rating > 0 & itemsep artist
> 40 & itemsep title > 40
M:\OtsFiles\Main\Spots\Spots.ots|7
~iq avail & !spot & double & rating > 0 & itemsep artist
= 2 & itemsep title > 40
# 1 general song
~iq avail & !spot & rating > 0 & (1970s|1980s|1990s|classic|double)
& itemsep artist > 40 & itemsep title > 40
# 1 optional general song
~optional group=1
~iq avail & !spot & rating > 0 & (1970s|1980s|1990s|classic|double)
& itemsep artist > 40 & itemsep title > 40
# general spot
~iq avail & spot_gen & lastplay > 30 minutes
# 2 general songs
~iq=2 avail & !spot & rating > 0 & (1970s|1980s|1990s|classic|double)
& itemsep artist > 40 & itemsep title > 40
# 1 optional general song
~optional group=1
~iq avail & !spot & rating > 0 & (1970s|1980s|1990s|classic|double)
& itemsep artist > 40 & itemsep title > 40
# oldie spot & song
M:\OtsFiles\Main\Spots\Spots.ots|6
~iq avail & !spot & 1960s & rating > 0 & itemsep artist
> 40 & itemsep title > 40
# 1 optional
general song
~optional group=1
~iq avail & !spot & rating > 0 & (1970s|1980s|1990s|classic|double)
& itemsep artist > 40 & itemsep title > 40