Audio mit variabler Dauer am Ende immer um 3 sec kürzen

Ähnlich wie eine Nachrichtendatei habe ich ein Audiofile, das ich regelmäßig neu bekomme (Download).

Diese Datei muss ich jeweils am Ende um 3 sec kürzen.

Zum Beginn ist das ja kein Problem. Aber wie sage ich mAirlist, dass er am Ende des Audiofiles mit unterschiedlicher Länge, jeweils die letzten 3 sec nicht spielen soll?

DANKE

Geht leider nicht.

Danke für die schnelle Antwort…

Vielleicht für den einen oder anderen interessant. Wir haben da eine Lösung, mittels batch und der Aufgabenplanung realisiert.

mix sox (http://sox.sourceforge.net) kann man Dateien vom Ende her schneiden. Einzigster Nachteil ist, es kann nicht mit mp3 Dateien umgehen. Desswegen wird zunächst mittels ffmpeg (https://www.ffmpeg.org) eine wav erstellt, die sox dann schneidet und anschließend ffmpeg wieder in eine mp3 umwandelt.

Jetzt könnte man meinen die Audiodatei ist vollends zerstört durch das hin und her umgewandle. Das Ergebnis ist aber völlig OK.

@Echo off

:: Umwandeln der mp3 in wav
ffmpeg -i datei.mp3 datei.wav

:: Original mp3 löschen
del datei.mp3

:: Die letzten 3 Sekunden der wav werden wegschneiden
sox datei.wav datei_neu.wav reverse trim 3 reverse

:: Original wav löschen
del datei.wav

:: Umwandeln der mp3 in wav
ffmpeg -i datei_neu.wav datei.mp3

:: Original wav löschen
del datei_neu.wav

end
2 Likes

Wann sollte denn die Kürzung erfolgen? Wenn sich das Audio (schon) in der Playlist befindet, ginge das mittels Skript schon (Stichwort: Cue-out-Marker verschieben).

Das klingt spannend.

Das ganze steckt in einem Container und kurz vor vor dem abspielen läd mAirlist die Datei vor und berechnet ja auch die tatsächliche Länge neu. Jetzt erst müsste der “Cue out” verschoben werden.

Wie kann man das realisieren?

Vielleicht so (nicht getestet):

procedure OnPlayerStart(PlaylistIndex: integer; PlayerIndex: integer; Item: IPlaylistItem);
var
  i: integer;
  Cue: TTimeValue;
  pi: IPlaylistItem;
begin
  for i := 1 to 5 do
  begin
  pi := CurrentPlaylist.GetItem(i);
    if (pi.GetItemType = pitContainer) AND
      (pi.GetAttributes.GetValue('Check') <> '1') then
    begin
      Cue := pi.GetCuePosition(ptCueOut);
      pi.SetCuePosition(ptCueOut, Cue - 3);
      pi.GetAttributes.SetValue('Check', '1');
    end;
  end;
end;

begin
end.

Dieses Skript schaut sich beim Start eines Elements die nächsten fünf Elemente an, ob sie ein Container sind. Falls ja, wird das CueOut ausgelesen und um drei Sekunden vermindert wieder zurückgeschrieben. Gleichzeitig wird dem Container eine Marke verpaßt, damit er beim nächsten Suchlauf nicht mehr angefaßt wird.

Ob tatsächlich fünf Elemente im voraus geschaut werden muß, hängt von Eurem

ab. Gegebenenfalls reichen dafür auch weniger Elemente. Und: Es werden alle Container gekürzt, egal, was drinnen ist. Solltet Ihr auch andere Container im Einsatz haben, die nicht gekürzt werden sollen, müssen die zu kürzenden anderweitig unterschieden werden (z. B. durch einen eindeutigen Beginn des Titels).

Danke, das würde wir natürlich viel lieber so lösen. Sehr geil.

Aber wie du schon gesagt hast, haben wir natürlich auch noch andere Container im Einsatz, insofern wäre die Angabe des Containernamen wohl die bessere Variante.

Kann man das realisieren, das sich das nur auf einen bestimmten Container bezieht?

Na ja, ich kenne Eure Programmelemente ja nicht. Haben die zu schnippelnden Container jeweils einen für sich sprechenden Namen, daß man sie von den anderen unterscheiden kann?

Naklar :wink: die heißen nicht nur “Container” sondern z.B. “Nachrichten”, “Werbung”

Ich bräüchte es schon konkreter. Möglicherweise müßtet Ihr Euch überlegen, wie man die zu kürzenden anders kennzeichnen könnte. Sie müssen ja gegenüber den anderen unterschieden werden sollen. Heißen sie zum Beispiel alle Nachrichten, dann wäre es okay.

Ok, das bekommen wir im dann auch im Nachhinein angepasst. Versuchen wir doch einfach mal das script mit dem Container “Nachrichten” zum laufen zu bringen.

Großes DANKE jetzt schon mal für Deine Hilfe :wave: :+1: :grinning:

Ungetestet:

const
  Titel = 'Nachrichten';

procedure OnPlayerStart(PlaylistIndex: integer; PlayerIndex: integer; Item: IPlaylistItem);
var
  i: integer;
  Cue: TTimeValue;
  pi: IPlaylistItem;
begin
  for i := 1 to 5 do
  begin
  pi := CurrentPlaylist.GetItem(i);
    if (pi.GetItemType = pitContainer) AND
      (pi.GetTitle = Titel) AND
      (pi.GetAttributes.GetValue('Check') <> '1') then
    begin
      Cue := pi.GetCuePosition(ptCueOut);
      pi.SetCuePosition(ptCueOut, Cue - 3);
      pi.GetAttributes.SetValue('Check', '1');
    end;
  end;
end;

begin
end.

In Zeile 2 kannst Du den Titel anpassen.

Hallo liebe Gemeinde,

nach einem kurzen Austausch mit @Tondose hole ich dieses Thema noch einmal hervor. Ich bin gerade mit dem Script am herumtüfteln und bin nun auf folgendes Problem gestoßen: Beim Starten des Containers erhalte ich die Meldung “List out of bounds (1)”.

Woran könnte das liegen?

Bei dem Container handelt es sich um einen Nachrichtencontainer, der Opener, Musikbett, das Nachrichtenelement (mit gleichbleibender ID) und ein Outro enthält. Gekürzt werden durch das Script soll auf jeden Fall das Nachrichtenelement, da es hinten zu viel Stille enthält, die nur im Nachhinein durch mAirList entfernt werden kann.

Über eine Hilfestellung würde ich mich sehr freuen!
Möglicherweise darf ich zusätzlich auch @Torben dafür aktivieren?

Freundliche Grüße
Oliver :slight_smile: