Thema: Delphi mp3 schneiden?

Einzelnen Beitrag anzeigen

Benutzerbild von Gausi
Gausi

Registriert seit: 17. Jul 2005
873 Beiträge
 
Delphi 11 Alexandria
 
#12

Re: mp3 schneiden?

  Alt 14. Mai 2007, 15:52
Das hat mir keine Ruhe gelassen, und daher hab ich mich mal ein Stündchen hingesetzt, und meine MPEG-Klasse etwas erweitert.

Das ganze ist eher ein Proof-Of-Concept, aber es sollte soweit funktionieren. Bei VBR gibts die Einschränkung, dass ein evtl. vorhandenes optionales Sprungstellen-Array gelöscht wird. Die Anzahl der Frames in diesem Xing-Header wird aber korrigiert. Das Array anzupassen dürfte auch kein prinzipielles Problem sein, allerdings verstehe ich nicht ganz, was da für Daten drin stehen.

Folgende Funktion bröselt eine MP3-Datei in die einzelnen Frames auf:
Delphi-Quellcode:
function TMpegInfo.ReadFrames(stream: TStream): Integer;
var c, i, bufpos: Integer;
    buffer: TBuffer;
    aMpegHeader: TMpegHeader;
begin
  LoadFromStream(stream);
  Setlength(fFrameArray, fFramesCount);

  setlength(buffer, stream.Size);
  Stream.Seek(0, soFromBeginning);
  c := Stream.Read(buffer[0], length(buffer));
  if c < Stream.Size then Setlength(Buffer, c);

  bufpos := fFirstHeaderPosition;
  fFramesread := 0;
  // besser wäre eigentlich: Die forschleife ersetzen durch eine,
  // die bis zum Dateiende läuft
  for i := 0 to fFramesCount-1 do
  begin
    aMpegHeader := GetValidatedHeader(buffer, bufpos);
    if aMpegHeader.valid then
    begin
      Setlength(fFrameArray[i], aMpegHeader.framelength);
      Move(buffer[bufpos], fFrameArray[i][0], aMpegHeader.framelength);
      bufpos := bufpos + aMpegHeader.framelength;
      inc(fFramesread);
    end else
    begin
      // d.h. es wurde kein gültiger Frame mehr gefunden
      // d.h. irgendwas ist falsch -einfach den Rest kopieren
      // mögliche Ursache, falls man den oben erwähnten besseren Weg wählt:
      // Ende der Musik, und Start von ID3v1-Tag oder Lyrics-Tag.
      // Das könnte man ggf. abfangen.
      Setlength(fFrameArray[i], length(buffer) - bufpos);
      Move(buffer[bufpos], fFrameArray[i][0], length(fFrameArray[i]));
      bufpos := bufpos + aMpegHeader.framelength;
      inc(fFramesread);
      result := fFramesread;
      exit;
    end;
  end;
  result := fFramesRead;
end;
...und diese schreibt einen Teil in einen (neuen) Stream. Erwartete start-ende-Werte sind in Millisekunden anzugeben.
Delphi-Quellcode:
// leicht gekürzt
function TMpegInfo.Cut(stream: TStream; start,ende: LongInt): Boolean;
var idxstart, minidx, idxend, i: integer;
begin
  result := False;

  if FirstFrameIsXing then
    minidx := 1
  else
    minidx := 0;
  //...
  // Aus den zeiten den Start- und EndIndex im Frame-Array berechnen
  // ein MPEGFrame ist 26ms lang
  idxstart := Round(start Div 26);
  idxend := Round(ende DIV 26);
  //...
  if vbr and CorrectXingHeader(idxend - idxstart + 1) then
    Stream.WriteBuffer(fFrameArray[0][0], length(fFrameArray[0]));

  for i := idxstart to idxend do
  begin
    Stream.WriteBuffer(fFrameArray[i][0], length(fFrameArray[i]));
  end;
  
  result := True;
end;
Angehängte Dateien
Dateityp: zip mp3_schneiden_166.zip (17,6 KB, 50x aufgerufen)
  Mit Zitat antworten Zitat