Autor Beitrag
BungeeBug
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 901



BeitragVerfasst: Sa 31.01.04 11:04 
Hi all,

ich hab da mal wieder nen kleines Problem. Ich hab mir ein Backup von einer CD gemacht. Ab nich mit einem MP3 Ripper sonder mir na Brennersoftware. Das Ergebniss ist eine große MP3 Datei und eine CUE Datei, in der Steht wann ein Leid anfängt und wann Ende ist. Nun will ich aber viele kleine MP3s haben und nicht das ( ? ) eine Große. Was also nun tun? Wie sieht eine MP3 Datei aus, was muss man in den Header schreiben oder brauch ich den garnicht? Ausserdem wie kann ich "Frames" in der MP3 Datei auf eine Position als Byte "umrechnen"? Wie ihr seht steh ich wie der Ochs vorm Berg ... ich bin also für jede Information dankbar!
patrick
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 1481

WIN2k, WIN XP
D6 Personal, D2005 PE
BeitragVerfasst: Sa 31.01.04 13:17 
soweit ich weiß kann man aufgrund der MP3 kompressionsstruktur nicht die MP3 an sich schneiden.
man muss es zuerst in eine wave-datei umwandeln. diese auseinanderschnippeln und dann wieder komprimieren

_________________
Patrick
im zweifelsfall immer das richtige tun!!!
Gausi
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8535
Erhaltene Danke: 473

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: Sa 31.01.04 16:28 
@patrick: Das ist kompletter Unsinn. mp3 ist streamingfähig, d.h. man kann reinhören, wenn man auch nur einen Teil des Files hat. Daher ist es auch möglich, das mp3 File beliebig zu cutten, am Ende, am Anfang, mittendrin, völlig egal.

@ BungeeBug: Eine Mp3 Datei sieht im Idealfall folgendermassen aus
* ID3v2Tag (variable Grösse)
* Mp3Frames (ein paar100(0)(0))
* ID3v1 / v1.1 Tag

Jeder MP3Frame besteht aus einem MPEGHeader (4Bytes groß) und dem Datenteil. Aus den Daten im MpegHeader kannst du die Größe des Frames berechnen, und so zum nächsten springen. Hab da mal ne Procedur geschrieben, die die einzelnen Frames in ein 2dimensionales Array schreibt:

Edit: Wer suchet, der findet, und ist doch nicht am Ziel. Hier war mal ein Stück Code, das dem Weihnachtsmann auf seiner Suche nach dem Ziel helfen kann, doch der böse Grinch hat ihn versteckt, und stattdessen ein Bild hinterlassen. Aber der Grinch spielt gerne verstecken, und konnte es auch hier nicht lassen.

Edit2: Original-Code wieder eingefügt. Weihnachten 2007 ist vorbei :D. Für etwas besseren Code vgl. dieses Posting

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
type   TMpegFrame = array of byte;
[...]

var mp3file:array of byte;
  MpegFrames:array of TMpegFrame;

[...]
function TForm1.GetMpegFrames(mpeginfo:Tmpeginfo): integer;
var framestart,framelength:integer;
    erfolg,j:integer;
begin
    erfolg:=0;
    framestart:=mpeginfo.position;   // =0, oder nach ID3v2Tag
    setlength(MpegFrames,mpeginfo.frames);
    repeat
        // diesen frame kopieren
        framelength:=GetFramelength(framestart);
       // wenn da was schiefläuft, den rest der Datei nehmen!
        if (framelength=-1OR (erfolg=length(MPegFrames)-1then
        begin
            framelength:=length(mp3file)-framestart;
        end;
        setlength(MpegFrames[erfolg],framelength);
        // frame mit Nr. Erfolg kopieren
        for j:=0 to framelength-1 do Mpegframes[erfolg][j]:=mp3file[framestart+j];
        framestart:=framestart+framelength;
        inc(erfolg);
    until framestart>=length(mp3file);
    memo1.lines.add('Gelesene Blöcke: '+inttostr(erfolg));
    result:=erfolg;
end;

function TForm1.GetFramelength(framestart:integer):integer;
var mpeginfo:Tmpeginfo;
    framelength:integer;
    bitrate,version,samplerate:integer;
    layer:integer;
    bitrateindex,padding,samplerateindex: byte;
begin
    if (ord(mp3file[framestart])=$FFAND (ord(mp3file[framestart+1])>=$E0)then
    begin
        //Byte 1 und 2: AAAAAAAA AAABBCCD
        case ((ord(mp3file[framestart+1]) shr 3and 3of
            0: version:=3//eigentlich ist das Version 2.5 aber wegen dem Array-Index...
            1: version:=0//Reserved
            2: version:=2;
            3: version:=1;
        end;
        Layer:=4-((ord(mp3file[framestart+1]) shr 1and 3);
        // Byte 3: EEEEFFGH
        bitrateindex:=((ord(mp3file[framestart+2]) shr 4AND $F);
        bitrate:=MPEG_BIT_RATES[version][layer][bitrateindex];
        padding:=((ord(mp3file[framestart+2]) shr 1AND 1);
        samplerateindex:=((ord(mp3file[framestart+2]) shr 2AND 3);
        samplerate:=sample_rates[version][samplerateindex];

        if mpeginfo.layer=1 then
            framelength:=12*MPEG_BIT_RATES[version][layer][bitrateindex]*1000 DIV samplerate+padding*4
        else
            framelength:=144*MPEG_BIT_RATES[version][layer][bitrateindex]*1000 DIV samplerate+padding;
    end else
    begin
        framelength:=-1;
    end;
    result:=framelength;
end;


Wenn ich jetzt noch wüßte, wie lang ein einzelner Frame in Sekunden ist, wär das gessamte Problem gelöst...einfach nur die entsprechenden Frames in eine neue Datei schreiben, und ggf. die ID3 Tags einfügen...

Und: Was der Typ "Tmpeginfo"ist, steht in der FAQ, die ich mal zu dem Thema verfasst habe. Da ist auch die Prozedur, die diese Infos ausliest. Alternativ kannst du annehmen, dass dein File keinen ID3v2 Tag hat, und die Größe des Frame-Arrays anderweitig berechnen (initial auff z.B. 100, bei Bereichsüberschreitung vergrößern etc.). Dann kannst du dir diese etwas unübersichtliche Prozedur sparen.
Einloggen, um Attachments anzusehen!
_________________
We are, we were and will not be.


Zuletzt bearbeitet von Gausi am Fr 04.01.08 19:23, insgesamt 2-mal bearbeitet
Gausi
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8535
Erhaltene Danke: 473

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: Sa 31.01.04 16:38 
Hab da noch was gefunden:
www.mp3-converter.com/mp3codec/frames.htm hat folgendes geschrieben:
Regardless of the bitrate of the file, a frame in an MPEG-1 file lasts for 26ms (26/1000 of a second). This works out to around 38fps. If the bitrate is higher, the frame size is simply larger, and vice versa.

Ein Frame in einem mp3File ist also 26ms lang, damit kannst du ausrechnen, wie viele Frames du aus dem Array kopieren musst, um das Lied vollständig zu haben.

_________________
We are, we were and will not be.
BungeeBug Threadstarter
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 901



BeitragVerfasst: Sa 31.01.04 16:49 
Hi,

erst mal Danke an alle .

@ Gausi ... bedeutet das das ich die Datei an jeder Stelle zerschneiden kann ohne sie zuzerstörn?
Gausi
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8535
Erhaltene Danke: 473

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: Sa 31.01.04 16:59 
prinzipiell ja. Obwohl ich grade darauf gestossen bin, dass das bei mp3s nicht möglich sein soll. Es gibt da nämlich die Möglichkeit, dass sich einzelne Frames Platz bei anderen leihen, wenn z.b. bei einfachen Passagen weniger Platz zum Kodieren benötigt wird, als die Framelänge angibt, dann kann eine komplizierte Passage diesen Platz nutzen.
Auf der anderen Seite: Der Code oben ist ein Teil eines Programms, welches die Frames eines Mp3s durcheinanderwürfelt und in eine neue Datei schreibt. Das Ergebnis ist in Winamp abspielbar. Und: es gibt schon Freeware-Mp3-Cutter, die direkt das File splitten (z.B. mp3DirectCut). CueSheets werden davon auch unterstützt.

_________________
We are, we were and will not be.
patrick
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 1481

WIN2k, WIN XP
D6 Personal, D2005 PE
BeitragVerfasst: So 01.02.04 14:07 
Gausi hat folgendes geschrieben:
@patrick: Das ist kompletter Unsinn. mp3 ist streamingfähig, d.h. man kann reinhören, wenn man auch nur einen Teil des Files hat. Daher ist es auch möglich, das mp3 File beliebig zu cutten, am Ende, am Anfang, mittendrin, völlig egal.

aha, wieder was dazugelernt
man soll halt nicht alles glauben was einem die leute so erzählen :autsch:

_________________
Patrick
im zweifelsfall immer das richtige tun!!!