import invariant from "invariant" ; import { IMusicMetadataBrowserApi } from "./types" ; import { IAudioMetadata } from "music-metadata-browser" ; import * as Utils from "./utils" ; type MediaDataType = string | ArrayBuffer | Blob ; export function genMediaTags ( file , musicMetadata ) { invariant ( file != null , "Attempted to get the tags of media file without passing a file" ) ; const options = { duration : true , skipPostHeaders : true , } ; if ( typeof file === "string" ) { return musicMetadata . fetchFromUrl ( file , options ) ; } return musicMetadata . parseBlob ( file as Blob , options ) ; } export function genMediaDuration ( url ) { invariant ( typeof url === "string" , "Attempted to get the duration of media file without passing a url" ) ; return new Promise ( ( resolve , reject ) => { const audio = document . createElement ( "audio" ) ; audio . crossOrigin = "anonymous" ; const durationChange = ( ) => { resolve ( audio . duration ) ; audio . removeEventListener ( "durationchange" , durationChange ) ; audio . src = "" ; } ; audio . addEventListener ( "durationchange" , durationChange ) ; audio . addEventListener ( "error" , ( e ) => { reject ( e ) ; } ) ; audio . src = url ; } ) ; } export async function genArrayBufferFromFileReference ( fileReference ) { invariant ( fileReference != null , "Attempt to get an ArrayBuffer without assigning a fileReference" ) ; return new Promise ( ( resolve , reject ) => { const reader = new FileReader ( ) ; reader . onload = ( ) => { resolve ( reader . result as ArrayBuffer ) ; } ; reader . onerror = reject ; reader . readAsArrayBuffer ( fileReference ) ; } ) ; } export async function genStringFromFileReference ( fileReference ) { return new Promise ( ( resolve , reject ) => { const reader = new FileReader ( ) ; reader . onload = ( ) => { resolve ( reader . result as string ) ; } ; reader . onerror = reject ; reader . readAsText ( fileReference ) ; } ) ; } interface PromptForFileReferenceOptions { accept ? : string | null ; directory ? : boolean ; } export async function promptForFileReferences ( { accept , directory = false } = { accept : null , directory : false , } ) { return new Promise < FileList > ( ( resolve ) => { const fileInput = document . createElement ( "input" ) ; if ( accept ) fileInput . setAttribute ( "accept" , accept ) ; fileInput . type = "file" ; fileInput . multiple = true ; fileInput . webkitdirectory = directory ; fileInput . directory = directory ; fileInput . mozdirectory = directory ; fileInput . value = null ; fileInput . addEventListener ( "change" , ( e ) => { const files = ( < HTMLInputElement > e . target ) . files ; resolve ( files as FileList ) ; } ) ; fileInput . click ( ) ; } ) ; } function urlIsBlobUrl ( url ) { return /^blob:/ . test ( url ) ; } export function curUrlFromByteArray ( arr ) { const base64 = Utils . base64FromDataArray ( arr ) ; return `data:image/x-win-bitmap;base64,${ base64 }` ; } export function filenameFromUrl ( url ) { if ( urlIsBlobUrl ( url ) ) { return null ; } const lastSegment = url . split ( "/" ) . pop ( ) ; if ( lastSegment == null ) { return null ; } return lastSegment . split ( "#" ) [ 0 ] . split ( "?" ) [ 0 ] ; }