Mason Wright
Mason Wright

Reputation: 367

How to load a file into a html5 audio tag

How would a I load a audio file from a <input type="file"> tag into a audio tag? I have tried :

<input type="file" id="file"></input>
<script>
var file = document.getElementById("file");
var audio = document.createElement("audio");
audio.src = file.value;
document.write(audio)
</script>

Upvotes: 6

Views: 9891

Answers (3)

Shimon Doodkin
Shimon Doodkin

Reputation: 4569

I have developed an es6 code to load a file into an Audio element with a Promise that catches errors and resolves on success

    //functions:

    function setSrcObject(element, f) {
    if ('srcObject' in element) {
      try {
        // eslint-disable-next-line no-param-reassign
        element.srcObject = f; // this is the new way. only safary supports muliplt inputs, it is possible to put here media streams and files and blobs, but current new browsers support only media stream so need a fallback.
      } catch (e) {
        if (e.name !== 'TypeError') throw e;
        // Avoid using this in new browsers, as it is going away.
        // eslint-disable-next-line no-param-reassign
        element.src = URL.createObjectURL(f);
      }
    }
    // eslint-disable-next-line no-param-reassign
    else element.src = URL.createObjectURL(f);
  }

  function loadAudioFile(audio, file) {
    let onloadeddataResolve;
    let onloadeddataReject;
    // once
    function onloadeddataEv() {
      onloadeddataResolve();
      audio.removeEventListener('loadeddata', onloadeddataEv);
      audio.removeEventListener('error', onerrorEv);
    }
    function onerrorEv(e) {
      onloadeddataReject(e.srcElement.error);
      audio.removeEventListener('loadeddata', onloadeddataEv);
      audio.removeEventListener('error', onerrorEv);
    }
    audio.addEventListener('loadeddata', onloadeddataEv);
    audio.addEventListener('error', onerrorEv);
    const promise = new Promise((resolve, reject) => {
      onloadeddataResolve = resolve;
      onloadeddataReject = reject;
    }); // inversion of control promise
    // try load it:
    try {
      // audio.src =  url; // = http://example.org/myfile.mp3 or .ogg
      setSrcObject(audio, file);
      audio.load();
    } catch (e) {
      audio.removeEventListener('loadeddata', onloadeddataEv);
      audio.removeEventListener('error', onerrorEv);
      onloadeddataReject(e);
    }
    return promise;
  }

//example:

let audio =  new Audio(); // create audio element
audio.autoPlay=false;
filefield.oninput=async function test() {
  try {
    const f =  filefield.files[0]; // take first file 
    await loadAudioFile(audio, f); // load the file
    await audio.play();
  } catch(e) { console.log(e.stack?e.stack:e) }
}
playpause.onclick = async () => {  if( audio.paused) await audio.play(); else await audio.pause(); };
<input type="file" id="filefield" multiple="multiple"  accept="audio/mpeg, audio/mp4, audio/ogg">
<input id="playpause" value="play pause" type="button">

this solution was a part of a playlist player object I have developed

https://jsfiddle.net/shimondoodkin/7zmhsg30/20/

related solution, play audio using web audio API

https://jsfiddle.net/shimondoodkin/251wx8ys/31/

Upvotes: 0

Adam Azad
Adam Azad

Reputation: 11297

I believe it will satisfy your needs. First, the file input needs to be bound via JavaScript or jQuery (if you prefer). You can use Blob browser support

The following is a very basic example;

<input type="file" id="file"></input>
<audio id="audio" controls autoplay></audio>

We bind the #file for changes using AddEventListener as below

// Check for BlobURL support
var blob = window.URL || window.webkitURL;
    if (!blob) {
        console.log('Your browser does not support Blob URLs :(');
        return;           
    }

document.getElementById('file').addEventListener('change', function(event){

        consolePrint('change on input#file triggered');
        var file = this.files[0],
         fileURL = blob.createObjectURL(file);
        console.log(file);
        console.log('File name: '+file.name);
        console.log('File type: '+file.type);
        console.log('File BlobURL: '+ fileURL);
        document.getElementById('audio').src = fileURL;

});

Or the other hand, here's a nice and more interactive example I created

<iframe style="height:600px;width:102.7%;margin:-10px;overflow:hidden;" src="//jsfiddle.net/adamazad/0oy5moph/embedded/result,js,html,css/" allowfullscreen="allowfullscreen" frameborder="0"></iframe>

Upvotes: 9

SIMDD
SIMDD

Reputation: 645

    var wrap = document.getElementById("wrap");
    var file = document.getElementById("file");
    var audio = document.createElement("audio");
    file.onchange = function() {
        audio.src = file.value;
        wrap.appendChild(audio);
    };
<div id="wrap">
    <input type="file" id="file">
</div>

This is to realize the train of thought, but this also cannot achieve, because url that the upload is not local url, You can discuss with me in the comments section

Upvotes: 0

Related Questions