Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi mp3 schneiden? (https://www.delphipraxis.net/91974-mp3-schneiden.html)

Gausi 14. Mai 2007 10:00

Re: mp3 schneiden?
 
Joah, das Problem dabei ist aber die Neukodierung der Musikdaten. Dabei geht grundsätzlich Qualität verloren.

Ich guck mal, ob ich die Tage versuche, meinen Code von damals zu rekonstruieren. Dürfte nicht allzuviel Aufwand sein. Ersten MPEG-Frame suchen, dessen Länge bestimmen, nächsten suchen usw. Dabei jeden Frame in eine Byte-Array einlesen, und so die ganze Datei in ein Array of Array of Byte aufteilen. Anschließend einen Teil der Frames in eine neue Datei schreiben. Das einzige, was ich gerade noch nicht weiß ist, wie ich von einer Zeitangabe auf die richtige Frame-Nr. komme, aber das dürfte auch kein größeres Problem sein.

Edit: Ich hab grade gemerkt, dass meine Idee nur für Dateien mit konstanter Bitrate so einfach ist. Bei VBR muss ggf. zusätzlich der Xing-Header geändert werden. Da muss die neue Frameanzahl rein, und das Sprungstellen-Array muss neu berechnet/geschrieben werden.

Gausi 14. Mai 2007 16:52

Re: mp3 schneiden?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Das hat mir keine Ruhe gelassen, und daher hab ich mich mal ein Stündchen hingesetzt, und meine MPEG-Klasse etwas erweitert. :stupid:

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;

gandime 14. Mai 2007 18:27

Re: mp3 schneiden?
 
hey super sache blos jetzt habe ich nichts mehr zu tun :-D
aber trotzdem danke :-)

Wishmaster 14. Mai 2007 22:27

Re: mp3 schneiden?
 
Hi

Ich hatte hier schon en Code Schnipsel geschrieben!

Delphi-Quellcode:
Channel:= BASS_StreamCreateFile(FALSE, PChar(FSource), StartPos, EndPos, BASS_STREAM_DECODE or BASS_STREAM_AUTOFREE);
Oder benutze BASS_ChannelSetPosition(Channel, StartPos) Für die start position

Und den Rest wie im Code Schnipsel!


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:14 Uhr.
Seite 2 von 2     12   

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz