Skip to content

Commit

Permalink
Add support for Vorbis Comment RATING tag
Browse files Browse the repository at this point in the history
  • Loading branch information
Borewit committed Nov 7, 2023
1 parent c07debb commit 976dc49
Show file tree
Hide file tree
Showing 12 changed files with 53 additions and 7 deletions.
12 changes: 7 additions & 5 deletions lib/ogg/vorbis/VorbisTagMapper.ts
Expand Up @@ -119,11 +119,11 @@ const vorbisTagMap: INativeTagMap = {

export class VorbisTagMapper extends CommonTagMapper {

public static toRating(email: string, rating: string): IRating {
public static toRating(email: string, rating: string, maxScore: number): IRating {

return {
source: email ? email.toLowerCase() : email,
rating: parseFloat(rating) * CommonTagMapper.maxRatingScore
rating: (parseFloat(rating) / maxScore) * CommonTagMapper.maxRatingScore
};
}

Expand All @@ -132,10 +132,12 @@ export class VorbisTagMapper extends CommonTagMapper {
}

protected postMap(tag: ITag): void {

if (tag.id.indexOf('RATING:') === 0) {
if (tag.id === 'RATING') {
// The way Winamp 5.666 assigns rating
tag.value = VorbisTagMapper.toRating(undefined, tag.value, 100);
} else if (tag.id.indexOf('RATING:') === 0) {
const keys = tag.id.split(':');
tag.value = VorbisTagMapper.toRating(keys[1], tag.value);
tag.value = VorbisTagMapper.toRating(keys[1], tag.value, 1);
tag.id = keys[0];
}

Expand Down
Binary file added test/samples/rating/testcase-0star.mp3
Binary file not shown.
Binary file added test/samples/rating/testcase-1star.mp3
Binary file not shown.
Binary file added test/samples/rating/testcase-2star.mp3
Binary file not shown.
Binary file added test/samples/rating/testcase-3star.mp3
Binary file not shown.
Binary file added test/samples/rating/testcase-4star.mp3
Binary file not shown.
Binary file added test/samples/rating/testcase-5star.mp3
Binary file not shown.
Binary file added test/samples/rating/testcase.flac
Binary file not shown.
Binary file added test/samples/rating/testcase.opus
Binary file not shown.
14 changes: 12 additions & 2 deletions test/test-file-flac.ts
Expand Up @@ -8,7 +8,7 @@ import { samplePath } from './util.js';

const t = assert;

describe('Parse FLAC', () => {
describe('Parse FLAC Vorbis comment', () => {

const flacFilePath = path.join(samplePath, 'flac');

Expand Down Expand Up @@ -152,7 +152,6 @@ describe('Parse FLAC', () => {
assert.isUndefined(format.duration, 'format.duration');
});


it('Support additional Vorbis comment TAG mapping "ALMBUM ARTIST"', async () => {

const filePath = path.join(flacFilePath, '14. Samuel L. Jackson and John Travolta - Personality Goes a Long Way.flac');
Expand All @@ -164,4 +163,15 @@ describe('Parse FLAC', () => {
assert.strictEqual(common.albumartist, 'Various Artists', 'common.albumartist');
});

it('RATING mapping', async () => {

const filePath = path.join(samplePath, 'rating', 'testcase.flac');
const {common} = await mm.parseFile(filePath);

assert.isDefined(common.rating, 'Expect rating property to be present');
assert.equal(common.rating[0].rating, 0.80, 'Vorbis tag rating score of 80%');
assert.equal(mm.ratingToStars(common.rating[0].rating), 4, 'Vorbis tag rating conversion');
});

});

9 changes: 9 additions & 0 deletions test/test-file-ogg.ts
Expand Up @@ -203,6 +203,15 @@ describe('Parse Ogg', function() {

});

it('RATING mapping', async () => {

const filePath = path.join(samplePath, 'rating', 'testcase.opus');
const {common} = await mm.parseFile(filePath);

assert.isDefined(common.rating, 'Expect rating property to be present');
assert.equal(common.rating[0].rating, 0.80, 'Vorbis tag rating score of 80%');
assert.equal(mm.ratingToStars(common.rating[0].rating), 4, 'Vorbis tag rating conversion');
});

describe('Calculate duration', () => {

Expand Down
25 changes: 25 additions & 0 deletions test/test-id3v2.3.ts
Expand Up @@ -264,6 +264,31 @@ describe('Extract metadata from ID3v2.3 header', () => {
assert.deepEqual(id3v2.GEOB[0].description, 'Serato Overview', 'ID3v2.GEOB[0].description');
});

it('4.18 POPM', async () => {

// Rating (stars) assigned with Winamp 5.666 Media Library.
const testCaseFiles = [
{file: 'testcase-0star.mp3', stars: undefined},
{file: 'testcase-1star.mp3', stars: 1},
{file: 'testcase-2star.mp3', stars: 2},
{file: 'testcase-3star.mp3', stars: 3},
{file: 'testcase-4star.mp3', stars: 4},
{file: 'testcase-5star.mp3', stars: 5}
];

for (const testCaseFile of testCaseFiles) {
const filePath = path.join(samplePath, 'rating', testCaseFile.file);
const {common} = await mm.parseFile(filePath);
if (common.rating === undefined) {
assert.isUndefined(common.rating, 'Expect no rating property to be present in: ' + testCaseFile.file);
} else {
assert.isDefined(common.rating, 'Expect rating property to be present in: ' + testCaseFile.file);
assert.equal(Math.round(common.rating[0].rating * 4 + 1), testCaseFile.stars, 'ID3v2.3 rating conversion in: ' + testCaseFile.file);
assert.equal(mm.ratingToStars(common.rating[0].rating), testCaseFile.stars, 'ID3v2.3 rating conversion in: ' + testCaseFile.file);
}
}
});

describe('TXXX', async () => {

it('Handle empty TXXX', async () => {
Expand Down

0 comments on commit 976dc49

Please sign in to comment.