From cde0b4eb7406e9dea698b03e5b080f570ec5b5a2 Mon Sep 17 00:00:00 2001 From: Borewit Date: Wed, 17 Oct 2018 21:40:52 +0200 Subject: [PATCH] #673 Integration with limited to jsmediatags function replacement. --- config/webpack.common.js | 5 -- js/actionCreators/files.ts | 16 +++--- js/fileUtils.ts | 47 +++++++-------- js/index.js | 19 +------ js/types.ts | 2 +- js/webamp.js | 4 +- js/webampLazy.js | 4 +- package.json | 5 +- yarn.lock | 114 ++++++++++++++++++++++++++++++++----- 9 files changed, 139 insertions(+), 77 deletions(-) diff --git a/config/webpack.common.js b/config/webpack.common.js index 8904c7d5..62626079 100644 --- a/config/webpack.common.js +++ b/config/webpack.common.js @@ -7,11 +7,6 @@ module.exports = { resolve: { extensions: [".js", ".ts", ".tsx"] }, - node: { - // Consider suggesting jsmediatags use: https://github.com/feross/is-buffer - // Cuts 22k - Buffer: false - }, module: { rules: [ { diff --git a/js/actionCreators/files.ts b/js/actionCreators/files.ts index e396b656..9c29febd 100644 --- a/js/actionCreators/files.ts +++ b/js/actionCreators/files.ts @@ -291,20 +291,20 @@ function queueFetchingMediaTags(id: number): Dispatchable { } export function fetchMediaTags(file: string | Blob, id: number): Dispatchable { - return async (dispatch, getState, { requireJSMediaTags }) => { + return async (dispatch, getState, { requireMusicMetadata }) => { dispatch({ type: MEDIA_TAG_REQUEST_INITIALIZED, id }); + try { - const data = await genMediaTags(file, await requireJSMediaTags()); + const metadata = await genMediaTags(file, await requireMusicMetadata()); // There's more data here, but we don't have a use for it yet: - // https://github.com/aadsm/jsmediatags#shortcuts - const { artist, title, album, picture } = data.tags; + const { artist, title, album, picture } = metadata.common; let albumArtUrl = null; - if (picture) { - const byteArray = new Uint8Array(picture.data); - const blob = new Blob([byteArray], { type: picture.type }); + if (picture && picture.length >= 1) { + const byteArray = new Uint8Array(picture[0].data); + const blob = new Blob([byteArray], { type: picture[0].format }); albumArtUrl = URL.createObjectURL(blob); } - dispatch({ type: SET_MEDIA_TAGS, artist, title, album, albumArtUrl, id }); + dispatch({ type: SET_MEDIA_TAGS, artist: artist ? artist : '', title: title ? title : '', album, albumArtUrl, id }); } catch (e) { dispatch({ type: MEDIA_TAG_REQUEST_FAILED, id }); } diff --git a/js/fileUtils.ts b/js/fileUtils.ts index 0b4adfe2..a705d564 100644 --- a/js/fileUtils.ts +++ b/js/fileUtils.ts @@ -1,31 +1,23 @@ import invariant from "invariant"; - -export interface MediaTags { - tags: { - artist: string; - title: string; - album: string; - picture: { - data: number[]; - type: string; - }; - }; -} +import { IAudioMetadata, IOptions } from 'music-metadata-browser'; type JsMediaTagsFile = string | ArrayBuffer | Blob; interface JsMediaTagsHandlers { - onSuccess: (tags: MediaTags) => void; + onSuccess: (tags: IAudioMetadata) => void; onError: (error: Error) => void; } -interface JsMediaTags { - read: (file: JsMediaTagsFile, handlers: JsMediaTagsHandlers) => void; +interface MusicMetadataBrowserApi { + + parseBlob(blob: Blob, options?: IOptions): Promise; + + fetchFromUrl(audioTrackUrl: string, options?: IOptions): Promise } export function genMediaTags( file: JsMediaTagsFile, - jsmediatags: JsMediaTags -): Promise { + musicMetadata: MusicMetadataBrowserApi +): Promise { invariant( file != null, "Attempted to get the tags of media file without passing a file" @@ -34,16 +26,17 @@ export function genMediaTags( if (typeof file === "string" && !/^[a-z]+:\/\//i.test(file)) { file = `${location.protocol}//${location.host}${location.pathname}${file}`; } - return new Promise((resolve, reject) => { - try { - jsmediatags.read(file, { onSuccess: resolve, onError: reject }); - } catch (e) { - // Possibly jsmediatags could not find a parser for this file? - // Nothing to do. - // Consider removing this after https://github.com/aadsm/jsmediatags/issues/83 is resolved. - reject(e); - } - }); + + const options = { + duration: true, + skipPostHeaders: true // avoid unnecessary data to be read + }; + + if (typeof file === "string") { + return musicMetadata.fetchFromUrl(file, options); + } + // Assume Blob + return musicMetadata.parseBlob(file as Blob, options); } export function genMediaDuration(url: string): Promise { diff --git a/js/index.js b/js/index.js index d76ea1c2..614c3797 100644 --- a/js/index.js +++ b/js/index.js @@ -43,22 +43,6 @@ import { import { bindToIndexedDB } from "./indexedDB"; -const requireJSMediaTags = () => { - return new Promise((resolve, reject) => { - require.ensure( - ["jsmediatags/dist/jsmediatags"], - require => { - resolve(require("jsmediatags/dist/jsmediatags")); - }, - e => { - console.error("Error loading jsmediatags", e); - reject(e); - }, - "jsmediatags" - ); - }); -}; - const DEFAULT_DOCUMENT_TITLE = document.title; const NOISY_ACTION_TYPES = new Set([ @@ -235,7 +219,8 @@ Raven.context(async () => { enableHotkeys: true, requireJSZip: () => import(/* webpackChunkName: "jszip" */ "jszip/dist/jszip"), - requireJSMediaTags, + requireMusicMetadata: () => + import(/* webpackChunkName: ""music-metadata-browser */ "music-metadata-browser/dist/index"), __extraWindows, __enableMediaLibrary: library, __initialWindowLayout, diff --git a/js/types.ts b/js/types.ts index 4eace24c..68b6801b 100644 --- a/js/types.ts +++ b/js/types.ts @@ -519,7 +519,7 @@ export interface AppState { export interface Extras { requireJSZip: () => Promise; - requireJSMediaTags: () => Promise; + requireMusicMetadata: () => Promise; } export type GetState = () => AppState; diff --git a/js/webamp.js b/js/webamp.js index e065f809..9fc8d835 100644 --- a/js/webamp.js +++ b/js/webamp.js @@ -1,5 +1,5 @@ import JSZip from "jszip"; -import jsmediatags from "jsmediatags"; +import musicMetadataBrowser from "music-metadata-browser"; import WebampLazy from "./webampLazy"; class Winamp extends WebampLazy { @@ -7,7 +7,7 @@ class Winamp extends WebampLazy { super({ ...options, requireJSZip: () => JSZip, - requireJSMediaTags: () => jsmediatags + requireMusicMetadata: () => musicMetadataBrowser }); } } diff --git a/js/webampLazy.js b/js/webampLazy.js index 50379af4..dbd2eee8 100644 --- a/js/webampLazy.js +++ b/js/webampLazy.js @@ -66,7 +66,7 @@ class Winamp { enableHotkeys = false, zIndex, requireJSZip, - requireJSMediaTags, + requireMusicMetadata, __extraWindows } = this.options; @@ -78,7 +78,7 @@ class Winamp { this._actionEmitter, this.options.__customMiddlewares, this.options.__initialState, - { requireJSZip, requireJSMediaTags } + { requireJSZip, requireMusicMetadata } ); this.store.dispatch({ type: navigator.onLine ? NETWORK_CONNECTED : NETWORK_DISCONNECTED diff --git a/package.json b/package.json index b529aea3..0a01b2d1 100644 --- a/package.json +++ b/package.json @@ -98,10 +98,10 @@ "jest-mock-random": "^1.0.2", "jest-puppeteer": "^3.0.1", "jest-runner-eslint": "^0.4.0", - "jsmediatags": "^3.8.1", "jszip": "^3.1.3", "lodash": "^4.17.11", "milkdrop-preset-converter-aws": "^0.1.0", + "music-metadata-browser": "^0.6.1", "prettier": "^1.14.2", "prop-types": "^15.5.10", "puppeteer": "^1.4.0", @@ -138,5 +138,6 @@ "config/jest.*.js" ] }, - "prettier": {} + "prettier": {}, + "dependencies": {} } diff --git a/yarn.lock b/yarn.lock index 7ba881a5..c57aae18 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1043,7 +1043,7 @@ assert-plus@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" -assert@^1.1.1: +assert@^1.1.1, assert@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91" dependencies: @@ -1586,6 +1586,13 @@ buffer@^4.3.0: ieee754 "^1.1.4" isarray "^1.0.0" +buffer@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.2.1.tgz#dd57fa0f109ac59c602479044dca7b8b3d0b71d6" + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + builtin-modules@^1.0.0, builtin-modules@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" @@ -1731,6 +1738,12 @@ center-align@^0.1.1: align-text "^0.1.3" lazy-cache "^1.0.3" +"chainsaw@>=0.0.7 <0.1": + version "0.0.9" + resolved "https://registry.yarnpkg.com/chainsaw/-/chainsaw-0.0.9.tgz#11a05102d1c4c785b6d0415d336d5a3a1612913e" + dependencies: + traverse ">=0.3.0 <0.4" + chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" @@ -2428,6 +2441,12 @@ debug@^3.1.0: dependencies: ms "2.0.0" +debug@^4.0.1, debug@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.0.tgz#373687bffa678b38b1cd91f861b63850035ddc87" + dependencies: + ms "^2.1.1" + decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" @@ -3404,6 +3423,10 @@ file-loader@^1.1.5: loader-utils "^1.0.2" schema-utils "^0.3.0" +file-type@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-10.0.0.tgz#084f32ab827238aa9a1482195ca7448c77a006b3" + file-type@^3.1.0: version "3.9.0" resolved "https://registry.yarnpkg.com/file-type/-/file-type-3.9.0.tgz#257a078384d1db8087bc449d107d52a52672b9e9" @@ -3930,6 +3953,12 @@ hash.js@^1.0.0, hash.js@^1.0.3: inherits "^2.0.3" minimalistic-assert "^1.0.0" +"hashish@>=0.0.2 <0.1": + version "0.0.4" + resolved "https://registry.yarnpkg.com/hashish/-/hashish-0.0.4.tgz#6d60bc6ffaf711b6afd60e426d077988014e6554" + dependencies: + traverse ">=0.2.4" + hawk@3.1.3, hawk@~3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" @@ -4556,7 +4585,7 @@ is-symbol@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572" -is-typedarray@~1.0.0: +is-typedarray@^1.0.0, is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" @@ -5147,12 +5176,6 @@ jsesc@~0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" -jsmediatags@^3.8.1: - version "3.8.1" - resolved "https://registry.yarnpkg.com/jsmediatags/-/jsmediatags-3.8.1.tgz#e27d26e957b0b330c28f9762c82940c4dcc64720" - dependencies: - xhr2 "^0.1.4" - json-loader@^0.5.4: version "0.5.7" resolved "https://registry.yarnpkg.com/json-loader/-/json-loader-0.5.7.tgz#dca14a70235ff82f0ac9a3abeb60d337a365185d" @@ -5511,7 +5534,7 @@ mdn-data@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-1.1.2.tgz#ceaa6a831b4de494352af984d301e3a8f2cad6e5" -media-typer@0.3.0: +media-typer@0.3.0, media-typer@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" @@ -5760,6 +5783,10 @@ ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" +ms@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + multicast-dns-service-types@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901" @@ -5771,6 +5798,28 @@ multicast-dns@^6.0.1: dns-packet "^1.3.1" thunky "^1.0.2" +music-metadata-browser@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/music-metadata-browser/-/music-metadata-browser-0.6.1.tgz#6b44544f817937e00d82bb983a0c49044c2b3348" + dependencies: + assert "^1.4.1" + buffer "^5.2.1" + debug "^4.0.1" + music-metadata "^3.1.4" + remove "^0.1.5" + typedarray-to-buffer "^3.1.5" + +music-metadata@^3.1.4: + version "3.1.4" + resolved "https://registry.yarnpkg.com/music-metadata/-/music-metadata-3.1.4.tgz#ca652c462ebd5f470d15045888f35e3580d0545b" + dependencies: + debug "^4.1.0" + file-type "^10.0.0" + media-typer "^0.3.0" + strtok3 "^2.1.0" + then-read-stream "^1.3.1" + token-types "^1.0.0" + mute-stream@0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" @@ -7260,6 +7309,12 @@ remove-trailing-separator@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" +remove@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/remove/-/remove-0.1.5.tgz#095ffd827d65c9f41ad97d33e416a75811079955" + dependencies: + seq ">= 0.3.5" + renderkid@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-2.0.1.tgz#898cabfc8bede4b7b91135a3ffd323e58c0db319" @@ -7607,6 +7662,13 @@ send@0.16.1: range-parser "~1.2.0" statuses "~1.3.1" +"seq@>= 0.3.5": + version "0.3.5" + resolved "https://registry.yarnpkg.com/seq/-/seq-0.3.5.tgz#ae02af3a424793d8ccbf212d69174e0c54dffe38" + dependencies: + chainsaw ">=0.0.7 <0.1" + hashish ">=0.0.2 <0.1" + serialize-javascript@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.4.0.tgz#7c958514db6ac2443a8abc062dc9f7886a7f6005" @@ -8062,6 +8124,14 @@ strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" +strtok3@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-2.1.0.tgz#f1e3aab64c15dadd23b09fdf9788afd11031b85a" + dependencies: + debug "^4.0.1" + then-read-stream "^1.3.0" + token-types "^1.0.0" + style-loader@^0.19.1: version "0.19.1" resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.19.1.tgz#591ffc80bcefe268b77c5d9ebc0505d772619f85" @@ -8208,6 +8278,10 @@ text-table@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" +then-read-stream@^1.3.0, then-read-stream@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/then-read-stream/-/then-read-stream-1.3.1.tgz#81f91fa31d8044bd9a6d49b84af4fb6b34b5cfc7" + throat@4.1.0, throat@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a" @@ -8297,6 +8371,10 @@ to-regex@^3.0.2: regex-not "^1.0.2" safe-regex "^1.1.0" +token-types@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/token-types/-/token-types-1.0.0.tgz#91f8180eb5464abb28af361ced3ac855a1e18fb2" + topo@2.x.x: version "2.0.2" resolved "https://registry.yarnpkg.com/topo/-/topo-2.0.2.tgz#cd5615752539057c0dc0491a621c3bc6fbe1d182" @@ -8325,6 +8403,14 @@ tr46@^1.0.1: dependencies: punycode "^2.1.0" +traverse@>=0.2.4: + version "0.6.6" + resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.6.6.tgz#cbdf560fd7b9af632502fed40f918c157ea97137" + +"traverse@>=0.3.0 <0.4": + version "0.3.9" + resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.3.9.tgz#717b8f220cc0bb7b44e40514c22b2e8bbc70d8b9" + travis-weigh-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/travis-weigh-in/-/travis-weigh-in-1.0.2.tgz#e1b1e2161ae0f967fa6aa971e672da1d2429c80e" @@ -8376,6 +8462,12 @@ type-is@~1.6.15: media-typer "0.3.0" mime-types "~2.1.15" +typedarray-to-buffer@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + dependencies: + is-typedarray "^1.0.0" + typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" @@ -9027,10 +9119,6 @@ ws@^4.0.0: async-limiter "~1.0.0" safe-buffer "~5.1.0" -xhr2@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/xhr2/-/xhr2-0.1.4.tgz#7f87658847716db5026323812f818cadab387a5f" - xhr@^2.0.1: version "2.4.1" resolved "https://registry.yarnpkg.com/xhr/-/xhr-2.4.1.tgz#ba982cced205ae5eec387169ac9dc77ca4853d38"