Ich habe jetzt fast alle meine Scripts fertig um unser aktuelles Playout Programm komplett durch mAirList zu ersetzen.
Automatische Zeitansage funktionniert ja jetzt auch…
Das letzte Script war ein Parser für eine xml Datei um dort die aktuellen Wetterdaten auszulesen und in die Playliste einzufügen.
Wobei sich mir jetzt die Frage stellt ob es eine fertige Funktion gibt wo es (komfortabler) erlaubt die xml Tags auszulesen.
Momentan benutze ich die LoadFromFile Funktion um alle Zeilen in ein Array zu lesen welches dann nach den gewünschten Tags geparsed wird.
Filename : TextFile; als Deklaration geht ja leider nicht.
Bei meinen Versuchen konnte ich aber auch feststellen dass einfache Dephi Funktionen wie Inc(var) nicht von mAirList unterstützt werden.
Gibt es eigentlich eine Liste was man in den Scripts benutzen kann. So langsam bekomme ich (wieder) Übung mit dieser Programmiersprache. Man muss sich nur wieder angewöhnen das begin/end und ; nicht zu vergessen ;D
Ein Script werde ich in den nächsten Tagen noch schreiben welches das Verzeichnis mit den Programmhinweis-Dateien erfasst und dann eines über die Random() Funktion auswählt und in die Playliste schiebt.
Ohne mir jetzt den Wolf zu suchen… gibt es eine Funktion/Befehl welches erlaubt die Dateien in einem Verzeichnis einzulesen? Ansonsten muss ich die Filelist über eine Shell-Funktion erstellen.
var
sl: TStringList;
begin
sl := TStringList.Create;
try
sl.LoadFromFile('bla.txt');
finally
sl.Free;
end;
end.
Wenn es um XML-Dateien geht, kannst du auch den eingebauten XML-/DOM-Parser benutzen. Achtung, du brauchst Build 820, den ich gerade hochgeladen habe; in den älteren fehlte ein Teil der benötigten Definitionen im Script-Interface.
Hier mal ein Beispiel, wie man eine .mlp-Datei lädt und die Titel aller dortdrin befindlichen PlaylistItems ausgibt; einmal von Hand durch das DOM gesucht, und einmal mit XPath (wobei von XPath nur ein paar Basisfunktionen unterstützt werden):
var
doc: IXMLDocument;
i, j: integer;
n, n2: IXMLNode;
nl: IXMLNodeList;
begin
doc := Factory.CreateXMLDocument;
doc.SetPreserveWhitespace(false);
if not doc.Load('d:\temp\test.mlp') then begin
SystemLog('cannot load file');
exit;
end;
// Manuell durch das DOM hangeln
for i := 0 to doc.GetDocumentElement.GetChildNodes.GetLength - 1 do begin
n := doc.GetDocumentElement.GetChildNodes.GetItem(i);
if n.GetNodeName = 'PlaylistItem' then
for j := 0 to n.GetChildNodes.GetLength - 1 do begin
n2 := n.GetChildNodes.GetItem(j);
if n2.GetNodeName = 'Title' then
SystemLog(n2.GetText);
end;
end;
// Alternativ mit XPath
nl := doc.GetDocumentElement.SelectNodes('/PlaylistItem/Title');
for i := 0 to nl.GetLength - 1 do
SystemLog(nl.GetItem(i).GetText);
end.
mAirList verwendet die OmniXML-Bibliothek. Die Pascal-Datei mit der Interface-Definition hänge ich hier mal an. Hinweis: Die property-Einträge funktionieren in Scripts nicht; man muss immer die entsprechenden Get- und Set-Methoden verwenden (GetNodeName und SetNodeName statt property NodeName).
Komme nur kurz auf meine Frage zurück wie man am einfachsten alle Dateien eines Verzeichnisses in einem Array ablegen kann.
Wird eventuell die FindFirst/FindNext/FindClose Funktion unterstützt?
Es geht drum über Random einen Programmhinweis in die Playliste einzufügen.
Ich habe dir in den neuen Build 822 die Funktion “FindFiles” eingebaut, die ein Verzeichnis nach Dateien durchsucht und als Liste zurückgibt. Die Liste ist vom Typ IStrings. Das ist ein Wrapper für eine TStringList, der den Vorteil hat, dass er reference counted ist, also nicht manuell freigegeben werden muss. Wird bei mAirList an allen möglichen Stellen benutzt, zum Beispiel für die Liste der Attribute eines Playlist-Elements.
Hier ein Beispiel für FindFiles:
[code]
var
i: integer;
str: IStrings;
begin
str := FindFiles(‘g:\incoming*.mp3’, true);
for i := 0 to str.GetCount - 1 do
SystemLog(str.GetItem(i));
end.[/code]
Der zweite Parameter gibt an, ob das Verzeichnis rekursiv (true) oder nicht rekursiv (false) durchsucht werden soll.
Noch ein Beispiel: Einfügen einer zufälligen Datei aus einem Verzeichnis in die Playlist:
var
str: IStrings;
begin
str := FindFiles('g:\incoming\*.mp3', false);
CurrentPlaylist.InsertFile(CurrentPlaylist.GetNextIndex, str.GetItem(Random(str.GetCount)));
end.
Übrigens, mein “Reparaturversuch” von GetNextIndex neulich war eher kontraproduktiv. Im Moment kann es sein, dass die Datei ganz oben eingefügt wird, obwohl gerade ein Player spielt. Ich werde das in Build 823 korrigieren.
vielen vielen Dank für dein tolles Support!
Könntest du mir bitte GetNextIndex genauer erklären.
Ich hätte das jetzt (deinem Beispiel entsprechend) folgendermassen in die Playliste eingefügt (so mache ich das momentan mit der Werbung in meinen Tests)
GetNextIndex liefert dir die Stelle zurück, an der das nächste zu spielende Element liegt. Also die Position des ersten noch nicht gespielten und derzeit nicht spielenden Elementes.
Ob du das neue Element jetzt bei 0 (ganz oben) oder am GetNextIndex einfügst, spielt für das Ergebnis keine Rolle - die Automation sucht sich eh immer das oberste noch nicht gespielte Element raus, hält sich also im Zweifel nicht an die Reihenfolge in der Playlist. Aber am GetNextIndex einzufügen ist halt “hübscher”, weil man auch optisch genau die Reihenfolge sieht, in der die Sachen gespielt werden.
Der vermeintliche Bugfix, der jetzt wieder rückgängig gemacht wurde, sorgte dafür, dass GetNextIndex manchmal fälschlicherweise 0 zurückgegeben hat.
Stimmt dass es manchmal nicht direkt ersichtlich ist welches das nächste Element in der Playlist ist das gespielt wird.
Im “unattended” Automode ist das aber nicht wirklich wichtig.
Ich denke dass ich jetzt alles mal soweit zusammen habe und kann jetzt erst mal alles so testen ob das Ergebnis das Gleiche ist als bei unserm bestehenden Playout System.
Ausser für die “Overlap”-Funktion wo ich noch keine Lösung für gefunden habe.
Start Next muss ja über ein Script ausgeführt werden oder habe ich das falsch verstanden.
Und bei StartNext wird der laufende nicht ausgefadet? (Nur interessehalber)
Scripting nutzt mir hier (wahrscheinlich) nix. Was ich brauche ist dass mAirList im AutomationMode NIE ausfadet und nur bei EOF - x Sekunden den nächsten Player starten.
Also eine Funktion wie in diesem Thread bereits gefordert: http://forum.mairlist.com/index.php/topic,1229.0.html
Der Hintergrund ist dass wir unsere Titel nur minimal überblenden; also quasi voll ausspielen (wir dürfen das hier in Luxemburg)
Deshalb verzichten wir auch auf Cue-Out Punkte, etc…
Alle unsere Titel sind getrimmt auf maximal 500ms Stille am Ende des Tracks und so soll beispielsweise 1,5 Sekunden vor EOF der neue Titel starten ohne den laufenden auszufaden. Der ist ja ohnehin bereits im Ausfaden ausser es ist einer der wenigen wo cold/dry endet. (Dazu habe ich noch eine andere Frage wenn dies geklärt ist)
Ich hoffe ich konnte das jetzt genau genug erklären…
Nein, “Start Next” ist einer der Cue-Punkte, die du im PFL-Dialog setzen kannst. Funktioniert wie Fade Out, blendet aber den vorigen Titel nicht aus.
Wie wäre es, wenn du einfach alle Fade-Out-Punkte löschst (und vom Auto Cue keine neuen erstellen lässt) Dann blendet mAirList nie aus, sondern spielt bis zum Ende. Dann ggf. noch Start-Next-Punkte setzen.
aber ich kann unmöglich bei über 50.000 Titel den Start Next (manuell) setzen.
Auto-Cue ist deaktiviert. Demnach sind auch keine Fade-Out Punkte vorhanden.
Momentan spielt mAirList die Titel komplet aus und startet dann erst den nächsten.
Wie kann man den Start Next jetzt automatisch setzen? Irgendwie fehlt mir hier der entscheidende Hinweis…
EDIT: Also was ich brauche wäre eine “Auto Start Next” Funktion zum anhaken in der Config, so wie die Auto-Cue Funktion.
Habe mir folgendes überlegt. Ich konvertiere ja unsere Playlists vom xml Format des jetztigen Playout-Systems ins mAirList mlp Format.
Es wäre ein leichtes pro Element in der Playlist folgendes mit einzufügen:
// Entfernen Sie die FadeOut Cue-Punkt (setzen Sie ihn auf Null)
activeItem.SetCuePosition(ptFadeOut, 0);
// Cue-Punkte sind relativ zu BOF, so fügen wir die CueIn Cue-Point-Wert um die effektive Dauer
activeItem.SetCuePosition(ptStartNext,
activeItem.GetEffectivePlaybackDuration
+ activeItem.GetCuePosition(ptCueIn)
- SecondsToTimeValue(2));
[quote=“Cad, post:14, topic:7006”][code]
// Cue-Punkte sind relativ zu BOF, so fügen wir die CueIn Cue-Point-Wert um die effektive Dauer
activeItem.SetCuePosition(ptStartNext,
activeItem.GetEffectivePlaybackDuration
activeItem.GetCuePosition(ptCueIn)
SecondsToTimeValue (2));
[/code][/quote]
That’s exactly the same solution that Serge had guessed already
[quote=“Torben, post:15, topic:7006”][quote=“Cad, post:14, topic:7006”][code]
// Cue-Punkte sind relativ zu BOF, so fügen wir die CueIn Cue-Point-Wert um die effektive Dauer
activeItem.SetCuePosition(ptStartNext,
activeItem.GetEffectivePlaybackDuration
activeItem.GetCuePosition(ptCueIn)
SecondsToTimeValue(2));
[/code][/quote]
That’s exactly the same solution that Serge had guessed already
as GetEffectivePlaybackEnd = GetEffectivePlaybackDuration - GetCuePosition(ptCueIn). ???[/quote]
(Sorry, but I have to write this in English!)
Correct explanation ;D, but I’m sure you meant:
GetEffectivePlaybackEnd = GetEffectivePlaybackDuration + GetCuePosition(ptCueIn)
If your version was correct, and (for example) CueIn=0’02" and GetEffectivePlaybackDuration=1’58", then in your version, GetEffectivePlaybackEnd=1’56" which is obviously not correct. In this example, GetEffectivePlaybackEnd should be 2’00", unless I very badly misunderstand all this. (?)
Ich hätte da noch 'ne kleine Frage wo ich jetzt nicht dahinterkomme…
CurrentPlaylist.InsertFile(x, 'filename');
wenn ich die .chm durchforste ist bei “CurrentPlaylist” die Klasse “IPlaybackControl” als Referenz angegeben.
Bei “IPlaybackControl” gibt’s aber dann wieder keine Methode “InsertFile” ???
Die ist bei “IPlayList” gelistet.
Wie hängt das zusammen?
(Was ich suche ist eine Methode wie “SetTitle” aber halt um das Icon anzugeben wenn man ein Element in die Playliste per Script einfügt. “SetIcon” habe ich jetzt nicht gefunden)
Das Stichwort lautet: Klassenhierarchie (oder hier genauer: Interfacehierarchie). IPlaybackControl ist von IActivePlaylist abgeleitet, das wiederum von IPlaylist abgeleitet sind. Daher erbt IPlaybackControl alle Methoden von IPlaylist, auch wenn das in der CHM-Datei leider so nicht ersichtlich ist. Das Tool, was ich für die Erstellung verwende, fügt leider keine entsprechenden Links ein. Du siehst nur unter dem Punkt “Class Hierarchy”, von welchem Interface das aktuell dargestellte abgeleitet ist. Außerdem gibt es im Inhalt als zweites von oben den Punkt “_Class Hierarchy”, da bekommt man eine baumartige Darstellung.