Während eines LiveFeed Interpret & Titel aus externer Datei

Hallo an die mAirList Script-Experten - ich brauche mal Euer Schwarmwissen :grinning:

Mein Ziel:
Ich möchte während mAirList ein LiveFeed abgreift und überträgt den aktuellen Interpreten & Titel aus einer externen Datei auslesen und an den Encoder übergeben.

Ist-Status:
Die externe (.txt)-Datei wird vom Zuspieler bei Titelwechsel aktualisiert und auf ein freigegebenes Netzlaufwerk geschrieben. Anhand von einem Code-Beispiel hier im Forum habe ich mir ein Script gebaut, dass mich schon ein gutes Stück weit gebracht hat. Jedoch war das Beispiel wohl für die mAirList Version 6 und verursacht in Version 7 einen Fehler “TBassStreamingEncoder: Access violation at address 0130F077 in module ‘mAirList.exe’. Read of address 00000000

Interpret & Titel werden aber schon richtig aus der Text-Datei gelesen und ich kann diese ins Systemprotokoll schreiben lassen (aktuell nicht im Script eingebaut).

Das Script sieht aktuell so aus:

var
  lastTitle: string;

procedure OnTimer;
var
  sl: TStringList;
  logger: ILogger;
begin
  sl := TStringList.Create;
  try
    sl.LoadFromFile('\\SRV-NAS\Daten\NowPlaying\history.txt');
    if (sl.Count > 0) and (sl[0] <> lastTitle) then 
    begin 
      logger := Instance.GetLogger;
      if Assigned(logger) then
        logger.CurrentTitleLog(nil, '', 0, sl[0]);
      lastTitle := sl[0];
    end;
  finally
    sl.Free;
  end;
end;

procedure OnLoad;
begin
  lastTitle := '';
  EnableTimer(10000); // alle 10 Sekunden
end;

begin
end.

Was mir fehlt:
Ich denke, dass mir nur eine kleine Anpassung des Script fehlt, damit die Daten in v7 an den Encoder übergeben werden. Leider setzen meine Kentnisse im mAirList Scripting an dieser Stelle aus :pensive:

Nice-to-have:
Das i-Tüpfelchen für das Script (welches ich als Hintergrund Script einbinden würde) wäre, wenn es nur dann reagiert, wenn auch tatsächlich gerade ein Live-Feed aktiv ist und bei anderen Elementen im Player das Senden der Daten an den Encoder einfach überspringt (falls möglich).

Freue mich über jeglichen Ansatz, wie ich das Problem lösen kann.

Schon mal Danke und ein schönes restliches WE :hugs:

… und der Fehler verschwindet, wenn Du das Skript außer Betrieb setzt?

Ja. Wenn ich das Script deaktiviere ist das SysLog ohne Fehler.

Hier noch ein vollständiger Screenshot aus dem Log:

Vielleicht hilft das weiter.

In der Version 7 hat sich intern ein bisschen was mit dem Logging verändert.
CurrentTitleLog scheint es nicht mehr zu geben (?)

Du kannst versuchen, dein Skript ähnlich hierzu zu verändern:

Dazu noch folgende Ergänzung:
Das dort im Code genannte

Instance.GetLogger.StartLog(item, 0, '');

benötigt in der v7 noch ein “false” am Ende, also:

Instance.GetLogger.StartLog(item, 0, '', false);
1 Like

Wenn es nur um den Encoder geht, kann man den Titel sehr leicht setzen:

Encoder.SetStreamTitle('blablup', false);

(Mit dem zweiten Parameter kann man eine eventuell eingestellte Verzögerung temporär außer Kraft setzen.)

Wenn es allerdings um die Übergabe an das gesamte Logging-System geht, haben sich die Interna in v7.3 tatsächlich etwas geändert.

Die Methode ILogger.StartLog gibt ein sogenanntes “Logging-Ticket” zurück (in Form einer ILoggingTicket-Referenz), über das zum einen der StartLog-Eintrag erzeugt wird, das aber auch als “Handle” dient, um CurrentTitle-Events auszusenden, während der Player läuft. Und wenn man die Referenz wieder freigibt, wird automatisch der StopLog-Eintrag erzeugt.

Um manuell dort einzugreifen und “Fake-Einträge” zu senden, muss man nun die Methode Inject benutzen, und dort ein vorbereitetes TLoggingEvent übergeben:

https://scripting.docs.mairlist.com/mAirListInterfaces.ILogger.html#Inject
https://scripting.docs.mairlist.com/mAirListInterfaces.TLoggingEvent.html

In dem Event müssen einige Felder gesetzt sein, damit die Logging-Schnittstellen es korrekt verarbeiten:

var 
   event: TLoggingEvent;

begin
  event.Timestamp := now; // Aktuelle Zeit
  event.Scope := lsoCurrentTitle; // Es handelt sich um ein "CurrenTitle"-Event
  event.Region := 0; // Region 0 = auf allen Regionen zu hören = unregionalisiert
  event.ItemType := pitMusic; // Muss zum konfigurierten Filter der Logging-.Schnittstelle passen
  event.CurrentTitle := 'haha'; // Und natürlich der eigentliche Titel
  Logger.Inject(event);
end.
4 Likes

Vielen Dank an Euch beide :upside_down_face:

Aktuell reicht mir die Variante Encoder.SetStreamTitle();

Je nachdem wie sich das Vorhaben weiter entwickelt, werde ich das Logging später mit einbeziehen.

Zum Primärziel haben mich jedenfalls beide Lösungen gebracht :+1: