Ansteuerung des OnAirScreen

Wieder einmal vielen Dank, ich brauche noch etwas, bis ich das adaptiere.

Der Stream Timer auf dem OnAirScreen. (unten links)


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.:cut_of_meat::cut_of_meat:

Oh, fällt mir gerade erst auf: Die Wort-Uhr ist ja auch klasse “5 Minuten nach halb 13” :thinking:

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.

if Stunde > 12 then Stunde := Stunde - 12;

Oder hier.

Zeitige Grüße

TSD

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. :smile: Webradio mit ARI Signalisierung und Hinztriller. :rofl:
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.

Das mit dem Encoder Status, wollte ich hier: "Altes" ONAIR-Script funktioniert nur noch teilweise - #27 by shorty.xs einfach mitählen und in die RuntimeData schreiben.
Oder macht es mehr Sinn das noch mal extra laufen zu lassen?

Hinztriller

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 F11 und F12 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.

Danke

Klammer vergessen, wegzumähen, sorry.

Weil der Befehl vielleicht in der Systemsteuerung/Konfiguration versehentlich mit einem führenden Leerzeichen eingetragen ist?

Forschende Grüße

TSD

Sooo! Ich bin einen Schritt weiter.

Das Gamepad Script sieht jetzt so aus:

{

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.

Ja klar. Das hat ja auch nichts mit der udp-Geschichte, sondern direkt mit mAirList zu tun. (Du solltest den Kommentar noch entsprechend abändern.)

Direkte Grüße

TSD

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.


Der Ensprechende Encoder Status der einzelnen Encoder siehr nach wie vor so aus
grafik

Airtcheck Recoder in Action
grafik

Und entsprechend der Stream Monitor mit dem TalkTimer

1 Like

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

Hatte ich schon mal erwähnt, dass die Suchfunktion in diesem Forum Weltlkasse ist? Ich glaube diesen Monat noch nicht.

Ich habe diesen alten Thread ausgeraben: Codebeispiele mAirListScript
und daraus das OnAirScreen Script etwas erweitert.

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
  sl: TStringList;
  pi: IPlaylistItem;
  idx, c, 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
    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 OnPlayerStart(PlaylistIndex: integer; PlayerIndex: integer; Item: IPlaylistItem);

begin
  idx := CurrentPlaylist.IndexOf(item);
  if idx = -1 then begin
    SystemLog('Das war kein Element aus unserer Playlist ...');
    exit;
  end;

  sl := TStringList.Create;
  c := 0;                                                                                                       
  while (idx < CurrentPlaylist.GetCount) and (c < 2) do begin
    pi := CurrentPlaylist.GetItem(idx);
    sl.Add(pi.GetArtist + Chr(32) + '-' + Chr(32) + pi.GetTitle );
    c := c + 1;
    idx := idx + 1;
  end;
  PostOnAirScreen('NOW:' + sl[0] );
  PostOnAirScreen('NEXT:' + sl[1] );
  sl.Free;
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);
procedure OnPlayerStateChange(PlaylistIndex: integer; PlayerIndex: integer; OldState: TPlayerState; NewState: TPlayerState; 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.

Wir haben nun den laufenden Titel und den folgenden Titel gelistet. Müsste man ggf. noch Typfilter einbauen und die Länge begrenzen. Für mich funktioniert das so aber erst mal.

EDIT: Oben war noch ein Copy & Paste Fehler drin.

1 Like

Hi,
da ich null Ahnung vom Coden habe frage ich jetzt einfach mal. Wie genau ist es jetzt möglich den OnAirScreen mit mAirList zu verbinden? Wo packe ich die Scipts hin? Ich steige da einfach nicht dahinter…

LG Gregor

Moin Gregor,
ich war der Meinung, dass in einem der alten Handbücher mehr über die Scripts steht, das ist aber nicht so. Ich werde dazu demnächst mal den Scripting-Kurs von @Tondose erweitern, hier im Forum.

In aller Kürze:
Es gibt im Prinzip 2 Script Typen. Scripts die man aus der Oberfläche von mAirlist heraus ausführt, also über das Menü oder beim starten eines (Audio)Elementes, dass ein Script hinterlegt hat oder beim laden einer Playliste und es gibt noch ein paar weitere Stellen, an denen man gezielt auf ein Script verweist.

Die 2. Variante sind Hintergrundscripte oder früher hießen sie mal Notification-Scripts. Diese werden in einem zentralen Bereich der mAirlist Konfiguration definiert.


Das Verzeichnis, was ich hier gewählt habe um die Scripte zu speichern ist nicht unbedingt die beste Wahl, also nimm das bitte nicht als Vorbild, dazu später mehr.

Diese Scripte laufen, wie der Name vermuten lässt, immer im Hintergrund mit und warten auf gewisse Trigger um etwas auszuführen. Welche Trigger das sind und was dann ausgeführt wird, definierst Du innerhalb des Scriptes. Gerade wenn man noch daran schraubt, ist der Haken “Automatisches neu laden, wenn die Datei sich geändert hat”, Gold wert. So kannst Du Dein Hintergrundscript nämlich während mAirlist läuft, in einem Editor bearbeiten und es wird neu eingelesen, wenn Du es dort gespeichert hast. Sobald dann alles läuft kann man diesen Haken eigentlich raus nehmen und etwas Ressourcen sparen.

Also, wo muss das jetzt hin?
Das spielt genau genommen, keine Rolle, Du musst nur wissen wo Du Deine Sctipt Dateien gespeichert hast und der Windows User, mit dem Du mAirlist ausführst muss natürlich Zugriff darauf haben.
Ein dedizierter mAirlist Ordner unter eigene Dateien, wäre z.B. eine Möglichkeit. Etwa so wie bei der mAirlist DB, im Lokalen Modus. Die DB Datei hast Du ja auch irgendwo abgelegt.

Dann musst Du also nur noch Deine Script Dateien hier eintragen und dann laufen die los.
Im Script musst Du natürlich Die “PATH” Variable anpassen, auf den Verzeichnispfad wo du die "Swiss army Knife.exe hingelegt hast.

sorry dass ich dieses thema wieder öffne bei mir klappt das nicht kann mir jemand helfen vielleicht hat sich da was geändert

Hey @shorty.xs,
könntest du mich mal privat anschreiben?

Beste Grüße

@FlorianG, zur Zeit sind meine Ressourcen für kostenpflichtigen mAirlist Support/ Systmadministration, leider ausgerizt. Wenn ich hier neue Möglichkeiten habe, werde ich das hier gerne kun tuen.

Ansonsten bitte einfach hier den Faden weiterühren, dann haben andre vielleicht auch etwas davon. Gelegentlich schaue ich hier im Forum vorbei.

Ich muss dieses alte Thema noch mal hoch holen mit einer Frage.
Die ansteuerung erfolgt ja hier mit einem externen Tool. Kann ich nicht aus dem Script heraus direkt einen UDP Befehl absetzen?
mAirlist Home-Studio?

Wenn ja wie sähe das dann aus?

1 Like

Here an example of what we are using here.

const
  iMax = 2;                                        
  IP = '10.0.0.7';                          
  PORT = '3310';                                  
  PATH = 'C:\sfk174.exe'; 
  
var
  sl: TStringList;
  pi: IPlaylistItem;
  idx, c, i: integer;
  EncoderState: array[0 .. iMax] of integer;  


procedure PostOnAirScreen(Command: string);
begin
  ShellExecuteHidden (PATH, 'udpsend ' + IP + Chr(32) + PORT + Chr(32) + Chr(34) + Command + Chr(34) + Chr(32) + '-quiet');
 end;

procedure OnLoad;
begin
end;

procedure OnRuntimeDataChange(Key, Value: string);
begin
  if Key = 'EncoderStatus' then begin
    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 OnExecuteCommand(Command: string);
begin
  if Command = 'TALKTIMER START' then begin
    PostOnAirScreen('AIR1:ON');
	end
	else begin
	PostOnAirScreen('AIR1:OFF');
end;
   if Command = 'PHONE ON' then begin
    PostOnAirScreen('AIR2:ON');
	end;
	if Command = 'PHONE OFF' then begin
    PostOnAirScreen('AIR2:OFF');
end;
end;


procedure OnPlayerStart(PlaylistIndex: integer; PlayerIndex: integer; Item: IPlaylistItem);

begin
  idx := CurrentPlaylist.IndexOf(item);
  if idx = -1 then begin
    SystemLog('Niets in de Playlist ...');
    exit;
  end;
  
  sl := TStringList.Create;
  c := 0;                                                                                                       
  while (idx < CurrentPlaylist.GetCount) and (c < 2) do begin
    pi := CurrentPlaylist.GetItem(idx);
    sl.Add(pi.GetArtist + Chr(32) + '-' + Chr(32) + pi.GetTitle );
    c := c + 1;
    idx := idx + 1;
  end;
  if (Item.GetItemType = pitMusic) OR

    (Item.GetItemType = pitDummy) OR

    (Item.GetItemType = pitNews) then  
  PostOnAirScreen('NOW:' + sl[0] );
 sl.Free;
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 OnPlayerStateChange(PlaylistIndex: integer; PlayerIndex: integer; OldState: TPlayerState; NewState: TPlayerState; Item: IPlaylistItem);
begin
  PostOnAirScreen('LED2:OFF');
end;

begin
end.