Hallo mairlist Community,
Aktuell arbeite ich an einem Script, das automatisch Stilleelemente abspielt, während wir eine Show über einen externen Player am laufen haben. Warum Stilleelemente? Damit wir Airplays zählen könnnen (und Daten auf der Webseite anzeigen), senden wir die Info über gespielte Elemente per HTTP Post und über Icecast. Nur, die externe Show läuft über einen separaten, von mairlist unabhängigen Player, der nicht von uns programmiert ist. Ergo: wir senden keine Daten der gespielten Songs, was für die Artists ziemlich doof ist, da ihre Airplays so nicht gezählt werden.
Die Lösung also ist, ein Script in mAirlist das diese Info von der URL liest und dann über mAirlist sendet. Es gäb jetzt zwei Möglichkeiten: Entweder direkt per HHTPPost die Daten senden, nur das Problem ist, dann senden wir keine Info per Icecast. Und ich habe auch keine Möglichkeit gefunden, dies direkt in die Icecast Verbindung zu senden die wir mit mAirlist haben.
Deswegen habe ich Variante zwei gewählt: Ein Stilleelement erstellen, Titel und Artist der Elements umbenennen und das dann abspielen. Dann werden die Info an alle Verbindungen die wir in mAirlist haben versendet.
Die Logik läuft so:
- Script prüft, ob die Sendung läuft (Check ob Element mit bestimmter ID aktuell in einem der Player abgespielt wird)
- Falls ja, Datenabfrage der URL
- Stilleelement erstellen und in einem separaten Player abspielen
Jetzt hänge ich aber an mehreren Punkten fest und würde bei euch gerne um Rat fragen:
- Wenn ich das richtig sehe, kann ein Element nur gleichzeitig abgespielt werden, wenn wir im assist Modus sind, nicht im Auto Modus. Kann ich das evtl umgehen und auch im Auto Modus ein zweites Element gleichzeitig abspielen?
- Falls das im Auto Modus nicht geht, vermute ich, dass ich wohl Auto im Script deaktivieren und wieder am Schluss aktivieren muss?
- Wenn ich im Assist Modus ein Element in einem Player abspielen will, dann klappt das iwie nicht immer bzw immer erst beim nächsten Befehl. Kann das daran liegen, dass das Stillelement erst noch fertig im player geladen sein muss bzw noch nicht bereit zum abspielen ist? Welche Vorgehensweise ist hier am Besten?
- Alle Umlaute die ich aus dem XML der URL lese werden zu � und Sonderzeichen werden zu &. Das passiert bereits mit dem HHTPGET Befehl von mAirlist selbst. Das XML ist UTF-8 codiert. Ich vermute mAirlist macht daraus was anderes. Gibt es eine Möglichkeit dies zu verhindern?
Vielen Dank im Voraus für eure Unterstützung!
Hier das aktuelle Script. Der main loop ist zu unterst bei “OnTimer”. Aktuell Endet es mit “CreateSilentItem”, da ich aktuell festhänge wie ich das Element richtig abspielen möchte, entsprechend meine Fragen oben.
(Ps: Die XML Funktionen zum extrahieren der Daten habe ich mir grösstenteils per Deepseek schreiben lassen. Der Rest ist sonst alles von mir.)
var
LastDisplayedTitleArtist: string; // Saved as string that we use to compare: 'Title Artist'
CurrentTitle: string;
CurrentArtist: string;
DataAvailable: boolean;
isProcedureRunning: boolean;
const
TargetDatabaseID = '6123'; // The item we will check if it is running
silentID = '6122'; // This is the Database ID of the silent object we will insert to play
DataURL = ''; // URL with XML data
playerZ = 2; // Player for the Silent objects
procedure OnLoad;
begin
EnableTimer(4000);
end;
function IsShowPlaying: Boolean;
// Return True if one of the players is playing the Swiss Music only show
// We will check this by comparing the Database ID of the show and the currently playing item
var
player: IPlaylistPlayerControl;
CurrentItem: IPlaylistItem;
i: integer;
begin
Result := False;
for i := 0 to CurrentPlaybackControl.GetPlayerCount - 1 do // For all players that we have
begin
player := CurrentPlaybackControl.GetPlayer(i);
if player.GetState = psPlaying then // Is player playing?
begin
CurrentItem := player.GetItem;
// Compare current playing items Database ID with the item we look for
if CurrentItem.GetDatabaseID = TargetDatabaseID then
begin
Result := True;
Exit; // Exit early since we found a match
end;
end;
end;
end;
procedure CreateSilentItem(Title, Artist: String);
// Create the silent object, change the Title and name, then play it
var
item: IPlaylistItem;
begin
item:= Database(0).CreatePlaylistItem(silentID);
item.SetTitle(Title);
item.SetArtist(Artist);
CurrentPlaylist.Insert(0, item);
end;
//
// XML Functions
//
function ExtractAfter(const Source, Search: string; StartPos: Integer): string;
var
PosFound: Integer;
begin
Result := '';
PosFound := Pos(Search, Copy(Source, StartPos, Length(Source) - StartPos + 1));
if PosFound > 0 then
Result := Copy(Source, StartPos + PosFound - 1, Length(Source));
end;
function GetValueBetween(const Source, StartTag, EndTag: string; AfterPos: Integer): string;
var
StartPos, EndPos: Integer;
TempStr: string;
begin
Result := '';
// Get substring starting from AfterPos
TempStr := Copy(Source, AfterPos, Length(Source) - AfterPos + 1);
// Find start tag
StartPos := Pos(StartTag, TempStr);
if StartPos > 0 then
begin
StartPos := StartPos + Length(StartTag);
// Find end tag
EndPos := Pos(EndTag, Copy(TempStr, StartPos, Length(TempStr) - StartPos + 1));
if EndPos > 0 then
Result := Copy(TempStr, StartPos, EndPos - 1);
end;
end;
procedure ExtractXML(XMLContent: string);
var
PresentPos: Integer;
begin
DataAvailable := False; // Disable as long as we don't have clean new data
// Find "present" item
PresentPos := Pos('sequence="present"', XMLContent);
if PresentPos > 0 then
begin
// Extract values and write new data
CurrentArtist := GetValueBetween(XMLContent, '<artist>', '</artist>', PresentPos);
CurrentTitle := GetValueBetween(XMLContent, '<title>', '</title>', PresentPos);
DataAvailable := True; // Re-enable
end;
end;
procedure FetchData;
// Getting the Data off the website and process it
var
XMLdata: string;
begin
XMLdata := HTTPGet(DataURL);
// SystemLog(XMLdata);
ExtractXML(XMLdata);
end;
procedure OnTimer; // Main loop
begin
if IsShowPlaying then
begin
if not isProcedureRunning then begin
SystemLog('Swiss Music Only is running')
isProcedureRunning := True
end;
FetchData; // Fetch XML Data off the website
if DataAvailable then
begin
// Check if the last data we fetched is NOT what we last displayed
if CurrentTitle + CurrentArtist <> LastDisplayedTitleArtist then
begin
CreateSilentItem(CurrentTitle, CurrentArtist)
LastDisplayedTitleArtist := CurrentTitle + CurrentArtist
SystemLog('Swiss Music Only: ' + CurrentArtist + ' ' + CurrentTitle)
end
end
end
else begin
if isProcedureRunning then begin
SystemLog('Swiss Music Only has stopped')
isProcedureRunning := False
LastDisplayedTitleArtist := ''
end;
end;
end;
begin
end.