Hallo,
auch auf die Gefahr hin, mich jetzt lächerlich zu machen, dann wäre dem halt so, wollte ich mal fragen, wie ich bestimmte Parameter von mAirlist an ein anderes Programm übergeben kann um mit diesen Parametern dann in dem zusätzlichen Programm arbeiten zu können.
Kurze Erklärung dazu: Ich möchte einen kleinen Studiomonitor “bauen”, in meinem Fall mit VB, zwar sind meine Kenntnisse in VB jetzt auch nicht auf der Profiebene angesiedelt, aber damit hab ich schon vor einiger Zeit mal gearbeitet und ein wenig ist noch hängen geblieben. Das Fehlende würde ich mir dann wieder durch belesen versuchen anzueignen.
Nun hatte ich gestern schon mal angefangen, den Zustand ob mAirlist gestartet ist oder nicht, erwies sich dabei nun nicht als Problem, jedoch hab ich gerade nicht wirklich einen Ansatzpunkt wie ich weitere Parameter von mAirlist via Script eben an ein zusätzliches Programm zu übergeben.
Es soll sich hier auch logischerweise nicht um einen Grundkurs in Sachen VB oder programmieren handeln, aber vielleicht hat ja jemand einen Tipp, vielleicht auch ein kleines einfaches Beispiel mit dem ich dann weiter machen kann. Ich tüftel mich da gerne rein, bräuchte halt nur mal einen Ansatzpunkt.
Meine erste Idee war, die benötigten Zustände via Script von mAirlist aus in eine *.txt Datei zu speichern und mit dieser dann weiter zuarbeiten. Aber auch hier weiß ich leider nicht, ob es seitens mAirlist möglich ist, eben eine *.txt Datei zu erstellen.
So, jetzt darf von mir aus gerne gelacht werden oder vielleicht auch in kleiner Weise geholfen.
Wie auch immer…
Ich sage schon mal Danke.
Hallo deadpool2016xx,
es wäre schön, wenn Du ein wenig näher erläutern könntest, was Du alles exportieren möchtest. Grundsätzlich wäre die einfachste Methode wohl das http-GET-Logging-Interface. Die verschiedenen Loggingvariablen findest Du hier, und was dort nicht vorhanden ist, ließe sich womöglich per Skript ermitteln und als Runtime-Data übergeben. Oder eben in eine .txt
-Datei loggen. (Vielleicht noch einfacher.)
Ganz und gar nicht lächerliche Grüße
TSD
Hallo Tondose,
ja, die HTTP-GET Variante habe ich aktuell noch, davon möchte aber gerne weg und das Ganze lieber als kleines Programm nebenher laufen lassen. Wäre mit ziemlicher Sicherheit auch Ressourcen schonender. Also im Grunde sollen folgende Parameter übergeben werden:
- ist mAirlist gestartet (erledigt)
- EOF
- Mikrofon an/aus
- Encoder verbunden/getrennt
- Assist oder Automation
ggf. später noch aktueller Titel.
Wie halt schon erwähnt, meine VB Kenntnisse sind eher Anfänger, hatte zwar mal vor Jahren einiges damit zutun, bin dann aber immer mehr davon abgekommen. Daher ist es vermutlich auch gerade etwas schwierig einen Ansatz zu finden, dennoch bin ich auch motiviert genug, mich dann wieder reinzuarbeiten.
Ob mAirlist gestartet ist oder eben nicht hab ich zur Zeit so gelöst
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles timer_all.Tick
p = Process.GetProcessesByName(“mAirList”)
If p.Count > 0 Then
systemon.Text = “System online”
systemon.BackColor = Color.Red
Else
systemon.Text = “System offline”
systemon.BackColor = Color.Lime
End If
End Sub
Beste Grüße
Hier sind zwei Skripte. Dieses hier fragt Auto/Assist, Mikrofon im Encoder, den Encoder selber, Player, Titel und EOF ab:
var
Recurring: boolean;
EOFCount: integer;
EncoderStatus: Array[0 .. 255] of boolean;
procedure OnLoad;
begin
EOFCount := 0;
EnableTimer(1000);
end;
// Automationsmodus überwachen
procedure OnAutomationOn(PlaylistIndex: integer);
begin
SetRuntimeData('Auto', 'Auto');
end;
procedure OnAutomationOff(PlaylistIndex: integer);
begin
SetRuntimeData('Auto', 'Assist');
end;
// Titel und Player überwachen
procedure OnPlayerStart(PlaylistIndex: integer; PlayerIndex: integer;
Item: IPlaylistItem);
begin
SetRuntimeData('Title', Item.GetTitle);
if PlayerIndex = 0 then
SetRuntimeData('Player', 'A')
else if PlayerIndex = 1 then
SetRuntimeData('Player', 'B');
end;
// EOF überwachen
procedure OnPlayerEOFWarning(PlaylistIndex: integer; PlayerIndex: integer);
begin
SetRuntimeData('EOF' + IntToStr(PlayerIndex + 1), 'EOF' + IntToStr(PlayerIndex + 1) +'On');
EOFCount := EOFCount + 1;
SetRuntimeData('EOF', IntToStr(EOFCount));
end;
procedure OnPlayerStop(PlaylistIndex: integer; PlayerIndex: integer;
Duration: TTimeValue; Item: IPlaylistItem);
begin
SetRuntimeData('EOF' + IntToStr(PlayerIndex + 1), 'EOF' + IntToStr(PlayerIndex + 1) +'Off');
EOFCount := EOFCount - 1;
SetRuntimeData('EOF', IntToStr(EOFCount));
end;
// Mikrofon überwachen
procedure OnEncoderInputToggle(Input: TEncoderInput; NewState: boolean);
begin
if Input = eiMic then begin
if NewState then
SetRuntimeData('Mic', 'MicOn')
else
SetRuntimeData('Mic', 'MicOff');
end;
end;
// Encoder überwachen. "On" wird signalisiert, wenn mindestens einer von
// beliebig vielen Encodern aufgeschaltet ist.
procedure OnTimer;
var
Test: boolean;
i, k: integer;
begin
try
for i := 0 to 255 do
begin
if Encoder.GetConnections.GetItem(i).GetState = ecsConnected then
EncoderStatus[i] := true
else
EncoderStatus[i] := false;
end;
except
k := i - 1;
end;
for i := 0 to k do
begin
Test := true;
if NOT EncoderStatus[0] AND (EncoderStatus[i] = EncoderStatus[i + 1]) then
begin
Test := false;
Break;
end;
end;
if Recurring <> Test then
if Test then
SetRuntimeData('Encoder', 'EncOn')
else
SetRuntimeData('Encoder', 'EncOff');
Recurring := Test;
end;
begin
end.
Das zweite schreibt die Daten in ein Textfile, Pfad und Filename sind frei wählbar (innerhalb sinnvoller Grenzen):
const
PATH = 'C:\Path\to\file\'; // <-- Hier den Pfad zum File eintragen.
FILENAME = 'Runtime.txt'; // <-- Hier den Filenamen eintragen.
// Anführungszeichen nicht vergessen!
var
StringList: TStringList;
procedure OnRuntimeDataChange(Key, Value: string);
begin
if (Key = 'Auto')
OR (Key = 'Title')
OR (Key = 'Player')
OR (Key = 'EOF')
OR (Key = 'Mic')
OR (Key = 'Encoder') then
begin
try
StringList := TStringList.Create;
StringList.Add('Auto:' + Chr(9) + GetRuntimeData('Auto'));
StringList.Add('Title:' + Chr(9) + GetRuntimeData('Title'));
StringList.Add('Player:' + Chr(9) + GetRuntimeData('Player'));
StringList.Add('EOF1: ' + Chr(9) + GetRuntimeData('EOF1'));
StringList.Add('EOF2: ' + Chr(9) + GetRuntimeData('EOF2'));
StringList.Add('Mic:' + Chr(9) + GetRuntimeData('Mic'));
StringList.Add('Enc:' + Chr(9) + GetRuntimeData('Encoder'));
StringList.SaveToFile(PATH + FILENAME);
finally
StringList.Free;
end;
end;
end;
begin
end.
Probier mal ein bißchen damit rum.
Geloggte Grüße
TSD
Edit: Hinweis: Mit jeder Änderung eines der Zustände wird das File mit den neuen Daten überschrieben.
Mensch du bist ja der Hammer, das wird ne lange Nacht. Ich danke dir auf jeden Fall für deine Mühe und dein Engagement. Ich werde gleich loslegen mit testen und gebe dann definitiv Rückmeldung.
Nochmal ganz lieben Dank
Also bisher funktioniert alles super. Zustände werden anständig verarbeitet. Habe noch den Artist hinzugefügt, muss jetzt nur mal schauen, was noch was alles übermittelt wird bzw. was man noch übermitteln kann. Weiß nicht ob es da irgendwo eine Liste gibt, aber da fuchse ich mich schon rein und zur Not kann ich ja dann noch mal fragen. Du hast mich auf jeden Fall ein ganzes Stück weiter gebracht.
Dafür noch mal ein ganz liebes Danke.
Na ja, andersherum würde ein Schuh draus: Du überlegst Dir, was alles exportiert werden soll, und dann versuchen wir herauszufinden, wie wir da rankommen. Ich könnte mir zum Beispiel die Restlaufzeit der Player vorstellen, dann würde allerdings die Exportdatei jede Sekunde überschrieben. Ob man das will, muß man sich halt überlegen.
Die „Ist-mAirList-gestartet“-Frage ließe sich übrigens eleganter mit Bordmitteln lösen:
procedure OnLoad;
begin
EOFCount := 0;
EnableTimer(1000);
SetRuntimeData('Prog', 'Up');
end;
procedure OnUnLoad;
begin
SetRuntimeData('Prog', 'Down');
end;
… mit entsprechender Anpassung des Write-Skripts.
Ergänzte Grüße
TSD
Ja, genau, das wäre nämlich mein nächstes Ziel gewesen, zum Beispiel die Restlaufzeit und ggf. die Startzeit mit reinzunehmen. Hatte das gestern schon mal mit StartTime usw probiert, aber ich denke, dass ich da noch einen Denkfehler drin hatte.
Habe dann hier und da noch eine Sache hier im Forum gefunden, die natürlich angepasst werden müsste, da sie noch aus älteren mAirlist Zeiten stammen und sicher so nicht mehr funktionieren.
Ok, ich werde mal, deine Variante probieren bezüglich “Ist-mAirlist-gestartet”
Edit: Oki, Deine Variante funktioniert super!
LG
Da die ganzen Daten ohnehin weiterverarbeitet werden sollen, müßten sie auch nicht von Menschen lesbar sein. Allen Ein/Aus-Zuständen könntest Du im Ein-Zustand lediglich Werte zuordnen, z. B.
Programm: 1
Auto: 2
EOF1: 4
EOF2: 8
Mic: 16
Encoder: 32
Wenn Du diese aufaddierst, brauchst Du nur eine Integer zu übergeben, und Dein VB-Programm weiß sofort Bescheid, was los ist. 43
hieße zum Beispiel: „Programm läuft im Auto-Modus, EOF2 blinkt und Encoder ist an.“ (Stichwort: Stellenwerte).
Binäre Grüße
TSD
Edit: Aufaddieren von Strings (die die Zahlen ja noch sind) mit
StrToInt('<Zahl als String>')
Alles klar, ich mache mich direkt mal ran.
LG
Jetzt wird’s kompliziert. Geht aber:
procedure OnPlayerStart(PlaylistIndex: integer; PlayerIndex: integer;
Item: IPlaylistItem);
begin
SetRuntimeData('Title', Item.GetTitle);
if PlayerIndex = 0 then
begin
SetRuntimeData('Player', 'A');
SetRuntimeData('StartA', FormatDateTime('hh:nn:ss',
CurrentPlaylist.GetMetadata(CurrentPlaylist.IndexOf(Item)).
GetStartTime(sttCalculated)));
end
else if PlayerIndex = 1 then
begin
SetRuntimeData('Player', 'B');
SetRuntimeData('StartB', FormatDateTime('hh:nn:ss',
CurrentPlaylist.GetMetadata(CurrentPlaylist.IndexOf(Item)).
GetStartTime(sttCalculated)));
end;
end;
Ellenlange Grüße
TSD
Das mit der Zeit funktioniert super, damit “procedure OnPlayerStart” nicht doppelt drin ist, hab ich dann einfach die schon vorhandene erweitert.
Werde mich jetzt mal mit “aufaddieren” befassen, mal schauen in wie weit ich das verstanden habe.
LG
Genau, das ginge auch gar nicht, zwei gleiche Prozeduren. Sie war zum Ersetzen gedacht.
In Sachen Laufzeit: Ich hielte es für sinnvoller, die jeweils verbleibende Zeit auszugeben. Dies geht mit dem beigelegten Skript. Das Dateischreib-Skript muß entsprechend geändert werden.
var
Recurring: boolean;
EOFCount: integer;
StartTimeA, StartTimeB: TTimeValue;
ItemA, ItemB: IPlaylistItem;
EncoderStatus: Array[0 .. 255] of boolean;
procedure OnLoad;
begin
EOFCount := 0;
EnableTimer(1000);
end;
// Automationsmodus überwachen
procedure OnAutomationOn(PlaylistIndex: integer);
begin
SetRuntimeData('Auto', 'Auto');
end;
procedure OnAutomationOff(PlaylistIndex: integer);
begin
SetRuntimeData('Auto', 'Assist');
end;
// Titel und Player überwachen
procedure OnPlayerStart(PlaylistIndex: integer; PlayerIndex: integer;
Item: IPlaylistItem);
begin
SetRuntimeData('Title', Item.GetTitle);
if PlayerIndex = 0 then
begin
SetRuntimeData('Player', 'A');
StartTimeA := CurrentPlaylist.GetMetadata(CurrentPlaylist.IndexOf(Item)).
GetStartTime(sttCalculated)
SetRuntimeData('StartA', FormatDateTime('hh:nn:ss', StartTimeA));
ItemA := Item;
end
else if PlayerIndex = 1 then
begin
SetRuntimeData('Player', 'B');
StartTimeB := CurrentPlaylist.GetMetadata(CurrentPlaylist.IndexOf(Item)).
GetStartTime(sttCalculated)
SetRuntimeData('StartB', FormatDateTime('hh:nn:ss', StartTimeB));
ItemB := Item;
end;
end;
// EOF überwachen
procedure OnPlayerEOFWarning(PlaylistIndex: integer; PlayerIndex: integer);
begin
SetRuntimeData('EOF' + IntToStr(PlayerIndex + 1), 'EOF' + IntToStr(PlayerIndex + 1) +'On');
EOFCount := EOFCount + 1;
SetRuntimeData('EOF', IntToStr(EOFCount));
end;
procedure OnPlayerStop(PlaylistIndex: integer; PlayerIndex: integer;
Duration: TTimeValue; Item: IPlaylistItem);
begin
SetRuntimeData('EOF' + IntToStr(PlayerIndex + 1), 'EOF' + IntToStr(PlayerIndex + 1) +'Off');
EOFCount := EOFCount - 1;
SetRuntimeData('EOF', IntToStr(EOFCount));
end;
// Mikrofon überwachen
procedure OnEncoderInputToggle(Input: TEncoderInput; NewState: boolean);
begin
if Input = eiMic then begin
if NewState then
SetRuntimeData('Mic', 'MicOn')
else
SetRuntimeData('Mic', 'MicOff');
end;
end;
// Encoder überwachen. "On" wird signalisiert, wenn mindestens einer von
// beliebig vielen Encodern aufgeschaltet ist.
procedure OnTimer;
var
Test: boolean;
i, k: integer;
begin
try
for i := 0 to 255 do
begin
if Encoder.GetConnections.GetItem(i).GetState = ecsConnected then
EncoderStatus[i] := true
else
EncoderStatus[i] := false;
end;
except
k := i - 1;
end;
for i := 0 to k do
begin
Test := true;
if NOT EncoderStatus[0] AND (EncoderStatus[i] = EncoderStatus[i + 1]) then
begin
Test := false;
Break;
end;
end;
if Recurring <> Test then
if Test then
SetRuntimeData('Encoder', 'EncOn')
else
SetRuntimeData('Encoder', 'EncOff');
Recurring := Test;
// Laufzeiten der Player
if CurrentPlaybackControl.GetPlayer(0).GetState = psPlaying then
SetRuntimeData('RunA', FormatDateTime('nn:ss', StartTimeA +
CurrentPlaylist.GetItem(CurrentPlaylist.IndexOf(ItemA)).
GetEffectivePlaybackDuration / 86400 - Instance.FakeNow))
else
SetRuntimeData('RunA', '00:00');
if CurrentPlaybackControl.GetPlayer(1).GetState = psPlaying then
SetRuntimeData('RunB', FormatDateTime('nn:ss', StartTimeB +
CurrentPlaylist.GetItem(CurrentPlaylist.IndexOf(ItemB)).
GetEffectivePlaybackDuration / 86400 - Instance.FakeNow))
else
SetRuntimeData('RunB', '00:00');
end;
begin
end.
Die Daten hast Du jetzt. Viel Spaß beim Verwursten. Laß dann mal von Deinem Ergebnis hören.
Neugierige Grüße
TSD
Ich gebe mein Bestes und halte dich auf dem Laufenden. Und vielleicht kommt ja noch die ein oder andere Frage. Ich glaube sie wird sicher kommen, denn eine Sache will ich im Moment nicht so recht verstehen, aber dazu später mehr. Muss erst mal was tun hier.
Und ich sags immer wieder, ganz lieben Dank.
LG
1 Like
Kleiner Zwischenstand. Das mit der Restlaufzeit funktioniert nicht ganz so wie gewünscht. Die Restzeit wird angezeigt, es wird auch runtergezählt ABER nur etwa 20 Sekunden lang. Dann stürzt die Anwendung ab mit der Meldung, dass der Prozess nicht auf die *.txt Datei zugreifen kann, da sie von einem anderen Prozess verwendet wird.
Irgendwo vielleicht auch nachvollziehbar, zum einen schreibst mAirlist via Script in 1000 Millisekunden-Schritten die Restzeit in die Datei und zum anderen liest meine VB Anwendung natürlich diese *.txt Datei aus, was eben früher oder später zu Konflikten kommt.
Nun weiß ich nicht, ob es noch andere Möglichkeiten, ich sag mal elegantere, oder ob ich vielleicht auch einfach etwas ist, auf dass man “verzichten” kann.
LG
Na ja, im schlimmsten Falle schreibst Du die Restlaufzeiten einfach in eine andere Datei.
procedure OnRuntimedataChange(Key, Value: string);
begin
if (Key = 'Auto')
OR (Key = 'Mic') then
begin
// mach was
end
else if (Key = 'RunA')
OR (Key = 'RunB') then
begin
// mach was anderes
end;
end;
end;
begin
end.
Achtung: Vor else
steht nie ein Semikolon. Näheres unter delphibasics.co.uk oder hier im Forum unter dem Suchbegriff Scripting-Hilfe:
Geteilte Grüße
TSD
Ja ok, dass mit einer zweiten *.txt Datei wäre natürlich eine Möglichkeit. Im Moment bekomme ich aber nur einen Error in mAirlist. Ich werde aber hier im Forum noch mal schauen, ich meine hier mal was gelesen zu haben, wie man den Fehler deutet usw.
08.04.2020 07:47:42 Fehler Fehler beim Laden des Hintergrund-Scripts C:\*******\mairlist_runtime.mls: [Error] (33:5): Identifier expected
Da stimmt was nicht mit Deinen Semikola bzw. end;
. So müßte es aussehen:
procedure OnRuntimeDataChange(Key, Value: string);
begin
if (Key = 'Auto')
OR (Key = 'Encoder') then
begin
// do something
finally
StringList.Free;
end;
end
else if (Key = 'RunA')
OR (Key = 'RunB') then
begin
// do something else
end;
end;
begin
end.
Was versprichst Du Dir vom vorangestellten leeren String in
StringList.Add('' + GetRuntimeData(' RunA'));
Wenn Du ein Leerzeichen einfügen möchtest, mußt Du es auch reinschreiben:
StringList.Add(' ' + GetRuntimeData(' RunA'));
Pingelige Grüße
TSD
(Man muß da aber auch pingelig sein!)
Hehe, alles gut. Warum ich das da einfach leer lasse ist recht einfach.
In meinem Programm frage ich ab, was in Zeile XY steht. z.B. beim Mikrofon. Zu Anfang stand
Mic: MicOn
drin, jetzt steht halt nur MicOn drin. So hab ich das bei den anderen auch gemacht. Ich denke aber, das wird sich noch ändern, sobald ich mit dem Aufaddieren der Strings klar komme. Hab deinen Scripting-Hilfe Beitrag dazu gefunden, muss es nur noch “verstehen”.
LG