Skip to content

Commit

Permalink
Added support for MP3 with ID3V2 at start of the files
Browse files Browse the repository at this point in the history
  • Loading branch information
jbraendle committed Jan 9, 2022
1 parent aebd639 commit c547757
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 0 deletions.
Binary file not shown.
Binary file not shown.
39 changes: 39 additions & 0 deletions MetadataExtractor.Tests/Formats/Mpeg/Mp3ReaderTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright (c) Drew Noakes and contributors. All Rights Reserved. Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.

using MetadataExtractor.Formats.Mpeg;
using MetadataExtractor.IO;
using Xunit;

namespace MetadataExtractor.Tests.Formats.Mpeg
{
/// <summary>Unit tests for <see cref="Mp3Reader"/>.</summary>
public sealed class Mp3ReaderTest
{
private static Directory ProcessBytes(string file)
{
using var stream = TestDataUtil.OpenRead(file);
return new Mp3Reader().Extract(new SequentialStreamReader(stream));
}

[Fact]
public void Mp3()
{
var directory = ProcessBytes("Data/file_example_MP3_5MG_short.mp3");

Assert.False(directory.HasError);

Assert.Equal(320, directory.GetInt32(Mp3Directory.TagBitrate));
}

[Fact]
public void Mp3_IDV2()
{
var directory = ProcessBytes("Data/file_example_MP3_5MG.mp3");

Assert.False(directory.HasError);

Assert.Equal(320, directory.GetInt32(Mp3Directory.TagBitrate));
}

}
}
10 changes: 10 additions & 0 deletions MetadataExtractor/Formats/Mpeg/Mp3Reader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,23 @@ public sealed class Mp3Reader
{
// http://id3.org/mp3Frame
// https://www.loc.gov/preservation/digital/formats/fdd/fdd000105.shtml
// https://id3.org/id3v2.4.0-structure

public Directory Extract(SequentialReader reader)
{
var directory = new Mp3Directory();

var header = reader.GetInt32();

// Support ID3V2 - starts at the beginning of a MP3 file
if ((header & 0xFFFFFF00) == 0x49443300)
{
// Adjust start to end of header
var id3Bytes = reader.GetBytes(6);
reader.Skip(id3Bytes[2] * 2097152 + id3Bytes[3] * 16384 + id3Bytes[4] * 128 + id3Bytes[5]);
header = reader.GetInt32();
}

// ID: MPEG-2.5, MPEG-2, or MPEG-1
int id = 0;
switch ((header & 0x000180000) >> 19)
Expand Down
8 changes: 8 additions & 0 deletions MetadataExtractor/Formats/Mpeg/MpegAudioTypeChecker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,20 @@ 2 Layer description
11 - Layer I
Additional bits contain more information, but are not required for file type identification.
MP3 with ID3V2-Tags https://id3.org/id3v2.4.0-structure
MP3-File with ID3V2-Tagging at start
*/

public int ByteCount => 3;

public Util.FileType CheckType(byte[] bytes)
{

// MP3-File with "ID3" at start
if (bytes[0] == 0x49 && bytes[1] == 0x44 && bytes[2] == 0x33)
return Util.FileType.Mp3;

// MPEG audio requires the first 11 bits to be set
if (bytes[0] != 0xFF || (bytes[1] & 0xE0) != 0xE0)
return Util.FileType.Unknown;
Expand Down

0 comments on commit c547757

Please sign in to comment.