Initial working version

This commit is contained in:
Samuel Kent
2022-12-22 20:22:22 +11:00
parent ce9675a1cc
commit ced7fa5092
902 changed files with 150252 additions and 0 deletions
+34
View File
@@ -0,0 +1,34 @@
import { IAudioMetadata, IOptions } from 'music-metadata/lib/type';
import * as mm from 'music-metadata/lib/core';
export { IPicture, IAudioMetadata, IOptions, ITag, INativeTagDict, IChapter } from 'music-metadata/lib/type';
export { parseBuffer, parseFromTokenizer, orderTags, ratingToStars, IFileInfo, selectCover } from 'music-metadata/lib/core';
/**
* Parse audio Stream
* @param stream - ReadableStream
* @param contentType - MIME-Type
* @param options - Parsing options
* @returns Metadata
*/
export declare const parseNodeStream: typeof mm.parseStream;
/**
* Parse Web API ReadableStream: https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream
* @param stream - ReadableStream (web stream according WTWG Streams Standard)
* @param fileInfo FileInfo object or MIME-Type
* @param options - Parsing options
* @returns Metadata
*/
export declare function parseReadableStream(stream: ReadableStream, fileInfo?: mm.IFileInfo | string, options?: IOptions): Promise<IAudioMetadata>;
/**
* Parse Web API File
* @param blob - Blob to parse
* @param options - Parsing options
* @returns Metadata
*/
export declare function parseBlob(blob: Blob, options?: IOptions): Promise<IAudioMetadata>;
/**
* Parse fetched file, using the Web Fetch API
* @param audioTrackUrl - URL to download the audio track from
* @param options - Parsing options
* @returns Metadata
*/
export declare function fetchFromUrl(audioTrackUrl: string, options?: IOptions): Promise<IAudioMetadata>;
+81
View File
@@ -0,0 +1,81 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.fetchFromUrl = exports.parseBlob = exports.parseReadableStream = exports.parseNodeStream = exports.selectCover = exports.ratingToStars = exports.orderTags = exports.parseFromTokenizer = exports.parseBuffer = void 0;
const initDebug = require("debug");
const mm = require("music-metadata/lib/core");
const readable_web_to_node_stream_1 = require("readable-web-to-node-stream");
const debug = initDebug('music-metadata-browser:main');
var core_1 = require("music-metadata/lib/core");
Object.defineProperty(exports, "parseBuffer", { enumerable: true, get: function () { return core_1.parseBuffer; } });
Object.defineProperty(exports, "parseFromTokenizer", { enumerable: true, get: function () { return core_1.parseFromTokenizer; } });
Object.defineProperty(exports, "orderTags", { enumerable: true, get: function () { return core_1.orderTags; } });
Object.defineProperty(exports, "ratingToStars", { enumerable: true, get: function () { return core_1.ratingToStars; } });
Object.defineProperty(exports, "selectCover", { enumerable: true, get: function () { return core_1.selectCover; } });
/**
* Parse audio Stream
* @param stream - ReadableStream
* @param contentType - MIME-Type
* @param options - Parsing options
* @returns Metadata
*/
exports.parseNodeStream = mm.parseStream;
/**
* Parse Web API ReadableStream: https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream
* @param stream - ReadableStream (web stream according WTWG Streams Standard)
* @param fileInfo FileInfo object or MIME-Type
* @param options - Parsing options
* @returns Metadata
*/
async function parseReadableStream(stream, fileInfo, options) {
const ns = new readable_web_to_node_stream_1.ReadableWebToNodeStream(stream);
const res = await exports.parseNodeStream(ns, typeof fileInfo === 'string' ? { mimeType: fileInfo } : fileInfo, options);
await ns.close();
return res;
}
exports.parseReadableStream = parseReadableStream;
/**
* Parse Web API File
* @param blob - Blob to parse
* @param options - Parsing options
* @returns Metadata
*/
async function parseBlob(blob, options) {
const fileInfo = { mimeType: blob.type, size: blob.size };
if (blob instanceof File) {
fileInfo.path = blob.name;
}
return parseReadableStream(blob.stream(), { mimeType: blob.type, size: blob.size }, options);
}
exports.parseBlob = parseBlob;
/**
* Parse fetched file, using the Web Fetch API
* @param audioTrackUrl - URL to download the audio track from
* @param options - Parsing options
* @returns Metadata
*/
async function fetchFromUrl(audioTrackUrl, options) {
const response = await fetch(audioTrackUrl);
const fileInfo = {
size: parseInt(response.headers.get('Content-Length'), 10),
mimeType: response.headers.get('Content-Type')
};
if (response.ok) {
if (response.body) {
const res = await this.parseReadableStream(response.body, fileInfo, options);
debug('Closing HTTP-readable-stream...');
if (!response.body.locked) { // Prevent error in Firefox
await response.body.cancel();
}
debug('HTTP-readable-stream closed.');
return res;
}
else {
// Fall back on Blob
return this.parseBlob(await response.blob(), options);
}
}
else {
throw new Error(`HTTP error status=${response.status}: ${response.statusText}`);
}
}
exports.fetchFromUrl = fetchFromUrl;
+1
View File
@@ -0,0 +1 @@
export {};
+102
View File
@@ -0,0 +1,102 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
localStorage.debug = 'music-metadata-browser:*';
const http = require("stream-http");
const mm = require("./index");
const testData = require("../test/test-data");
jasmine.DEFAULT_TIMEOUT_INTERVAL = 20000;
function httpGetByUrl(url) {
// Assume URL
return new Promise(resolve => {
http.get(url, stream => {
resolve(stream);
});
});
}
const urlInBloom = 'https://raw.githubusercontent.com/Borewit/music-metadata/master/test/samples/Nirvana - In Bloom - 2-sec.ogg';
function getAsBlob(url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.responseType = 'blob'; // force the HTTP response, response-type header to be blob
xhr.onload = () => {
resolve(xhr.response); // xhr.response is now a blob object
};
xhr.onerror = () => {
reject(new Error(`Failed download url=${url}`));
};
xhr.send();
});
}
const parsers = [
{
methodDescription: 'parseStream()',
parseUrl: async (audioTrackUrl, options) => {
const stream = await httpGetByUrl(audioTrackUrl);
return mm.parseNodeStream(stream, stream.type, options);
}
},
{
methodDescription: 'parseBlob()',
parseUrl: async (audioTrackUrl, options) => {
const blob = await getAsBlob(audioTrackUrl);
return mm.parseBlob(blob, options);
}
},
{
methodDescription: 'fetchFromUrl()',
parseUrl: (audioTrackUrl, options) => {
return mm.fetchFromUrl(audioTrackUrl, options);
}
}
];
xdescribe('music-metadata-browser', () => {
describe('Parse Ogg audio track: Nirvana - In Bloom', () => {
parsers.forEach(parser => {
it(parser.methodDescription, async () => {
const metadata = await parser.parseUrl(urlInBloom);
expect(metadata).toBeDefined();
expect(metadata.format.tagTypes).toEqual(['vorbis'], 'expect Vorbis metadata header');
expect(metadata.format.duration).toEqual(2.0, 'duration should be 2.0 sec');
expect(metadata.format.sampleRate).toEqual(44100, 'sample-rate should be 44.1 kHz');
expect(metadata.format.numberOfChannels).toEqual(2, 'number of channels should be 2 (stereo)');
expect(metadata.format.bitrate).toEqual(64000, 'bitrate should be 64 kbit/sec');
expect(metadata.common.title).toEqual('In Bloom');
expect(metadata.common.artist).toEqual('Nirvana');
expect(metadata.common.albumartist).toEqual('Nirvana', 'common.albumartist');
expect(metadata.common.album).toEqual('Nevermind', 'common.album');
expect(metadata.common.year).toEqual(1991, 'common.year');
expect(metadata.common.track).toEqual({ no: 2, of: 12 }, 'common.track');
expect(metadata.common.disk).toEqual({ no: 1, of: 1 }, 'common.disk');
expect(metadata.common.genre).toEqual(['Grunge', 'Alternative'], 'genre');
expect(metadata.common.picture[0].format).toEqual('image/jpeg', 'picture format');
expect(metadata.common.picture[0].data.length).toEqual(30966, 'picture length');
expect(metadata.common.barcode).toEqual('0720642442524', 'common.barcode (including leading zero)');
expect(metadata.common.asin).toEqual('B000003TA4', 'common.asin');
expect(metadata.common.catalognumber).toEqual(['GED24425'], 'common.asin');
expect(metadata.common.isrc).toEqual(['USGF19942502'], 'common.isrc');
// Make sure the orderTags is working
const vorbisTags = mm.orderTags(metadata.native.vorbis);
expect(vorbisTags.TRACKNUMBER).toEqual(['2'], 'vorbis.TRACKNUMBER');
expect(vorbisTags.TRACKTOTAL).toEqual(['12'], 'vorbis.TRACKTOTAL');
}, 5000);
});
});
it('Should expose the `ratingToStars()`', () => {
expect(mm.ratingToStars(1.0)).toEqual(5);
});
});
describe('Parse Tiuqottigeloot Vol 24 tracks', () => {
parsers.forEach(parser => {
describe(`Parser: ${parser.methodDescription}`, () => {
testData.tracks.forEach(track => {
it(`track ${track.metaData.artist} - ${track.metaData.title}`, async () => {
const url = testData.providers.netlify.getUrl(track);
const metadata = await parser.parseUrl(url);
expect(metadata.common.artist).toEqual(track.metaData.artist);
expect(metadata.common.title).toEqual(track.metaData.title);
});
});
});
});
});