androidcordovafile-accesscordova-plugin-filetone.js

Cordova, I can use a file remotely but not locally, what am I wrong?


to try to solve another problem with the Tone.js library and the audio buffer (see here), I created a "default cordova hello world app", and added the "cordova-plugin-file" plugin.

I can't understand why, I can process a remote file and play it, but the same file locally, I can't play it, what am I wrong ?.

I removed all the "Content-Security-Policy" from my index.html ... I changed the permissions in the Config.xml file as follows:

 <preference name = "AndroidPersistentFileLocation" value = "Internal" />
     <access origin = "cdvfile: //*" />
     <access origin = "*" />
     <allow-intent href = "cdvfile: //*/*" />
     <allow-intent href = "http: //*/*" />
     <allow-intent href = "https: //*/*" />
     <allow-intent href = "tel: *" />
     <allow-intent href = "sms: *" />
     <allow-intent href = "mailto: *" />
     <allow-intent href = "geo: *" />

Then in the deviceready, if I switch to Tone.js Player, the external url works, with the local url no, where am I wrong?

//Local NO ok!: "cdvfile://localhost/persistent/1_Hat.mp3"

//Remote OK!: "https://vivo-vivendo-musica.com/sample/1_Hat.mp3"

function onDeviceReady() {
    // Cordova is now initialized. Have fun!
    console.log('Running cordova-' + cordova.platformId + '@' + cordova.version);
    document.getElementById('deviceready').classList.add('ready');
  
    //Local NO ok!: "cdvfile://localhost/persistent/1_Hat.mp3"
    //Remote OK!: "https://vivo-vivendo-musica.com/sample/1_Hat.mp3"

    window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function (fs) {
       console.log('file system open: ' + fs.name);
       fs.root.getFile("1_Hat.mp3", {  exclusive: false }, function (fileEntry) {

          console.log("fileEntry is file? " + fileEntry.isFile.toString());
          
          fileEntry.file(function (file) {
            console.log(file.localURL);
            player = new Tone.Player(file.localURL).toDestination();
            // play as soon as the buffer is loaded
            player.autostart = true;
          });
  
        }, console.log("getFile") );
  
      }, console.log("onErrorLoadFs") );  
}

I think it's almost certainly a security issue, but I don't understand what's missing, I've tried all sorts of ways to get to this file, which is present in the www folder.


Solution

  • Finally I managed to solve in this way, I don't know if it is the best way, or if it is the only way, but in this way I can get to the resources, present in the www / directory. It hasn't been easy for me, and I think this can help someone else.

    //attach a click listener to a play button
    document.querySelector('#Play').addEventListener('click', async () => {
        await Tone.start()
        console.log('audio is ready');
      play();
    })
    
    function play() {
        var xhr = new XMLHttpRequest();
        xhr.open("GET", "1_Hat.mp3", true);
        xhr.responseType = 'blob';
        xhr.onload = function(){
            var blob = URL.createObjectURL(this.response);
            console.log('pressed');
            var player = new Tone.Player().toDestination();
            player.load(blob);
            player.autostart = true;
        };
        xhr.send();
    }
    

    Thanks for this! great help: #628 (comment)