1

I'm developing an app with Electron and React, it's kind of mp3 player. The problem is that I want to play audios that are not in the project folder. How can I upload these files from my hard drive?

import React from 'react';
import Sound from 'react-sound';

class App extends React.Component {
  render() {
    return (
      <Sound
      url='/media/user/Vol/a.mp3'
      playStatus={Sound.status.PLAYING}
      playFromPosition={300}
      onLoading={this.handleSongLoading}
      onPlaying={this.handleSongPlaying}
      onFinishedPlaying={this.handleSongFinishedPlaying}
    />
    )
  }
}

export default App;


I tried to set the url like file:///media/user/Vol/a.mp3, but it doesn't work.

isherwood
  • 58,414
  • 16
  • 114
  • 157
Raúl C. Rivero
  • 307
  • 1
  • 4
  • 20
  • I suspect that your problem is the same as is addressed here: https://stackoverflow.com/questions/47196800/reactjs-and-images-in-public-folder – isherwood Jan 02 '20 at 22:13
  • It's not, my problem is that I need to import files out of the project folder. – Raúl C. Rivero Jan 02 '20 at 22:18
  • 1
    Don't know if it is possible. Most (if not all) browsers prevent it for security reasons. This link asks why JS can't with some good answers. https://security.stackexchange.com/questions/201208/why-do-browsers-disallow-accessing-files-from-local-file-system-even-if-the-html. I say JS because TS transpiles to JS, which means TS cannot be better or have more privileges than what it is running on. – Potato Jan 02 '20 at 22:33

3 Answers3

4

Of course Electron can speak to files outside its project root. It wouldn't be any good for making desktop apps if it couldn't.

There are a few ways to do this in Electron.

The dialog API lets you present the user with standard File Open dialogs from their OS.

The File Object API lets you speak directly to files on the filesystem.

And the shell API allows you to run native commands, such as launching a native MP3 player.

UPDATE: I forgot to mention one of the main ways you will talk to files outside of the project root: which is via node.js itself.

Nathan Hawks
  • 557
  • 4
  • 14
  • Yes, I already get the list of mp3 in a folder that the user selects but what I need is to play it from react, which is what I built the user interface – Raúl C. Rivero Jan 03 '20 at 19:15
  • You may then need to load the data in node and pass it to Electron, possibly by stream. Have you pursued that direction? – Nathan Hawks Jan 03 '20 at 20:17
1

Below is the example you can try in your application

//audioFile: path of your audio file
export const playAudio = (audioFile) => {
  if (!audioFile) return;

  if (process.platform === 'darwin') {
    let command = `afplay ${audioFile}.aiff`;
    exec(command, (error, _, stderr) => {
      if (error) {
        stderr: ${stderr}`);
      }
    });
  } else {
    // Try an mp3 file format
    var audio = new Audio(audioFile);
    audio.play();
  }
};
1

To put it simply the URL should be like this E:\folder\musique.mp3 (on windows)

I guess that you allow the user to choose which audio file to play. so first you will do something like this in the main process

ipcMain.handle('get-audio', async () => {
    let files = []
    try {
      files = (await dialog.showOpenDialog({
        properties: ['openFile', 'multiSelections']
      })).filePaths
    } catch (error) {
      console.error(error);
    }
    return files
});

in the renderer process add a button or something like that with this event

const files = await ipcRenderer.invoke('get-audio') 
// update the stats here

Then disable web security preference within BrowserWindow

new BrowserWindow({
    webPreferences: {
      webSecurity: false, // very important 
    }
  });
evgeni fotia
  • 4,650
  • 3
  • 16
  • 34