Natürlich funktioniert das nicht. Das Log wird geschrieben und man sieht auch kurz das CMD Fenster aufflackern. mAirlist läuft mit meinen User Credentials und das CMD Fenster auch, ich sehe das Problem gerade nicht, warum kein Befehl abgesetzt wird.
Wenn ich in der Kommandozeile den gleichen Befehl ausführe, funktioniert est.
Vielleicht könnte einer der Admins, den Titel mal ändern in “Ansteuerung des OnAirScreen”
Dann können wir diesen Thread wenigstens noch zur Dokumentation verwenden.
procedure OnLoad;
begin
ShellExecute ('C:\ProgramData\mAirList\6.1\sfk174.exe', 'udpsend 192.168.51.103 3310 "CONF:LED2:autoflash=True"');
ShellExecute ('C:\ProgramData\mAirList\6.1\sfk174.exe', 'udpsend 192.168.51.103 3310 "CONF:CONF:APPLY=TRUE"');
end;
procedure OnOnAir;
begin
ShellExecute ('C:\ProgramData\mAirList\6.1\sfk174.exe', 'udpsend 192.168.51.103 3310 "LED1:ON"');
SystemLog ('C:\ProgramData\mAirList\6.1\sfk174.exe udpsend 192.168.51.103 3310 "LED1:ON"');
end;
procedure OnOffAir;
begin
ShellExecute ('C:\ProgramData\mAirList\6.1\sfk174.exe', 'udpsend 192.168.51.103 3310 "LED1:OFF"');
SystemLog ('C:\ProgramData\mAirList\6.1\sfk174.exe udpsend 192.168.51.103 3310 "LED1:OFF"');
end;
procedure OnPlayerEOFWarning(PlaylistIndex: integer; PlayerIndex: integer);
begin
ShellExecute ('C:\ProgramData\mAirList\6.1\sfk174.exe', 'udpsend 192.168.51.103 3310 "LED2:ON"');
SystemLog ('C:\ProgramData\mAirList\6.1\sfk174.exe udpsend 192.168.51.103 3310 "LED2:ON"');
end;
procedure OnPlayerStop(PlaylistIndex: integer; PlayerIndex: integer; Duration: TTimeValue; Item: IPlaylistItem);
begin
ShellExecute ('C:\ProgramData\mAirList\6.1\sfk174.exe', 'udpsend 192.168.51.103 3310 "LED2:OFF"');
SystemLog ('C:\ProgramData\mAirList\6.1\sfk174.exe udpsend 192.168.51.103 3310 "LED2:OFF"');
end;
procedure OnShutdown; // Sollte den Rechner mit den OnAirScreen herunterfahren, funktioniert bisher aber nicht.
begin
ShellExecute ('C:\ProgramData\mAirList\6.1\sfk174.exe', 'udpsend 192.168.51.103 3310 "CMD:SHUTDOWN"');
SystemLog ('C:\ProgramData\mAirList\6.1\sfk174.exe udpsend 192.168.51.103 3310 "CMD:SHUTDOWN"');
end;
Jetzt möchte ich diese art und Weise: "Altes" ONAIR-Script funktioniert nur noch teilweise Nutzen um den Stream Timer zu starten, wenn mindestens einer der Streams verbunden ist und stoppen wenn alle offline sind.
Ausserdem möchte ich aus meinem Gamepad, eine Funktion triggern. Die soll zum einen, hier einen Befehl absetzen und ebenfalls einen Timer starten und zum anderen den dedizierten “Aircheck” recorder starten.
Warscheinlich kann man den ganzen Spaghetti code da oben auch wieder in eine eigene Procedure verpacken und dann nur noch die Befehle übergeben. Dazu später, ich will erst einmal alle Funktionen überhaupt am laufen haben.
“Vielleicht könnte einer der Admins, den Titel mal ändern in “Ansteuerung des OnAirScreen””
done by Mod (es gibt nur einen Admin hier )
Das eben war nur die Verpackung mit Prozeduren. Jetzt Deine Streamabfrage. Da wir eine procedure OnEncoderStateToggle leider (noch?) nicht besitzen, müssen wir wieder die Timerabfrage bemühen:
const
iMax = 5; // Hier die maximale Senderanzahl einsetzen
IP = '192.168.51.103'; // <-- IP-Adresse
PORT = '3310'; // <-- Port
PATH = 'C:\ProgramData\mAirList\6.1\sfk174.exe'; // <-- Pfad
var
EncoderCount, i: integer;
EcoderState: array[0 .. iMax] of integer;
procedure PostOnAirScreen(Befehl: string);
begin
ShellExecute (PATH, 'udpsend ' + IP + Chr(32) + PORT + Chr(32) + Chr(34) + Befehl + Chr(34));
ShellExecute (PATH, 'udpsend ' + IP + Chr(32) + PORT + Chr(32) + Chr(34) + Befehl + Chr(34));
end;
procedure OnLoad;
begin
EnableTimer(100);
end;
procedure OnTimer;
begin
for i := 0 to iMax-1 do
begin
if (Encoder.GetConnections.GetItem(i).GetState = ecsConnected) then
EncoderState[i] := 1
else
EncoderState[i] := 0;
end;
for i := 0 to iMax-1 do
begin
EncoderCount := 0;
EncoderCount := EncoderCount + EncoderState[i];
end;
if EncoderCount = 0 then
PostOnAirScreen('<Befehl, wenn Streams aus>')
else
PostOnAirScreen('<Befehl, wenn ein Stream an>');
end;
begin
end.
Dieses Skript fragt (wenn es läuft, ist wieder am grünen Tisch entstanden) alle Zehntelsekunde (muß das so oft sein?) den Encoderstatus ab. Ist ein Encoder verbunden, bekommt er eine Eins, wenn nicht, eine Null verpaßt. Dann werden diese Zahlen addiert – sind alle Encoder offline, ist das Ergebnis null und ein enstprechender Befehl für die Shell ergeht. Ist auch nur ein Encoder verbunden, ist das Ergebnis nicht mehr null, ein anderer Befehl ergeht.
(Man könnte das etwas speichersparender programmieren, wenn man wüßte, daß ord(<Boolsche Variable>) funktioniert, das kann ich im Moment aber nicht ausprobieren.)
Ich frage mich gerade was jetzt passier, bzw. was effktiver wäre, wenn ich sowohl den Status der indivduellen Encoder in mAirlist direkt anzeige als auch die gesammlte Übergabe um den Timer zu triggern.
Sollte man einfach 2 Scripte pollen lassen? Oder lieber das Stautsscript so ändern, dass es einen Wert unter “Runtimedata” weg schreibt den das Sceen Script abfragt?
Und nein, es muss nicht so schnell gepollt werden, ich denke 1 Sekunde reicht auch noch komfortabel aus.
Das sieht soweit schon mal wirklich gut aus und funktioniert:
const
iMax = 5; // Hier die maximale Senderanzahl einsetzen
IP = '192.168.51.103'; // <-- IP-Adresse
PORT = '3310'; // <-- Port
PATH = 'C:\ProgramData\mAirList\6.1\sfk174.exe'; // <-- Pfad
var
EncoderCount, i: integer;
EncoderState: array[0 .. iMax] of integer;
procedure PostOnAirScreen(Befehl: string);
begin
ShellExecuteHidden (PATH, 'udpsend ' + IP + Chr(32) + PORT + Chr(32) + Chr(34) + Befehl + Chr(34));
//ShellExecute (PATH, 'udpsend ' + IP + Chr(32) + PORT + Chr(32) + Chr(34) + Befehl + Chr(34));
end;
procedure OnLoad;
begin
// Eigentlich muss das nicht mal bei jedem Ladevorgang neu passieren aber so sind wir sicher, dass da keiner was verfummelt hat
// und man kann relativ komfortabel die Konfiguration anpassen ohne dass man an die eigentliche Anzeige ran muss
PostOnAirScreen('CONF:LED2:autoflash=True'); // Diese Anzeige soll blinken, blinkede Anzeigen sehen immer wichtig aus.
PostOnAirScreen('CONF:LED2:text=EOF'); // Auf dem Button soll EOF stehen.
PostOnAirScreen('CONF:CONF:APPLY=TRUE');
EnableTimer(1000);
end;
procedure OnTimer;
begin
for i := 0 to iMax-1 do
begin
if (Encoder.GetConnections.GetItem(i).GetState = ecsConnected) then
EncoderState[i] := 1
else
EncoderState[i] := 0;
end;
for i := 0 to iMax-1 do
begin
EncoderCount := 0;
EncoderCount := EncoderCount + EncoderState[i];
end;
if EncoderCount = 0 then begin
PostOnAirScreen('AIR4:OFF');
PostOnAirScreen('AIR4:RESET');
end
else
PostOnAirScreen('AIR4:ON');
end;
procedure OnOnAir;
begin
PostOnAirScreen('LED1:ON');
end;
procedure OnOffAir;
begin
PostOnAirScreen('LED1:OFF');
end;
procedure OnPlayerEOFWarning(PlaylistIndex: integer; PlayerIndex: integer);
begin
PostOnAirScreen('LED2:ON');
end;
procedure OnPlayerStop(PlaylistIndex: integer; PlayerIndex: integer; Duration: TTimeValue; Item: IPlaylistItem);
begin
PostOnAirScreen('LED2:OFF');
end;
procedure OnShutdown; // Sollte den Rechner mit den OnAirScreen herunterfahren, funktioniert bisher aber nicht.
begin
PostOnAirScreen('CMD:SHUTDOWN');
end;
begin
end.
Ein paar kleine Schreibfehler aber nicht was derjenige der Softwarefehler lieber mit dem Lötkolben löst, nicht beheben konnte
Da wo AIR4:OFF steht müsste ich eigentlich einen 2. Befehl absetzen AIR4:REST um den Timer wieder auf null zu stellen, das habe ich dann nicht hin bekommen.
In der PostOnAirScreen Prozedur war das absetzen der Befehle doppelt, da weiß ich nicht genau, wo das her kam, ich hatte vorher den Befehl einfach noch mal ins Log geschrieben?
Habe ich hier mal auskommentiert und auch gleich noch zum ShellexecuteHidden gemacht, dann ploppen keine CMD Fenster mehr auf, die auch noch den Fokus haben.
Jetzt muss ich nur noch ein Gamepad Kommandoe hier rein bekommen, was mir den Talk-Timer startet und stopt. Ich könnte ein Bildschirmobjekt schalter damit triggern und ein Script starten, was irgendwas in runtime setzt, geht das irgnedwie direkt? Kann ich einer Fernsteuerung direkt ein Script zuordnen?
Ah, moment, jetzt wo ich hier schreibe: Irgendwas war doch da mal mit eigene Befehle bauen über Hintergrundscripte. Ich bemühe mal die Forensuche.
EDIT: Ich weiß nicht, wie man hier Text durch streicht. Den doppelten befehl habe ich hinbekommen. Oben geändert.
EDIT2: Ich habe versucht, mit diesem Block unterhalb der OnLoad, einen befehl abzusetzen und habe das gloaben Hotkeys zugewiesen, klappt aber nicht.
procedure OnExecuteCommand(Command: string);
begin
if Command = 'MIC OPEN' then begin
PostOnAirScreen('AIR1:ON');
end
else if Command = 'MIC CLOSE' then begin
PostOnAirScreen('AIR1:OFF');
end;
end;
const
iMax = 5; // <-- Maximale Senderanzahl
var
EncoderCount, i: integer;
EncoderState: array[0..iMax] of integer;
procedure OnLoad;
begin
EnableTimer(1000);
end;
procedure OnRuntimeDataChange(Key, Value: string);
begin
end;
procedure OnTimer;
begin
for i := 0 to iMax - 1 do
begin
if (Encoder.GetConnections.GetItem(i).GetState = ecsConnected) then
EncoderState[i] := 1
else
EncoderState[i] := 0;
end;
for i := 0 to iMax - 1 do
begin
EncoderCount := 0;
EncoderCount := EncoderCount + EncoderState[i];
end;
if EncoderCount = 0 then begin
SetRuntimeData('EncoderStatus', '<Befehl, wenn Streams aus>');
//ExecuteCommand('<Befehl, um den Stream Timer zu starten'>); // <-- ??
end
else begin
SetRuntimeData('EncoderStatus', '<Befehl, wenn ein Stream an>');
//ExecuteCommand('<Befehl, um den Stream Timer zu stoppen'>); // <-- ??
end;
end;
begin
end.
Script für OnAirScreen:
const
IP = '192.168.51.103'; // <-- IP-Adresse
PORT = '3310'; // <-- Port
PATH = 'C:\ProgramData\mAirList\6.1\sfk174.exe'; // <-- Pfad
procedure PostOnAirScreen(Befehl: string);
begin
ShellExecute (PATH, 'udpsend ' + IP + Chr(32) + PORT + Chr(32) + Chr(34) + Befehl + Chr(34));
ShellExecute (PATH, 'udpsend ' + IP + Chr(32) + PORT + Chr(32) + Chr(34) + Befehl + Chr(34));
end;
procedure OnLoad;
begin
PostOnAirScreen('CONF:LED2:autoflash=True');
end;
procedure OnOnAir;
begin
PostOnAirScreen('LED1:ON');
end;
procedure OnOffAir;
begin
PostOnAirScreen('LED1:OFF');
end;
procedure OnPlayerEOFWarning(PlaylistIndex: integer; PlayerIndex: integer);
begin
PostOnAirScreen('LED2:ON');
end;
procedure OnPlayerStop(PlaylistIndex: integer; PlayerIndex: integer; Duration: TTimeValue; Item: IPlaylistItem);
begin
PostOnAirScreen('LED2:OFF');
end;
procedure OnRuntimeDataChange(Key, Value: string);
begin
if Key = 'EncoderStatus' then
PostOnAirScreen(Value)
else if Key = 'GamepadStatus' then
PostOnAirScreen(Value);
end;
procedure OnShutdown; // Sollte den Rechner mit den OnAirScreen herunterfahren, funktioniert bisher aber nicht.
begin
PostOnAirScreen('CMD:SHUTDOWN');
end;
begin
end.
Und noch das
Script für Gamepad-Steuerung:
{
Fernsteuer-Befehl für Gamepad: GAMEPAD ON AIR
In diesem Beispiel toggelt der Befehl vom Gamepad ein/aus.
Bei Verwendung von zwei Aktoren Muß das Skript entsprechend
abgeändert werden.
}
var
GamepadOnAirOn: boolean;
procedure OnLoad;
begin
GamepadOnAirOn := false;
end;
procedure OnTimer;
begin
ExecuteCommand('<Was immer es sein soll>');
//Disable Timer; // <-- Falls wiederholend, Zeile auskommentieren
end;
procedure OnRuntimeDataChange(Key, Value: string);
begin
end;
procedure OnExecuteCommand(Command: string);
begin
if NOT GamepadOnAirOn AND (Command = 'GAMEPAD ON AIR') then begin
GamepadOnAirOn := true;
SetRuntimeData('GamepadStatus', '<Steuerbefehl vom Gamepad beim Einschalten>');
//EnableTimer(<Dauer>);
Encoder.GetConnections.GetItem(<Nummer des Aircheck-Recorders>).SetEnabled(true);
end
else if GamepadOnAirOn AND (Command = 'GAMEPAD ON AIR') then begin
GamepadOnAirOn := false;
SetRuntimeData('GamepadStatus', '<Steuerbefehl vom Gamepad beim Ausschalten>');
//DisableTimer; // <-- Kommentierung entfernen, falls wiederholend
Encoder.GetConnections.GetItem(<Nummer des Aircheck-Recorders>).SetEnabled(true);
end;
end;
begin
end.
Was Du genau mit
meinst, ist mir nicht ganz klar. Ich habe mal einen Befehl eingebaut und auskommentiert, außerdem wird das OnAirScreen-Script verständigt.
Die Prozedur
procedure OnRuntimeDataChange(Key, Value: string);
begin
if Key = 'EncoderStatus' then
PostOnAirScreen(Value)
else if Key = 'GamepadStatus' then
PostOnAirScreen(Value);
end;
müßte mal ein Fachmann überprüfen, ob die so richtig ist.
Was für Grüße jetzt eigentlich?
TSD
Edit: Unsere Posts haben sich überschnitten, vielleicht bekommst Du ja die Skripts entsprechend selber hinfummeln.
Durchstreichen geht mit [s] und entsprechendem schließenden Tag.
Der ist auf dem Screenshot im Github nicht zu sehen, das hatte ich nicht auf dem Schirm.
Auf der rechten Seite stehen die LED1 bis 4 auf der linken Seite AIR1 bis 4. Die Timer haben aber alle leicht unterschiedliche Features. Der Talk-Timer (Mic) resetten automatisch beim stoppen, der Stream Timer möchte manuell zurückgesetzt werden.
Der Timer darüber erlaubt es sogar eine Zeit zu setzen und dann rückwärts zu zählen.
Da habe ich momentan noch keine Verwendung dafür, kann es aber auch nicht ausblenden. Die Funktion habe ich in Hardware in meinem Pult…
Da würde mich eher, der laufende Titel noch interessieren, den kann man anstatt der IP Adresse hin schreiben und den folgenden, darunter. Warnmeldungen gibt es auch noch, die man da untern fett hinschreiben kann. Nu muss ich aber erst mal den Rest einbinden.
Doorbell und ARI, habe ich auch noch keine Idee.
Hoffe, das BBQ war gut.
Oh, fällt mir gerade erst auf: Die Wort-Uhr ist ja auch klasse “5 Minuten nach halb 13”
Und wie! Vielleicht sogar zu gut, siehe den anderen Thread …
Aha, dann ist das nichts spezielles, sondern auch nur ein UDP an die bekannte Adresse. Gut.
Die IP-Adresse tritt ohnehin viel zu stark hervor und lenkt ab. Da würde ich ein ganz frisches aschgrau für nehmen.
Pultseitig ist es nur ein Port am Gamepad/Velleman/IO-Warrior. Türseitig habe ich mal für ein bekanntes Lokalradio aus der Region den Empfänger einer Funkklingel umgewidmet. Bei konservativ verdrahteten Klingeln nimmst Du ein paralleles Relais her. Sind Dir die Kabel widerlich, nimmst Du Relais und Funkklingel. Ran an den Lötkolben!
Wo kommt der ARI/Hinztriller her? Hardware? Dann hat der auch einen Schaltausgang. File? Dann ihm beim abspielen eine Aktion zuordnen. Rest wie oben.
Wenn ich nicht gerade Radio mache, bin ich begeisterter Grillsportler. Also das Sportgerät ist bei mir auch des öfteren am Start.
Ich meinte eher, dass ich die Klingel gar nicht brauche und die Anzeige komplett umfunktioniere.
Selbiges wie oben, ich habe keinen, vielleicht aber ein nettes gimmick. Die Audiodatei für einen Hinztriller habe ich mal irgendwo gefunden, sollte noch irgendwo auf meiner Festplatte rumgeistern. Im Moment bleibt es erst mal bei LED3:OFF und LED4:OFF
Das war ja hier nur die Defaultbeschriftung, die man auch ändern kann.
Aber jetzt wo Du es schreibtst müsste ich das eigentlich machen, einfach nur weil’s geht. Webradio mit ARI Signalisierung und Hinztriller.
Mein Pult hat da noch einen Line-Eingang, der keine Bedienelemete hat. Der muss mal für sowas gewesen sein und da hängt gerade nix dran. Wir werden sehen… Also wenn, dann komplett in Hardware.
Hmm, also die eigen gesetzten Fernsteuerbefehle triggern bei mir nicht.
Das was das GamePad mal machen soll habe ich erst mal auf globale Hotkeys gelegt.
{
Fernsteuer-Befehl für Gamepad: GAMEPAD ON AIR
In diesem Beispiel toggelt der Befehl vom Gamepad ein/aus.
Bei Verwendung von zwei Aktoren Muß das Skript entsprechend
abgeändert werden.
}
var
GamepadOnAirOn: boolean;
procedure OnLoad;
begin
GamepadOnAirOn := false;
end;
procedure OnTimer;
begin
//ExecuteCommand('<Was immer es sein soll>');
//Disable Timer; // <-- Falls wiederholend, Zeile auskommentieren
end;
procedure OnRuntimeDataChange(Key, Value: string);
begin
end;
procedure OnExecuteCommand(Command: string);
begin
if NOT GamepadOnAirOn AND (Command = 'GAMEPAD ON AIR') then begin
GamepadOnAirOn := true;
SetRuntimeData('GamepadStatus', 'AIR1:ON');
//EnableTimer(<Dauer>);
SystemLog('GamepadStatus AIR1:ON')
end
else if GamepadOnAirOn AND (Command = 'GAMEPAD OFF AIR') then begin
GamepadOnAirOn := false;
SetRuntimeData('GamepadStatus', 'AIR1:OFF');
//DisableTimer; // <-- Kommentierung entfernen, falls wiederholend
SystemLog('GamepadStatus AIR1:OFF')
end;
end;
begin
end.
Habe ich da noch einen Denkfehler?
An dem Punkt war ich gestern auch schon,Ansteuerung des OnAirScreen (Letzter Code Block) da hatte ich halt noch MIC OPEN und MIC CLOSE drin stehen aber auch da kam nicht mal ein Log Eintrag als ich den gesetzt habe.
Ich bin mir nicht sicher, ob ich das mit der RuntimeData richtig hinbekommen habe. Probiere mal stattdessen TESTBUTTON ON usw.
Evaluierende Grüße
TSD
Ach, und die Geschichte mit GamepadOnAirOn ist nur für toggelnden Betrieb, also beidesmal F11 (siehe Kommentar). Bei F11undF12 eher so:
{
Fernsteuer-Befehl für Gamepad: GAMEPAD ON AIR
In diesem Beispiel toggelt der Befehl vom Gamepad ein/aus.
Bei Verwendung von zwei Aktoren muß das Skript entsprechend
abgeändert werden.
}
procedure OnTimer;
begin
//ExecuteCommand('<Was immer es sein soll>');
//Disable Timer; // <-- Falls wiederholend, Zeile auskommentieren
end;
procedure OnRuntimeDataChange(Key, Value: string);
begin
end;
procedure OnExecuteCommand(Command: string);
begin
if Command = 'GAMEPAD ON AIR' then begin
SetRuntimeData('GamepadStatus', 'AIR1:ON');
//EnableTimer(<Dauer>);
SystemLog('GamepadStatus AIR1:ON');
end
else if Command = 'GAMEPAD OFF AIR')then begin
SetRuntimeData('GamepadStatus', 'AIR1:OFF');
//DisableTimer; // <-- Kommentierung entfernen, falls wiederholend
SystemLog('GamepadStatus AIR1:OFF');
end;
end;
begin
end.
Grmpf, ich frage mich gerade was ich da vorher falsch gemacht habe. Also F12 geht generell nicht, warum auch immer. Jetzt funktioniert auch die übergabe über RuntimeData.
Im else if ist eine klamer zu viel vor dem “then”.
Jetzt müsste ich erst mal wieder weiter kommen.
{
Fernsteuer-Befehl für Gamepad: GAMEPAD ON AIR
In diesem Beispiel toggelt der Befehl vom Gamepad ein/aus.
Bei Verwendung von zwei Aktoren muß das Skript entsprechend
abgeändert werden.
}
procedure OnRuntimeDataChange(Key, Value: string);
begin
end;
procedure OnExecuteCommand(Command: string);
begin
if Command = 'GAMEPAD ON AIR' then begin
SetRuntimeData('GamepadStatus', 'AIR1:ON');
ExecuteCommand ('AIRCHECK OPEN');
ExecuteCommand ('AIRCHECK ON');
end
else if Command = 'GAMEPAD OFF AIR' then begin
SetRuntimeData('GamepadStatus', 'AIR1:OFF');
ExecuteCommand ('AIRCHECK OFF');
ExecuteCommand ('AIRCHECK CLOSE');
end;
end;
begin
end.
Wobei AIRCHECK die Fernsteuer ID ist, die man für as Bildschirmobjekt des Aircheck Recorders vergeben hat. Der Aircheck Recorder ist ein Feature, was für die meisten User nicht zur Home Version dazu gehört. Das erschien mir hier sinnvoller, den Aircheck direkt zu triggern und nicht anhand des RuntimeData Satus aus dem OnAirScreen Script heraus.
Ich habe jetzt das ON-AIR Script, aus dem anderen Beitrag, so angepasst, dass es einfach bei einer bestehenden Verbdindung Den Encoder Count eins hoch zählt und am Ende die RunTimeData aktualisiert. Gleiches habe ich mit mit den Encodern gemacht, die den Status Connecting haben um damit eine Warnmeldung zu triggern.
{
Zwischen die geschweiften Klammern kann der Spickzettel hin, z.B.:
1: SWR, 2: HR, 3: RIAS.
4: NDR, 5: RB; 6: ORF
usw.
}
const
iMax = 4; // Hier die maximale Senderanzahl minus 1 einsetzen
var
EncoderErrorCount,EncoderOldCount,EncoderCount, i: integer;
EncoderName: array[0 .. iMax] of string;
procedure OnLoad;
begin
EncoderName[0] := 's1 live1';
EncoderName[1] := 's1 live2';
EncoderName[2] := 's2 live1';
EncoderName[3] := 's2 live2';
EncoderName[4] := 'Aircheck';
EnableTimer(800);
EncoderOldCount := 0;
end;
procedure OnTimer;
begin
EncoderOldCount := EncoderCount;
EncoderCount := 0;
EncoderErrorCount := 0;
for i := 0 to iMax do
begin
if (Encoder.GetConnections.GetItem(i).GetEnabled = true) then begin
if (Encoder.GetConnections.GetItem(i).GetState = ecsConnected) then begin
ExecuteCommand('ENCODER'+ IntToStr(i) +' TEXT '+ EncoderName[i] +' ON AIR');
ExecuteCommand('ENCODER'+ IntToStr(i) +' BACKGROUNDCOLOR #FF0000');
ExecuteCommand('ENCODER'+ IntToStr(i) +' FONTCOLOR #FFFFFF');
EncoderCount := EncoderCount + 1;
end
else if (Encoder.GetConnections.GetItem(i).GetState = ecsConnecting) then begin
ExecuteCommand('ENCODER'+ IntToStr(i) +' TEXT '+ EncoderName[i] +' !OFF AIR!');
ExecuteCommand('ENCODER'+ IntToStr(i) +' FONTCOLOR #FFFFFF');
ExecuteCommand('ENCODER'+ IntToStr(i) +' BACKGROUNDCOLOR #FF0000');
EncoderCount := EncoderCount + 1;
EncoderErrorCount := EncoderErrorCount + 1;
end
else begin
ExecuteCommand('ENCODER'+ IntToStr(i) +' BACKGROUNDCOLOR #00FF00');
ExecuteCommand('ENCODER'+ IntToStr(i) +' FONTCOLOR #000000');
ExecuteCommand('ENCODER'+ IntToStr(i) +' TEXT '+ EncoderName[i] +' READY!');
end
end
else begin
ExecuteCommand('ENCODER'+ IntToStr(i) +' BACKGROUNDCOLOR #F0F0F0');
ExecuteCommand('ENCODER'+ IntToStr(i) +' FONTCOLOR #848484');
ExecuteCommand('ENCODER'+ IntToStr(i) +' TEXT '+ EncoderName[i] +' AUS');
end;
end;
if EncoderCount = 0 then begin
SetRuntimeData('EncoderStatus', 'false');
end
else begin
SetRuntimeData('EncoderStatus', 'true');
end;
if EncoderErrorCount = 0 then begin
SetRuntimeData('EncoderError', 'WARN:');
end
else begin
SetRuntimeData('EncoderError', 'WARN:Encoder Fehler!');
end;
end;
begin
end.
Das OnAirScreen Script sieth jetzt so aus.
Da ich für diesen Stream Timer 2 Befehle brauche, um ihn zu stoppen habe ich hier noch eine Zwischenwert in die RuntimeData geschrieben und triggere den eigentlichen Befehl im OnAirScreen Script, weshalb hier eine weitere if Schleife her musste.
const
iMax = 5; // Hier die maximale Senderanzahl einsetzen
IP = '192.168.51.103'; // <-- IP-Adresse
PORT = '3310'; // <-- Port
PATH = 'C:\ProgramData\mAirList\6.1\sfk174.exe'; // <-- Pfad
var
i: integer;
EncoderState: array[0 .. iMax] of integer;
procedure PostOnAirScreen(Befehl: string);
begin
ShellExecuteHidden (PATH, 'udpsend ' + IP + Chr(32) + PORT + Chr(32) + Chr(34) + Befehl + Chr(34) + Chr(32) + '-quiet');
//ShellExecute (PATH, 'udpsend ' + IP + Chr(32) + PORT + Chr(32) + Chr(34) + Befehl + Chr(34));
end;
procedure OnLoad;
begin
// Eigentlich muss das nicht mal bei jedem Ladevorgang neu passieren aber so sind wir sicher, dass da keiner was verfummelt hat
// und man kann relativ komfortabel die Konfiguration anpassen ohne dass man an die eigentliche Anzeige ran muss
PostOnAirScreen('CONF:LED2:autoflash=True'); // Diese Anzeige soll blinken, blinkede Anzeigen sehen immer wichtig aus.
PostOnAirScreen('CONF:LED2:text=EOF'); // Auf dem Button soll EOF stehen.
PostOnAirScreen('CONF:CONF:APPLY=TRUE');
PostOnAirScreen('LED1:OFF');
PostOnAirScreen('LED2:OFF');
PostOnAirScreen('LED3:OFF');
PostOnAirScreen('LED4:OFF');
PostOnAirScreen('AIR4:OFF');
PostOnAirScreen('AIR4:RESET');
end;
procedure OnRuntimeDataChange(Key, Value: string);
begin
if Key = 'EncoderStatus' then begin
//SystemLog ('EncoderStatus'+ (Value));
if Value = ('false') then begin
PostOnAirScreen('AIR4:OFF');
PostOnAirScreen('AIR4:RESET');
end
else begin
PostOnAirScreen('AIR4:ON');
end;
end
else if Key = 'GamepadStatus' then begin
PostOnAirScreen(Value);
end
else if Key = 'EncoderError' then begin
PostOnAirScreen(Value);
end;
end;
procedure OnOnAir;
begin
PostOnAirScreen('LED1:ON');
end;
procedure OnOffAir;
begin
PostOnAirScreen('LED1:OFF');
end;
procedure OnPlayerEOFWarning(PlaylistIndex: integer; PlayerIndex: integer);
begin
PostOnAirScreen('LED2:ON');
end;
procedure OnPlayerStop(PlaylistIndex: integer; PlayerIndex: integer; Duration: TTimeValue; Item: IPlaylistItem);
begin
PostOnAirScreen('LED2:OFF');
end;
procedure OnShutdown; // Sollte den Rechner mit den OnAirScreen herunterfahren, funktioniert bisher aber nicht.
begin
PostOnAirScreen('CMD:SHUTDOWN');
end;
begin
end.
Ein erster Test am Wochenende lief sehr gut. Den Mikrofontrigger muss ich noch anlöten aber der Rest funktioniert schon mal ziemlich gut.
Ein Problem habe ich mit dem EOF Trigger.
Das hatten wir schon mal irgendwo im Forum, ich weiß aber gerade nicht mehr wo.
Wenn ich 2 Elemente miteinander verkette, dann löst der EOF Trigger am Ende des ersten Elementes aus, danach erfolgt aber kein Player Stop, weil der Player den nächsten Song einfach nachläd und spielt, EOF blinkt also weiter. Eigentlich ist Player Stop, schon der passende Trigger finde ich, funktioniert aber nur im voll manuellen Betrieb.
Weiterer offener Punkt:
In der mAirlist Home-Studio fehlt mir logging per UDP, ansonsten könnte ich den laufenden und den folgenden Titel einfach von dort an den Screen shicken. Nun muss ich das noch irgendwie in das Script fummeln. Bevor es das logging Interface nativ in mAirlist gab, hat man das doch auch mit Scripts gelöst. Funktionieren die noch? Irgendwo Version 1.x oder 2.x