-
-
Notifications
You must be signed in to change notification settings - Fork 90
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#119 Implementation of browser specific XHR-Reader
- Loading branch information
Showing
6 changed files
with
191 additions
and
179 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
import {CombinedTagMapper, IAudioMetadata, INativeAudioMetadata, IOptions} from "./"; | ||
import {TagPriority, TagType} from "./common/GenericTagTypes"; | ||
import {ParserFactory} from "./ParserFactory"; | ||
import {Promise} from "es6-promise"; | ||
import {ITokenizer} from "strtok3"; | ||
|
||
export class MusicMetadataParser { | ||
|
||
public static joinArtists(artists: string[]): string { | ||
if (artists.length > 2) { | ||
return artists.slice(0, artists.length - 1).join(', ') + ' & ' + artists[artists.length - 1]; | ||
} | ||
return artists.join(' & '); | ||
} | ||
|
||
private tagMapper = new CombinedTagMapper(); | ||
|
||
/** | ||
* Parse data provided by tokenizer. | ||
* @param {ITokenizer} tokenizer feed input (abstracting input) | ||
* @param {IOptions} options | ||
* @returns {Promise<IAudioMetadata>} | ||
*/ | ||
public parse(tokenizer: ITokenizer, options?: IOptions): Promise<IAudioMetadata> { | ||
if (!tokenizer.fileSize && options.fileSize) { | ||
tokenizer.fileSize = options.fileSize; | ||
} | ||
return ParserFactory.parse(tokenizer, options).then(nativeTags => { | ||
return this.parseNativeTags(nativeTags, options.native, options.mergeTagHeaders); | ||
}); | ||
} | ||
|
||
/** | ||
* Convert native tags to common tags | ||
* @param nativeData | ||
* @param includeNative return native tags in result | ||
* @param mergeTagHeaders Merge tah headers | ||
* @returns {IAudioMetadata} Native + common tags | ||
*/ | ||
public parseNativeTags(nativeData: INativeAudioMetadata, includeNative?: boolean, mergeTagHeaders?: boolean): IAudioMetadata { | ||
|
||
const metadata: IAudioMetadata = { | ||
format: nativeData.format, | ||
native: includeNative ? nativeData.native : undefined, | ||
common: {} as any | ||
}; | ||
|
||
metadata.format.tagTypes = []; | ||
|
||
for (const tagType in nativeData.native) { | ||
metadata.format.tagTypes.push(tagType as TagType); | ||
} | ||
|
||
for (const tagType of TagPriority) { | ||
|
||
if (nativeData.native[tagType]) { | ||
if (nativeData.native[tagType].length === 0) { | ||
// ToDo: register warning: empty tag header | ||
} else { | ||
|
||
const common = { | ||
track: {no: null, of: null}, | ||
disk: {no: null, of: null} | ||
}; | ||
|
||
for (const tag of nativeData.native[tagType]) { | ||
this.tagMapper.setGenericTag(common, tagType as TagType, tag); | ||
} | ||
|
||
for (const tag of Object.keys(common)) { | ||
if (!metadata.common[tag]) { | ||
metadata.common[tag] = common[tag]; | ||
} | ||
} | ||
|
||
if (!mergeTagHeaders) { | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
|
||
if (metadata.common.artists && metadata.common.artists.length > 0) { | ||
// common.artists explicitly by meta-data | ||
metadata.common.artist = !metadata.common.artist ? MusicMetadataParser.joinArtists(metadata.common.artists) : metadata.common.artist[0]; | ||
} else { | ||
if (metadata.common.artist) { | ||
metadata.common.artists = metadata.common.artist as any; | ||
if (metadata.common.artist.length > 1) { | ||
delete metadata.common.artist; | ||
} else { | ||
metadata.common.artist = metadata.common.artist[0]; | ||
} | ||
} | ||
} | ||
return metadata; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import {IAudioMetadata, IOptions} from "../"; | ||
import {Promise} from "es6-promise"; | ||
import * as strtok3 from "strtok3/lib/browser"; | ||
import {MusicMetadataParser} from "../MusicMetadataParser"; | ||
import * as Stream from "stream"; | ||
|
||
/** | ||
* Get audio track using XML-HTTP-Request (XHR). | ||
* @param {string} url URL to read from | ||
* @param {IOptions} opts Options | ||
* @returns {Promise<IAudioMetadata>} | ||
*/ | ||
export function parseUrl(url: string, opts?: IOptions): Promise<IAudioMetadata> { | ||
|
||
return strtok3.fromUrl(url).then(tokenizer => { | ||
opts.contentType = tokenizer.contentType || opts.contentType; | ||
return new MusicMetadataParser().parse(tokenizer, opts); // ToDo: mime type | ||
}); | ||
} | ||
|
||
/** | ||
* Parse audio from stream | ||
* @param stream Node stream | ||
* @param mimeType The mime-type, e.g. "audio/mpeg", extension e.g. ".mp3" or filename. This is used to redirect to the correct parser. | ||
* @param opts Parsing options | ||
* .native=true Will return original header in result | ||
* .mergeTagHeaders=false Populate common from data of all headers available | ||
* @returns {Promise<IAudioMetadata>} | ||
*/ | ||
export function parseStream(stream: Stream.Readable, mimeType?: string, opts?: IOptions): Promise<IAudioMetadata> { | ||
opts.contentType = mimeType || opts.contentType; | ||
return strtok3.fromStream(stream).then(tokenizer => { | ||
return new MusicMetadataParser().parse(tokenizer, opts); | ||
}); | ||
} |
Oops, something went wrong.