AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

mp3 schneiden?

Ein Thema von gandime · begonnen am 12. Mai 2007 · letzter Beitrag vom 14. Mai 2007
Antwort Antwort
Seite 2 von 2     12   
Benutzerbild von Gausi
Gausi

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

Re: mp3 schneiden?

  Alt 14. Mai 2007, 10:00
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.
  Mit Zitat antworten Zitat
Benutzerbild von Gausi
Gausi

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

Re: mp3 schneiden?

  Alt 14. Mai 2007, 16: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
gandime
(Gast)

n/a Beiträge
 
#13

Re: mp3 schneiden?

  Alt 14. Mai 2007, 18:27
hey super sache blos jetzt habe ich nichts mehr zu tun
aber trotzdem danke
  Mit Zitat antworten Zitat
Wishmaster

Registriert seit: 14. Sep 2002
Ort: Steinbach, MB, Canada
301 Beiträge
 
Delphi XE2 Architect
 
#14

Re: mp3 schneiden?

  Alt 14. Mai 2007, 22:27
Hi

Ich hatte hier schon en Code Schnipsel geschrieben!

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!
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:19 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz