Ots Media Query Language (OMQL)

Adam Ots - 19 May 2002

[This is preliminary documentation and is subject to change]

 

Introduction

OMQL is a query language developed by Ots Corporation that works in conjunction with the Media Library in OtsAV. With OMQL you can easily and instantly query your Media Library to find all items which satisfy certain criteria. OMQL is both fast and powerful. When combined with Playlist Templates, Directives and the Scheduling & Logging, OMQL is a potent tool that you'll wonder how you ever got by without!

OMQL is expanded and enhanced as necessary. This is simply the first incarnation of the language. Already extremely powerful, the potential for OMQL is enormous.

An OMQL query is a string which may consist of keywords, keyword arguments, logical operators, relational operators, values, categories and parenthesis. Don't worry if you don't know what these things are. This document will attempt to explain all aspects of OMQL.

 

Modes of operation

There are two modes of operation for OMQL. Immediate mode, which is when you enter a query directly into the Media Library input area and press Enter, and run-time mode, which is when an OMQL query is evaluated from within a Playlist Template by the Playlist Generator. Most OMQL keywords can be used in both immediate mode and run-time mode, however there are a couple which do not make sense in immediate mode and are therefore considered invalid within this mode of operation. In the Keyword and keyword argument reference section that outlines all legal OMQL keywords, it is also noted if a given command contains any restrictions upon modes of operation.

 

Case and spacing

Queries are always case-insensitive. You can mix and match lower and upper-case letters without any change in meaning. In addition, spacing is not important, except where it is obviously requried in order to separate two words that would otherwise be interpreted as a single word. Having five spaces between two elements of a query is the same as having a single space. The query interpreter tries very hard to be non-fussy about things like this.

 

Query examples

Often the best way to learn is by example. Following are some simple OMQL query strings, and an explanation of what they would return. First though, it's very helpful to understand what goes on when you submit a query to the Media Library area, either by typing it and pressing Enter, or by selecting it from the drop-down menu, or by clicking one of the button presets. When a query is submitted in immediate mode, the query is evaluated against every single item in your Media Library, and only those items whereby the query evaluates to true are displayed in the Media Library area list. Therefore it acts like a kind of filter, preventing any items from being displayed which do not satisfy the query. Here are some common examples each with an accompanying explanation:

Rock

For this example it is assumed that Rock is a category within the Media Library. Wherever category names appear in an OMQL query, they evaluate to true if the item is a member of the specified category, and false if it is not. Therefore, this query would result in all items which are part of the Rock category being displayed.

Rock or Dance

Rock | Dance

Rock and Dance are both categories. These two queries will display all items that are in either the Rock category or the Dance category (or both). Both queries are identical as the pipe (|) symbol is short-hand for the 'or' logical operator. This query essentially says "Show all items which are in Rock or Dance".

Rock and Dance

Rock & Dance

The ampersand (&) symbol is short-hand for the 'and' logical operator, therefore both of the above queries are identical. This query says "Show all items which are in Rock and Dance". Items which are only in one of the two categories will not be displayed as they do not satisfy the query expression.

(Rock or Dance) and not 1980s

(Rock | Dance) & !1980s

This query shows the use of parenthesis in order to group logic elements, and also introduces the 'not' logical operator. Again, both queries are identical, as the exclamation mark (!) is equivalent to typing the 'not' logical operator. The not operator negates the expression immediately following it, and the parenthesis group several expressions into a single logical element. Therefore this query says "Show all items which are in Rock or Dance, but only if they are not in 1980s".

(!uncat & rating >= 4 & bpm >= 120 & bpm < 140) | Favorite

The uncat, rating and bpm keywords are introduced here. Uncat returns true if the item is not in any categories. Since we are using "!uncat", which is the same as "not uncat", this part of the query is essentially saying "only show items which are in at least one category". Rating and BPM values are both stored in the Media Library and work here as your would expect. In full, this query is saying "Show items which are not uncategorized and which have a Rating of 4 or higher and have a BPM of 120 or higher and have a BPM of less than 140, or, if they are in the Favorite category then show them anyway no matter what".

lastplay unset or lastplay < 2 hours

The lastplay keyword has two formats. You can specify a time value and unit, such as "2 hours", "5 minutes", "44 seconds", "1 month", "27 years", etc, and the expression will evaluate to true only for items which have been played within that timeframe -- since we are using the 'less-than' (<) relational operator. If we used the 'greater-than' operator, then the expression would return true only for items which were last played longer ago than the period of time specified. The second format for the lastplay keyword is to use the 'unset' keyword argument after it, instead of a relational operator and value. "lastplay unset" evaluates to true for items which have never been played. In full therefore, this OMQL query is saying "Show items that have never been played or were played within the last two hours".

 

Reserved words and category names

In a query, if a word is not a keyword or logical operator then it is assumed to be a category name. If a category by that name does not exist, then an error will result. What about if you have a category name which clashes with a reserved keyword? As shown in the examples above, bpm is a keyword. If 'bpm' appears in your query, the OMQL interpreter will think you mean the bpm keyword. If you have a category called 'bpm', you can still reference it -- simply enclose the reference within double quotes, like this: "bpm". Whenever quotation marks are encountered within a query, the text within is assumed to be a reference to a category name. This also makes it possible to have category names which contain spaces or punctuation characters. Consider the following two category names:

Spaced out

You&Me

Ordinarily, it would be impossible to reference these categories within your queries, since Spaced out would be interpreted as the category 'Spaced' with the word 'out' following it. Similarly, it would be impossible to reference You&Me since the ampersand in the middle is a logical operator that means 'and', and would be interpreted as such. The interpreter would see that as saying "Show items that are in the You category and in the Me category". You can get around both of these limitations by surrounding your references to the categories within quotation marks, as follows:

"Spaced out" & "You&Me"

This says "Show items which are in the "Spaced out" category and the "You&Me" category".

Although you can reference category names which contain spaces and punctuation characters, it is much easier -- and you'll probably cause yourself less confusion -- if you stick to calling your categories nice short names which contain no spaces and no punctuation characters, apart from possibly the dash (-) or underscore (_) characters.

 

Logical operator reference

The following logical operators are available for use within OMQL queries between category references or keyword expressions:

&

logical and

and

logical and

|

logical or

or

logical or

!

logical negate

not

logical negate

Please note that logical operators are ordinarily always evaluated from left to right, but may have their evaluation priority influenced by the use of parenthesis around expression segments.

 

Relational operator reference

The following relational operators are available for use within OMQL keywords which expect or can support a relational operator:

=

equal to

==

equal to

!=

not equal to

<>

not equal to

<

less than

<=

less than or equal to

>

greater than

>=

greater than or equal to

 

Time unit reference

The following units of duration are available, and are defined as the specified number of seconds, for use within OMQL keywords which expect or can support a time unit reference:

sec/second/seconds

1 second

min/minute/minutes

60 seconds

hour/hours

3600 seconds

day/days

86400 seconds

week/weeks

604800 seconds

month/months

2628000 seconds

year/years

31536000 seconds

Most keywords have an internal limit to the time duration that may be represented. This is usually 100 years (3153600000 seconds).

 

Keyword and keyword argument reference

avail/available

Evaluates to true if the Ots Album file that the item is contained within is not marked as an unavailable album.

bpm

Can be followed by a relational operator and a numerical value between 0 and 240, or can be followed by the keyword argument 'unset'. Evaluates to true if the expression is true, which is based upon the BPM assigned to the item in the Media Library, or in the case of the 'unset' keyword argument, evaluates to true if the BPM value is flagged as unset. Also note that a logical BPM of 0 is used to flag that an item contains non-musical content, but this is different to the "unset" state.

false

Unconditionally evaluates to false.

itemsep

Note: Not available in immediate mode.

Must be followed by the keyword argument 'artist' or 'title', and then a relational operator and a numerical value between 1 and 64. Evaluates to true if the expression is true, which is based upon items in the playlist above the point of where this item (if selected) would be inserted into the playlist.

Example #1:

itemsep artist > 20

Will result in all items generated with this keyword expression having at least 20 items of spacing between the item and another item further up the playlist by the same artist.

Warning: Can only work with information available in the playlist. If you use this keyword to generate a playlist and ask for item spacing of 64, but there are only 20 items in the playlist at the time when the new playlist segment is generated, then this keyword can not possibly enforce spacing of greater than 20 items.

Example #2:

itemsep artist = 1

Will evaulate to true only for items which are by the same artist as the artist of the item immediately above this item. Useful for forcing a "double-play" (two songs in a row by the same artist). You could even have a special station ID or spot between the two items, and use "itemsep artist = 2" instead (to skip the spot).

lastplay

Can be followed by a relational operator and a numerical value and a time unit, or can be followed by the keyword argument 'unset'. Evaluates to true if the expression is true, which is based upon the time the item was last played as recorded in the Media Library, or in the case of the 'unset' keyword argument, evaluates to true if the item has never been played.

Example:

lastplay >= 12 hours

Will evaluate to true for all items which have not been played for 12 hours or longer, including items which have never been played before.

len/length

Can be followed by a relational operator and a numerical value and a time unit, or optionally can have a keyword argument of 'raw', 'trimmed' or 'effective' appear between the keyword and the relational operator. If no keyword argument is specified, the default of 'trimmed' is assumed. Evaluates to true if the expression is true, which is based upon the length of the item as recorded in the Media Library. 'trim' or 'eff' may be used in place of 'trimmed' and 'effective', respectively.

Example #1:

length >= 180 seconds & length < 181 seconds

Will evaluate to true for all items which have a trimmed length of greater than or equal to exactly 180 seconds and which have a trimmed length of less than exactly 181 seconds. Since 180 seconds is equal to 3 minutes, and the trimmed length value is what is used to generate the lengths shown in the "Len" column display in the Media Library area list, this query will return only items which have exactly 3:00 displayed in the length column of the Media Library area list.

Example #2:

length eff < 5 minutes

Will evaluate to true for items which have an effective length which is less than exactly 5 minutes. The effective length is the length of an item taking mixing into account. It is the length that will be added to the total duration of a playlist if you add that item to it.

rating

Must be followed by a relational operator and a numerical value between 0 and 10. Evaluates to true if the expression is true, which is based upon the rating assigned to the item in the Media Library.

true

Unconditionally evaluates to true.

uncat

Evaluates to true if the item is not contained within any Media Library categories.

.b

Evaluates to true if the item contains a valid beat info chunk with an intro and outro segue, BOTH flagged as active.

.bi

Evaluates to true if the item contains a valid beat info chunk with an intro segue flagged as active.

.bo

Evaluates to true if the item contains a valid beat info chunk with an outro segue flagged as active.

.v

Evaluates to true if the item contains a playable video data chunk that is based upon a full-motion video stream type.

.g

Evaluates to true if the item contains a playable video data chunk with a graphics-based stream type (eg. CD+G).

.k

Evaluates to true if the item has been flagged as Karaoke within the item's ACI chunk.

.cover

Evaluates to true if the item is associated with a displayable album cover image, either explicitly ("From Album: Cover" chunk type) or implicitly (belongs to an album with an "Album Cover" chunk type).