Search code examples
javascriptreactjsamazon-s3audioaudio-streaming

playing s3 audio and downloading the file in react component


I am trying to build out a component that can play audio files from my s3 bucket and have a button that will download the file locally if desired.

Here is what I have right now based on my research but it does not work. I think I may need to download a library?

Code:

import React from 'react';

<script src="https://unpkg.com/boxicons@latest/dist/boxicons.js"></script>

function AudioFilePlayer(props) {
  var name = props.name;
  var id = props.id;
  var s3_url = props.s3_url;

  const handleAudioPlay = (s3_url_link, state) => {
    
    var audio = new Audio(s3_url_link)

    if (state) {
      audio.play() 
    }
    else {
      audio.pause() 
    }

  }

 //no clue how to download
  return (
    <div className="AudioFileListItem">
      <div className="AudioFileListElements">
        <a href="javascript:void(0);" onClick={handleAudioPlay(s3_url, true)}>
          <span className="AudioFilePlayButton">
            <box-icon name='play-circle' color='#ffffff' size="sm"></box-icon>
          </span>
          <span className="AudioFilePlayButtonTitle">
            Play
          </span>
        </a>
       <a ref="javascript:void(0);" onClick={handleDownloadPlay(s3_url, true)}> 
        <span className="AudioFileDownloadButton">
          <box-icon name='download' type='solid' color='#ffffff' size="sm"></box-icon>
        </span>
        <span className="AudioFileDownloadButtonTitle">
          Download
        </span>
       </a> 
      </div>
    </div>
  );
}

export default AudioFileListItem;

I tested the aws s3_url and it works great. It downloads the correct wav file in my browser when the link is opened.

Example link would be:

https://bobmarley.s3.amazonaws.com/music/34/reggae.wav

My desired outcome is to be ablet o click the play html (button for user), have it change to the pause look (I can do this easily), and then actually play the audio. When I want to stop the audio, I can press it and it should pause and show the play button again.

For the download button, I just want to download the file. I know I can do this simply by opening the url in a tab but I don't want to reveal the URL. I want to know if theres another way to do it without showing the user the url.

I've been at this for weeks so truly any help would mean the world to me.

Thank you and this community so much!


Solution

  • I change 2 things and it's works fine from my side

    1. insted of using onClick={handleAudioPlay(s3_url, true) use onClick={()=>handleAudioPlay(s3_url, true)}
    2. since I could not access https://bobmarley.s3.amazonaws.com/music/34/reggae.wav from my side i use this url https://interactive-examples.mdn.mozilla.net/media/cc0-audio/t-rex-roar.mp3 to test.

    ReactDOM.render(<AudioFilePlayer />, document.getElementById("root"));
    
    function AudioFilePlayer(props) {
        let name = props.name;
        let id = props.id;
        let s3_url = "https://interactive-examples.mdn.mozilla.net/media/cc0-audio/t-rex-roar.mp3";
    
        const handleAudioPlay = (s3_url_link, state) => {
            var audio = new Audio(s3_url_link);
            if (state) {
                audio.play();
            } else {
                audio.pause();
            }
        };
    
        //no clue how to download
        return (
            <div className="AudioFileListItem">
                <div className="AudioFileListElements">
                    <a
                        href="javascript:void(0);"
                        onClick={()=>handleAudioPlay(s3_url, true)}
                    >
                        <span className="AudioFilePlayButton">
                            <box-icon
                                name="play-circle"
                                color="#ffffff"
                                size="sm"
                            ></box-icon>
                        </span>
                        <span className="AudioFilePlayButtonTitle">Play</span>
                    </a>
                    <a
                        href="javascript:void(0);"
                        // onClick={handleDownloadPlay(s3_url, true)}
                    >
                        <span className="AudioFileDownloadButton">
                            <box-icon
                                name="download"
                                type="solid"
                                color="#ffffff"
                                size="sm"
                            ></box-icon>
                        </span>
                        <span className="AudioFileDownloadButtonTitle">
                            Download
                        </span>
                    </a>
                </div>
            </div>
        );
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
      <div id="root"></div>