![]() |
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. |
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:
...und diese schreibt einen Teil in einen (neuen) Stream. Erwartete start-ende-Werte sind in Millisekunden anzugeben.
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;
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; |
Re: mp3 schneiden?
hey super sache blos jetzt habe ich nichts mehr zu tun :-D
aber trotzdem danke :-) |
Re: mp3 schneiden?
Hi
Ich hatte hier schon en Code Schnipsel geschrieben!
Delphi-Quellcode:
Oder benutze BASS_ChannelSetPosition(Channel, StartPos) Für die start position
Channel:= BASS_StreamCreateFile(FALSE, PChar(FSource), StartPos, EndPos, BASS_STREAM_DECODE or BASS_STREAM_AUTOFREE);
Und den Rest wie im ![]() |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:14 Uhr. |
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