Difference between revisions of "Metadata Scripts"
m (→iconv) |
|||
(17 intermediate revisions by the same user not shown) | |||
Line 2: | Line 2: | ||
Metadata scripts use LUA as primary language (see http://www.lua.org/). | Metadata scripts use LUA as primary language (see http://www.lua.org/). | ||
− | The source data has to be coded in '''UTF-8'''. | + | The source data has to be coded in '''UTF-8'''. (Since Server 4.1.75/Stream 2.4.12, UTF16 and UTF32 are also accepted). |
− | ===There are | + | ===There are 4 modes:=== |
*Char parsing: a callback is called for each char received | *Char parsing: a callback is called for each char received | ||
*Line parsing: a callback is called for each line received | *Line parsing: a callback is called for each line received | ||
*XML parsing: different callbacks might be called, see below. | *XML parsing: different callbacks might be called, see below. | ||
+ | *JSON parsing: a callback is called after JSON has been parsed ''(Since Stream 3.0.4)'' | ||
− | The script MUST call one of this function depending | + | The script MUST call one of this function depending on the parsing method choose (outside any function). |
*<code>UseCharParser()</code> | *<code>UseCharParser()</code> | ||
*<code>UseLineParser()</code> | *<code>UseLineParser()</code> | ||
*<code>UseXmlParser()</code> | *<code>UseXmlParser()</code> | ||
+ | *<code>UseJsonParser()</code> ''(Since Stream 3.0.4)'' | ||
===Tool functions=== | ===Tool functions=== | ||
====LogInfo==== | ====LogInfo==== | ||
− | Output to the sound4stream log. | + | Output to the sound4stream log for Stream metadata, or the sound4server log for RDS metadata. |
Ex: <code>LogInfo("The value is ", value,"... Continuing.")</code> | Ex: <code>LogInfo("The value is ", value,"... Continuing.")</code> | ||
====SendMetaDataSong [Deprecated] [Stream Only]==== | ====SendMetaDataSong [Deprecated] [Stream Only]==== | ||
− | + | This set the <code>compact_song</code> and <code>url</code> element in the metadata. | |
− | [NOTE: this is a deprecated function: see XML Metadata below for more | + | '''WARNING''': this does not send the metadata immediately, only when the source is disconnected. Use <code>SendMetaNow()</code> to send. |
+ | |||
+ | Since version 2.4.17, this sends the metadata immediately to be compatible with Telos implementations. | ||
+ | |||
+ | [NOTE: this is a deprecated function: see XML Metadata below for more powerful settings] | ||
Ex: <code>SendMetaDataSong(title,"")</code> | Ex: <code>SendMetaDataSong(title,"")</code> | ||
Line 48: | Line 54: | ||
====iconv==== | ====iconv==== | ||
+ | NOTE: Since Server 4.1.75/Stream 2.4.12, the software will try guess the encoding before applying the script. It will always work for UTF8/16/32 encoding, so those are the recommended encodings. In those cases, iconv is useless, unless to convert to ASCII for RDS. | ||
+ | |||
module has been added in Stream 2.4.4 for Linux (and boxes 1.56) and for windows version 2.4.7. You can use it like this:<syntaxhighlight lang="lua"> | module has been added in Stream 2.4.4 for Linux (and boxes 1.56) and for windows version 2.4.7. You can use it like this:<syntaxhighlight lang="lua"> | ||
-- convert the title from iso-8859-1 (Windows latin-1) to utf-8 | -- convert the title from iso-8859-1 (Windows latin-1) to utf-8 | ||
Line 55: | Line 63: | ||
end | end | ||
</syntaxhighlight> | </syntaxhighlight> | ||
+ | |||
+ | ====SendMetaNow==== | ||
+ | Since server 4.1.77 and Stream 2.4.14, you can call <code>SendMetaNow()</code> at any time to send the current metadata. | ||
+ | |||
+ | In Stream, before 2.4.17 it does not compute compact_song automatically. | ||
+ | |||
+ | ====DoNotSendMeta==== | ||
+ | Since server 4.1.83 and Stream 2.4.18, you can call <code>DoNotSendMeta()</code> to cancel metadata update without error. | ||
+ | |||
+ | Before, not setting the metadata was not sending it, but reported an error. | ||
===Callbacks=== | ===Callbacks=== | ||
Line 78: | Line 96: | ||
====OnXMLParsed [XML Mode]==== | ====OnXMLParsed [XML Mode]==== | ||
− | NB: In both Char Mode and Line Mode, it is possible to use the XML parser. | + | In XML mode, the callback OnXMLParsed is called when the XML has been successfully parsed. |
+ | |||
+ | Usually XPath is used to retreive XML data. | ||
+ | |||
+ | Ex:<syntaxhighlight lang="lua"> | ||
+ | UseXmlParser() | ||
+ | function OnXMLParsed() | ||
+ | local descr=XPath('/MyRootNode/MyList/MyElement[1]/@Description') | ||
+ | meta:Add("title", descr); | ||
+ | end | ||
+ | </syntaxhighlight>NB: In both Char Mode and Line Mode, it is possible to use the XML parser. | ||
For that, call the function ParseXML with the XML content as parameter. Ex: <code>ParseXML(mycontent)</code> | For that, call the function ParseXML with the XML content as parameter. Ex: <code>ParseXML(mycontent)</code> | ||
Line 85: | Line 113: | ||
So, it is possible to parse encapsulated XML. | So, it is possible to parse encapsulated XML. | ||
+ | ====OnJSONParsed [JSON Mode]==== | ||
+ | In JSON mode, the callback OnJSONParsed is called when the JSON has been successfully parsed, with the data as a table as parameter. | ||
Ex:<syntaxhighlight lang="lua"> | Ex:<syntaxhighlight lang="lua"> | ||
− | + | UseJsonParser() | |
− | function | + | function OnJSONParsed(js) |
− | + | local artist=js['artist'] | |
− | meta:Add(" | + | local title=js['title'] |
+ | meta:Add("title", title) | ||
+ | meta:Add("artist", artist) | ||
end | end | ||
− | </syntaxhighlight> | + | </syntaxhighlight>NB: In both Char Mode and Line Mode, it is possible to use the JSON parser. |
+ | |||
+ | For that, call the function ParseJSON with the JSON content as parameter. Ex: <code>ParseJSON(mycontent)</code> | ||
+ | |||
+ | This will act exactly the same way as if the JSON content had been received directly. | ||
+ | So, it is possible to parse encapsulated JSON. | ||
===Metadata=== | ===Metadata=== | ||
Metadata is internally stored as XML. | Metadata is internally stored as XML. | ||
Line 100: | Line 137: | ||
The main metadata node is called 'meta'. | The main metadata node is called 'meta'. | ||
+ | |||
+ | The metadata is sent when the source disconnects or when <code>SendMetaNow()</code> is called. | ||
Functions on nodes are: | Functions on nodes are: | ||
− | *node:Add("name", "content") : add a node, with the specified optional content. | + | *node:Add("name", "content") : add a node, with the specified optional content. Returns the new node |
− | *node:AddAttribute("name", "value") : add an attribute to the node. | + | *node:AddAttribute("name", "value") : add an attribute to the node. Returns the node. |
+ | *node:Set("name", "content") : add or replace a node, with the specified optional content. Returns the new node ''(Since Stream 2.4.17/Server 4.1.82)'' | ||
Ex: <code>meta:add("title", mytitle)</code> | Ex: <code>meta:add("title", mytitle)</code> | ||
+ | |||
+ | The usual metadata keys (handled automatically when the protocol allows it) are: | ||
+ | |||
+ | *<code>title</code> : the title of the song | ||
+ | *<code>artist</code> : the artist of the song | ||
+ | *<code>compact_song</code> : a combination of artist and title, generated automatically if missing as <code>artist - title</code> | ||
+ | *<code>url</code> : the album art cover | ||
=Streaming= | =Streaming= | ||
Some protocols have their own XML metadata: | Some protocols have their own XML metadata: | ||
− | *Icecast2 metadata can be set within special node '_ice' | + | *Icecast2 metadata can be set within special node ''''_ice'''<nowiki/>' |
− | *Shoutcast V2 metadata can be set within special node '_shout' | + | *Shoutcast V2 metadata can be set within special node ''''_shout'''<nowiki/>' |
− | *RTMP metadata can be set within special node '_rtmp' | + | *RTMP metadata can be set within special node ''''_rtmp'''<nowiki/>' |
In these cases, all specific data will be added or replace the default generated data. | In these cases, all specific data will be added or replace the default generated data. | ||
+ | ===All streams: meta=== | ||
+ | For the 'meta' node, used (depends on protocol support) automatic items are: | ||
− | + | *"artist" | |
+ | *"title" | ||
+ | *"album" | ||
+ | *<nowiki>"compact_song" : automatically set to "[artist] - [title]" if is not specified. Used by protocols that do not allow separate title/artist and for display in software.</nowiki> | ||
+ | *"next_song" : sub-node for metadata of next playing song. | ||
+ | **"artist" | ||
+ | **"title" | ||
− | + | BUG: before 2.4.17, meta node is cleared only after a disconnect, so using meta:Add will add nodes which will be ignored. | |
− | + | Example:<syntaxhighlight lang="lua"> | |
+ | meta:Add("title",title) | ||
+ | meta:Add("artist",artist) | ||
+ | </syntaxhighlight> | ||
− | + | ===Icecast: _ice=== | |
+ | For the '_ice' node, you can add directly tags. | ||
− | < | + | They will be put on the <code>updinfo</code> line, replacing the default song=XXX |
− | + | Example: To set the artist title only, use:<syntaxhighlight lang="lua"> | |
+ | local ice=meta:Add("_ice") | ||
+ | ice:Add("title",title) | ||
+ | ice:Add("artist",artist) | ||
+ | </syntaxhighlight> | ||
− | + | ===Shoutcast V2: _shout=== | |
+ | For the '_shout' node, you can add directly tags. | ||
− | + | Default is to use TPE1 for artist, TIT2 for title, TABL for album and to set next_song in <extension> <soon> tag. | |
− | + | Example: To set the content type ID3V1 genre code, you can use<syntaxhighlight lang="lua"> | |
+ | local shout=meta:Add("_shout") | ||
+ | shout:Add("TCON","Subgenre"):AddAttribute("v1","24") | ||
+ | </syntaxhighlight>will add: <TCON v1="24">Subgenre</TCON> | ||
− | + | ===MPEG-TS: _id3=== | |
+ | For the '_id3' node, you can add directly tags. | ||
− | + | Those tags will be embed in MPEG-TS as an ID3 PES metadata stream . | |
− | + | Default is to use TPE1 for artist, TIT2 for title. | |
− | + | Example: To set the content type ID3V1 genre code, you can use<syntaxhighlight lang="lua"> | |
− | + | local id3=meta:Add("_id3") | |
− | + | id3:Add("TPE1","Billie Holiday") | |
− | + | id3:Add("TIT2","Strange Fruit") | |
− | + | </syntaxhighlight> | |
− | + | ===RTMP: _rtmp=== | |
− | + | For the '_rtmp' node, all primary level nodes will be added to the <code>onMetadata</code>, using the node name as key, and the node content as value. | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | The top level metadata is ignored if _rtmp exists, but if title is not given in it, it will be set to the top level metadata compact_song (computed automatically from title/artist if missing). | |
− | + | If no _rtmp node is created, then rtmp send all the top level metadata (since 2.4.17). | |
− | + | Example:<syntaxhighlight lang="lua"> | |
+ | local rtmp=meta:Add("_rtmp") | ||
+ | rtmp:Add("mycommand", "This is my command") | ||
− | + | </syntaxhighlight>will add a field with key "<code>mycommand</code>" in the <code>onMetadata</code> notify AMF block. | |
− | + | ===SetAlbumArtURL=== | |
+ | You can also invoke function SetAlbumArtURL(url) with an url or path to the album art image. | ||
− | + | Protocols that support it (currently shoutcast V2) will send the album art to the server. | |
− | + | =RDS= | |
+ | For RDS, you can set the variables you want and then use them in Dynamic RT or Dynamic Labels by putting them between {}. | ||
− | + | For instance, if your script uses <code>meta:Add("title", myvalue)</code> then you can use <code>{title}</code> which will be replaced by the set value, like <code>You are listening to {title}</code>. | |
− | + | There is a special variable <code>DURATION</code> which can be set to limit the display time of the new data. It can be in <code>seconds</code>, or in <code>[hours:]minutes:seconds</code>. | |
− | + | For instance, you can limit the display to 10 seconds with <code>meta:Add("DURATION", 10)</code>. | |
− | + | =Standalone processors= | |
+ | When using sharing to put a source file in Public, it can be accessed locally in <code>/public/</code>. | ||
+ | [[Category:Metadata]] | ||
+ | [[Category:Streaming]] | ||
+ | [[Category:RDS]] |
Latest revision as of 13:41, 15 November 2024
Contents
Common to all
Metadata scripts use LUA as primary language (see http://www.lua.org/).
The source data has to be coded in UTF-8. (Since Server 4.1.75/Stream 2.4.12, UTF16 and UTF32 are also accepted).
There are 4 modes:
- Char parsing: a callback is called for each char received
- Line parsing: a callback is called for each line received
- XML parsing: different callbacks might be called, see below.
- JSON parsing: a callback is called after JSON has been parsed (Since Stream 3.0.4)
The script MUST call one of this function depending on the parsing method choose (outside any function).
UseCharParser()
UseLineParser()
UseXmlParser()
UseJsonParser()
(Since Stream 3.0.4)
Tool functions
LogInfo
Output to the sound4stream log for Stream metadata, or the sound4server log for RDS metadata.
Ex: LogInfo("The value is ", value,"... Continuing.")
SendMetaDataSong [Deprecated] [Stream Only]
This set the compact_song
and url
element in the metadata.
WARNING: this does not send the metadata immediately, only when the source is disconnected. Use SendMetaNow()
to send.
Since version 2.4.17, this sends the metadata immediately to be compatible with Telos implementations.
[NOTE: this is a deprecated function: see XML Metadata below for more powerful settings]
Ex: SendMetaDataSong(title,"")
can be used to answer if in TCP Server mode. Does nothing in other modes.
Ex: print("HTTP/1.1 200 OK\r\n")
XPath
is an XPath parser (see http://en.wikipedia.org/wiki/XPath) to extract XML data. It can be used only in an XML callback.
If an XPath fails, it returns an empty string
Ex: title=XPath("/Output/Current/@Title")
CheckMinVersion
can be used to check is the SOUND4Stream version is enough.
Ex: if CheckMinVersion("1.0.15") then
iconv
NOTE: Since Server 4.1.75/Stream 2.4.12, the software will try guess the encoding before applying the script. It will always work for UTF8/16/32 encoding, so those are the recommended encodings. In those cases, iconv is useless, unless to convert to ASCII for RDS.
module has been added in Stream 2.4.4 for Linux (and boxes 1.56) and for windows version 2.4.7. You can use it like this:
-- convert the title from iso-8859-1 (Windows latin-1) to utf-8
if iconv ~= nil then -- test, so if not implemented will not crash
local cd = iconv.new("utf-8//TRANSLIT//IGNORE", "iso-8859-1")
title = cd:iconv(title)
end
SendMetaNow
Since server 4.1.77 and Stream 2.4.14, you can call SendMetaNow()
at any time to send the current metadata.
In Stream, before 2.4.17 it does not compute compact_song automatically.
DoNotSendMeta
Since server 4.1.83 and Stream 2.4.18, you can call DoNotSendMeta()
to cancel metadata update without error.
Before, not setting the metadata was not sending it, but reported an error.
Callbacks
Any callback function might be defined or not, depending on the wanted use.
OnConnect
When new metadata arrives (wherever it comes from), the script is created.
The callback OnConnect is called with a string parameter indicating the source of connection (might be incomplete)
OnDisconnect
OnDisconnect callback is called at end of metadata arriving (either end of file, or end of connection in TCP server mode).
This happens just before metadata is sent.
OnCharacterReceived [Char Mode]
In char mode, the callback OnCharacterReceived is called with the signed number of the byte received as parameter.
OnLineReceived [Line Mode]
in line mode, the callback OnLineReceived is called with the line received as parameter.
This is called only when received a CR or LF or end of transmission
OnXMLParsed [XML Mode]
In XML mode, the callback OnXMLParsed is called when the XML has been successfully parsed.
Usually XPath is used to retreive XML data.
Ex:
UseXmlParser()
function OnXMLParsed()
local descr=XPath('/MyRootNode/MyList/MyElement[1]/@Description')
meta:Add("title", descr);
end
NB: In both Char Mode and Line Mode, it is possible to use the XML parser.
For that, call the function ParseXML with the XML content as parameter. Ex: ParseXML(mycontent)
This will act exactly the same way as if the XML content had been received directly.
So, it is possible to parse encapsulated XML.
OnJSONParsed [JSON Mode]
In JSON mode, the callback OnJSONParsed is called when the JSON has been successfully parsed, with the data as a table as parameter.
Ex:
UseJsonParser()
function OnJSONParsed(js)
local artist=js['artist']
local title=js['title']
meta:Add("title", title)
meta:Add("artist", artist)
end
NB: In both Char Mode and Line Mode, it is possible to use the JSON parser.
For that, call the function ParseJSON with the JSON content as parameter. Ex: ParseJSON(mycontent)
This will act exactly the same way as if the JSON content had been received directly.
So, it is possible to parse encapsulated JSON.
Metadata
Metadata is internally stored as XML.
So, it is possible to edit it to add some custom properties.
The main metadata node is called 'meta'.
The metadata is sent when the source disconnects or when SendMetaNow()
is called.
Functions on nodes are:
- node:Add("name", "content") : add a node, with the specified optional content. Returns the new node
- node:AddAttribute("name", "value") : add an attribute to the node. Returns the node.
- node:Set("name", "content") : add or replace a node, with the specified optional content. Returns the new node (Since Stream 2.4.17/Server 4.1.82)
Ex: meta:add("title", mytitle)
The usual metadata keys (handled automatically when the protocol allows it) are:
title
: the title of the songartist
: the artist of the songcompact_song
: a combination of artist and title, generated automatically if missing asartist - title
url
: the album art cover
Streaming
Some protocols have their own XML metadata:
- Icecast2 metadata can be set within special node '_ice'
- Shoutcast V2 metadata can be set within special node '_shout'
- RTMP metadata can be set within special node '_rtmp'
In these cases, all specific data will be added or replace the default generated data.
All streams: meta
For the 'meta' node, used (depends on protocol support) automatic items are:
- "artist"
- "title"
- "album"
- "compact_song" : automatically set to "[artist] - [title]" if is not specified. Used by protocols that do not allow separate title/artist and for display in software.
- "next_song" : sub-node for metadata of next playing song.
- "artist"
- "title"
BUG: before 2.4.17, meta node is cleared only after a disconnect, so using meta:Add will add nodes which will be ignored.
Example:
meta:Add("title",title)
meta:Add("artist",artist)
Icecast: _ice
For the '_ice' node, you can add directly tags.
They will be put on the updinfo
line, replacing the default song=XXX
Example: To set the artist title only, use:
local ice=meta:Add("_ice")
ice:Add("title",title)
ice:Add("artist",artist)
Shoutcast V2: _shout
For the '_shout' node, you can add directly tags.
Default is to use TPE1 for artist, TIT2 for title, TABL for album and to set next_song in <extension> <soon> tag.
Example: To set the content type ID3V1 genre code, you can use
local shout=meta:Add("_shout")
shout:Add("TCON","Subgenre"):AddAttribute("v1","24")
will add: <TCON v1="24">Subgenre</TCON>
MPEG-TS: _id3
For the '_id3' node, you can add directly tags.
Those tags will be embed in MPEG-TS as an ID3 PES metadata stream .
Default is to use TPE1 for artist, TIT2 for title.
Example: To set the content type ID3V1 genre code, you can use
local id3=meta:Add("_id3")
id3:Add("TPE1","Billie Holiday")
id3:Add("TIT2","Strange Fruit")
RTMP: _rtmp
For the '_rtmp' node, all primary level nodes will be added to the onMetadata
, using the node name as key, and the node content as value.
The top level metadata is ignored if _rtmp exists, but if title is not given in it, it will be set to the top level metadata compact_song (computed automatically from title/artist if missing).
If no _rtmp node is created, then rtmp send all the top level metadata (since 2.4.17).
Example:
local rtmp=meta:Add("_rtmp")
rtmp:Add("mycommand", "This is my command")
will add a field with key "mycommand
" in the onMetadata
notify AMF block.
SetAlbumArtURL
You can also invoke function SetAlbumArtURL(url) with an url or path to the album art image.
Protocols that support it (currently shoutcast V2) will send the album art to the server.
RDS
For RDS, you can set the variables you want and then use them in Dynamic RT or Dynamic Labels by putting them between {}.
For instance, if your script uses meta:Add("title", myvalue)
then you can use {title}
which will be replaced by the set value, like You are listening to {title}
.
There is a special variable DURATION
which can be set to limit the display time of the new data. It can be in seconds
, or in [hours:]minutes:seconds
.
For instance, you can limit the display to 10 seconds with meta:Add("DURATION", 10)
.
Standalone processors
When using sharing to put a source file in Public, it can be accessed locally in /public/
.