MP3-Lautstärkepegel (mp3gain) auslesen und in bestehende DB schreiben

Hallo mAirlist’ler

Ich erlaube mir, den Thread (http://forum.mairlist.com/index.php/topic,1688.0.html) im Bereich “Feature Requests” nochmals hier hervorzuholen, da der Thread recht alt war und meine Frage zudem nicht wirklich in den Thread dort passt.

Ich habe ein bestehendes MP3-Archiv, angelegt mit mAirListDB und als Backend natürlich pgSQL.
Nun wurde im “alten” Thread von Torben ein Script gepostet, welches aus den MP3-Files den Gain ausliest und dann in der Datenbank überschreibt.

Leider zeigt das Script bei mir mit der mairlist-Version 3.1.7 (Build 958) keine Wirkung.
Kann es sein, dass da was im Quellcode geändert wurde und somit das Script daher nicht mehr funktionsfähig ist?

Hat da jemand Durchblick und könnte der Nachwelt das Script anbieten/umschreiben?

Script:

[code]var
stmt: IZPreparedStatement;
rs: IZResultSet;
ts: TStringList;
i: integer;
pi1, pi2: IFilePlaylistItem;

begin
ts := TStringList.Create;
try

// Fetch all File item IDs - we need to lock the database in order to
// protect the connection
Database(0).BeginRead;
try
  stmt := ImAirListDB(Database(0)).GetConnection.PrepareStatement(
    'SELECT idx FROM items WHERE xmltype=''File'' Limit 50'
  );
  rs := stmt.ExecuteQueryPrepared;
  while rs.Next do
    ts.Add(rs.GetString(1));
finally
  Database(0).EndRead;
end;

SystemLog('Found ' + IntToStr(ts.Count) + ' files.');

for i := 0 to ts.Count - 1 do begin
  // load first item from database
  pi1 := IFilePlaylistItem(Database(0).CreatePlaylistItem(ts[i]));
  SystemLog(pi1.GetFilename);

  try
    // create second item directly from the file, read tags
    //pi2 := IFilePlaylistItem(Factory.CreatePlaylistItemFromFile(pi1.GetFilename, [fitTags]));

pi2 := IFilePlaylistItem(Factory.CreatePlaylistItemFromFile(pi1.GetFilename, [fitNativeTags]));

    // Is the amplification different from the one stored in the database?
    if IAmplifyable(pi1).GetAmplification <> IAmplifyable(pi2).GetAmplification then begin
      SystemLog('Amplification has changed');

      // Copy amplification over to the database item
      IAmplifyable(pi1).SetAmplification(IAmplifyable(pi2).GetAmplification);

      // write changes back to the database
      Database(0).SavePlaylistItem(pi1);
    end;
  except
    SystemLog('Error');
  end;
end;

finally
ts.Free;
end;

end.[/code]

Herzlichen Dank!

Was wird denn im Systemprotokoll ausgegeben?

Das “LIMIT 50” im SQL-Statement kommt mir schon etwas komisch vor.

Das ist der Fall, um nicht die ganzen 9’000 Titel durchs Script zu jagen, wenns dann doch nicht klappt.
Testweise hab ichs auf Limit 50 gesetzt.

Schon hier gehts wohl nicht mehr weiter - ich habe bisschen Mühe mit dem Ausgeben der Daten, um das Debugging zu betreiben:

if IAmplifyable(pi1).GetAmplification <> IAmplifyable(pi2).GetAmplification then begin

Eigentlich müsste es ja an dieser Stelle, wenn man in der DB keine gain-Werte hat, sowieso direkt weiter gehen…
Ausgeben könnte ich den Gain-Wert ja so, oder?

SystemLog('Amplification has changed:' + IAmplifyable(pi2).GetAmplification);

Im system-Log wird lediglich der Dateiname & Pfad angezeigt, aber kein “Amplification has changed”

Ja, ich würde auch mal ein paar zusätzliche Log-Ausgaben einbauen, damit man sieht, was dort passiert.

Allerdings musst du die Amplification explizit in einen String umwandeln, um sie dort auszugeben. Pascal ist leider sehr streng typisiert, ander als z.B. PHP oder JavaScript.

SystemLog('Amplification has changed:' + FloatToStr(IAmplifyable(pi2).GetAmplification));

Habs nun rausgekriegt… Das ist korrekt so, dass nur der MP3-Tag ausgelesen wird, nicht aber der APEv2-Tag, oder?
Habe mit foobar2000 nun den APEv2-Tag testweise ausgelesen und als MP3-Tag wieder geschrieben und so klappts. Suboptimal, aber klappt…

Das ist korrekt. APE liest mAirList nicht. Nur ID3.

Vielen Dank für die rasche Hilfe - klingt schon viel, viel besser und lief schneller als erwartet.

Offtopic:
mAirlist 3 ist genial, jetzt freue ich mich bereits auf Version 4 - bereits angetestet und innert kürzester Zeit fasziniert!

Mit mAirlist 4.0 funktioniert das Script nicht mehr.

Fehlermeldung:

Error running script: [Error] (39:12): Unknown identifier 'IAmplifyable'

Hat sich beim Schritt von Version 3x auf 4 daran was geändert?

Wenn ich mich nicht irre, kannst du das weglassen und nun einfach pi2.GetAmplification schreiben.

Scheint zu passen, jedoch noch das Selbe Problem mit “ImAirListDB”.

Ich schau mir das originale Script gerade nochmal an… In mAirList 4.1 funktioniert das mit dem direkten SQL-Zugriff so nicht mehr. Das muss man alles etwas umschreiben. Ich schau mal, dass ich etwas Zeit dafür finde (aber nicht mehr heute).

Okay, vielen herzlichen Dank - einfach wenn du mal Zeit hast.

Ich erlaube mir, rasch nachzufragen, ob du schon kurz Gelegenheit hattest, hier reinzuschauen.
Ansonsten könnte ich, wenn ich weiss, wie bei mAirlist4 die DB angesprochen wird, selber mal versuchen.