How to download audios from soundcloud


#1

Hello everybody,

I have an Ionic 2 app that can stream audios from SoundCloud.

Now, I need to know how to download an audio and then, how to find it in the device.

I thought if I can download an audio, I can storage the id with Storage or NativeStorage

But I don’t know if it is the best way to do that. Someone did it any time?


#2

Well, I’ve tried to download audios, but there is a problem. When I press the download button, I don’t see anything. So if I go to the app folder I can see an audio file but it’s broken because always have an 600bytes size, and I can’t manually play it.

I wanted to see the progress, so after research I found to do that whit an event. So I’ve tried to show the progress temporaly with toast notifications, but it shows me “97”…“98”… and then no more is happening. If I go to the app folder with my explorer, I see an audio file but broken. And it’s no showing errors! This is the code:

public download(audio: any): void {

        this.platform.ready().then(() => {
            console.log("Clicked to download: " + audio.id);

            let url = `https://api.soundcloud.com/tracks/${audio.id}/download?client_id=${this.SC_CLIENT_ID}`;

            let pathToSaveTo: string = '';

            if (this.platform.is('android')) {
                pathToSaveTo = cordova.file.externalApplicationStorageDirectory + audio.id + '.wav';

                let fileTransfer = new Transfer();

                fileTransfer.onProgress(this.onProgress);

                fileTransfer.download(url, pathToSaveTo)
                    .then((entry) => {
                        console.log('download complete: ' + entry.toURL());
                    }, (error) => {

                        let prompt = this.alertCtrl.create({
                            title: 'Error',
                            subTitle: error,
                            buttons: ['Accept']
                        });

                        prompt.present();
                    });
            }


        });

    }

    onProgress = (progressEvent: ProgressEvent) : void => {
        this.ngZone.run(() => {
            if (progressEvent.lengthComputable) {

                let progress: any = Math.round((progressEvent.loaded / progressEvent.total) * 100);
                console.log(progress);

                let toast = this.toastCtrl.create({
                  message: progress,
                  duration: 100
                });
                toast.present();

            }
        });
    }

#3

Hi,
did you find any solution for this? i am facing the same issue.


#4

@nst Yeah buddy! Soundcloud responses with a redirection status. So we need to handle the redirect url to store the audio file:

public download(audio: any): void {

        let url: string = `https://api.soundcloud.com/tracks/${audio.id}/download?client_id=${this.SC_CLIENT_ID}`;
        let fileName: string = audio.id + '.mp3';
        let filePath: string = cordova.file.dataDirectory + fileName;

        console.log("Destiny path: " + filePath);

        if (this.platform.is('ios')) {
            filePath = filePath.replace(/^file:\/\//, '');
            console.log("Updated IOS destiny path: " + filePath);
        }

        this.toastNotifications.showStartingDownloadMsg();

        this.http.downloadFile(url, {}, {}, filePath)
            .then(response => {
                this.toastNotifications.showDownloadCompleteMsg();
                this.storeAudioInformation(audio, fileName, filePath);

                console.log(JSON.stringify(response));
            })
            .catch(response => {
                console.log("Error catch: " + JSON.stringify(response));

                /**
                 * Handle redirects if exist.
                 */
                if (response.headers.Location != undefined && (response.status === 301 || response.status === 302)) {
                    console.log("Redirect to " + response.headers.Location);
                    this.redirectToDownload(audio, response.headers.Location, fileName, filePath);
                } else {
                    this.toastNotifications.showDownloadErrorMsg();
                    console.log("No redirect found.");
                }

            });
    }

    public redirectToDownload(audio: any, url: string, fileName: string, filePath: any): void {

        this.http.downloadFile(url, {}, {}, filePath)
            .then(response => {
                console.log('Downloaded after redirect');
                this.toastNotifications.showDownloadCompleteMsg();
                this.storeAudioInformation(audio, fileName, filePath);
            })
            .catch(response => {
                console.log("Error catch: " + JSON.stringify(response));
            });
    }

And later, you can find and play it:


var pathalone: string = '';

        if (this.platform.is('ios')) {

            this.file.createFile(cordova.file.dataDirectory, this.audio.fileName, true).then(() => {
                pathalone = this.audio.filePath;
                console.log("Pathalone: " + pathalone);
                this.mediaPlayer = this.media.create(pathalone, onStatusUpdate, onSuccess, onError);
            });
        } else {
            pathalone = this.audio.filePath.substring(8);
            this.mediaPlayer = this.media.create(pathalone, onStatusUpdate, onSuccess, onError);
        }

        setTimeout(() => {
            if (this.mediaPlayer) {
               this.mediaPlayer.play();
            }
        }, 1000);

:grinning:


#5

thank you so much for responding.
i am sorry, i am new to ionic, will it be possisble to explain a little more.

  1. what do you pass in audio ??

  2. what is the use of “storeAudioInformation” function?

  3. is it okay to use
    const fileTransfer: TransferObject = this.transfer.create();

         fileTransfer.download(url, filePath)
             .then(response => {})
             .catch(response => {})
    

instead of this.http.downloadFile??


#6

@Colo9311
I am also trying to download using soundloud url.
When I am trying as you answered above, I am getting response.headers.Location=undefined , so that I am not able download.
Can you provide any solution regarding this?