arielfaur / ionic-audio

An audio player for Ionic 3 and Angular 4. Works with HTML 5 audio or native audio using Cordova Media plugin.
http://arielfaur.github.io/ionic-audio/2.0/index.html
MIT License
321 stars 163 forks source link

Avoid Adding the same track to the audioProvider #109

Open ehusaint opened 7 years ago

ehusaint commented 7 years ago

I have multiple album within this app. As I navigate within each album, when I call the function to get all track by using the "audioProvider.tracks", i have the same tracks been added to the list. How can I avoid that. Here is the example:

  1. Navigate to album A
  2. 3 tracks are listed and are added to audioProviders - All tracks is equals to 3 item in array.
  3. Go back.
  4. Navigate to Album A again.
  5. 3 tracks are listed and are added again to the audioProviders - All tracks is equal to 6 items in the array.

How do I avoid audioProvider to add the same three tracks to the list?

I'm using ionic-audio 2.

ehusaint commented 7 years ago

Anyone please? or if there is a way to empty all the tracks that are in audioProvider.

ehusaint commented 7 years ago

@arielfaur - Thanks for responding. Is there a way currently to clear all the tracks within audioProvider?

arielfaur commented 7 years ago

@ehusaint I think this may be related to the way you are creating the bindings. The module will simply bind to an array of tracks. Maybe you should change the place where the binding takes place. For example use the constructor or any of the Angular or Ionic page cycle events to make sure that happens only once.

ehusaint commented 7 years ago

@arielfaur - I could be wrong here but I feel like the binding is happening on load of a page. I'm using your audio-track component. That component loads the audio every time the page is loaded. I'm not loading the tracks manually. Am I missing something?

arielfaur commented 7 years ago

Can you show me the code of your page component?

ehusaint commented 7 years ago

@arielfaur - It's a same code that is in your demo example. So here is the setup i have. There is a home page with album names. Click on album page (Let's say Album A) and it goes to album listing. Once i click play on one of the song within the album A, and i navigate back to the home page and come back to the same album A page, the id's of all the track on the album A page has changed. Because every time I navigate to album A page, it creates different ids for the same audio listing (which to my understanding is creating new track in audioProvider). So there is no way to know if this particular track is currently playing or not? Here is the code on the album page.

 <audio-track #audio *ngFor="let track of albumDetails" [track]="track" (onFinish)="onTrackFinished($event)">
      <ion-item>
        <audio-track-play  [audioTrack]="audio" item-left>
            <ion-spinner></ion-spinner>
          </audio-track-play>

        <div item-content style="width:100%" padding-right>
          <small>{{audio.title}}
          </small>
          <audio-track-progress [audioTrack]="track"></audio-track-progress>
          <audio-track-progress-bar dark duration progress [audioTrack]="audio"></audio-track-progress-bar>-->
          <!--<em style="font-size:.5em">Track ID: {{audio.id}}</em>-->
        </div>
        <ion-icon name="add" color="header" (click)="addToQueue(track)" item-right></ion-icon>
      </ion-item>
    </audio-track>
arielfaur commented 7 years ago

@ehusaint This is weird because the code that creates the binding is in the page constructor so that should execute only once. You could try moving that block to the ionViewDidLoad method but I don't know if that will make a change.

andrewlongdotcom commented 7 years ago

i think i am facing a similar issue in a podcast app i am building. similar to @ehusaint scenario i may do the following:

  1. navigate to a podcast page which contains the audio-track component
  2. press play
  3. navigate to some other pages
  4. come back to the original podcast page and i would like to have the audio-track component still showing correctly the playing status and track progress

i thought what i might be able to do is have 2 separate audio-track components on the page. one would be displayed when navigating to a podcast which is not currently being played and another to be displayed when i navigate back to the podcast that is currently being played.

for the component that would bind to the currently playing track i am trying to do the following in my page constructor to pull the track back from the AudioProvider and bind it to the audio-track component:

`var current = this._sharedDataService.getAudioProvider().current;

  if (current !== undefined &&
      current !== null &&
      this._sharedDataService.getAudioProvider().tracks !== undefined && 
      this._sharedDataService.getAudioProvider().tracks !== null &&
      this._sharedDataService.getAudioProvider().tracks.length > 0 &&
      this._sharedDataService.getAudioProvider().tracks[current].isPlaying &&
      this._sharedDataService.getAudioProvider().tracks[current].src === this.selectedFeedItem.link) {
        this.isCurrentPlayingTrack = true;            
        var track = this._sharedDataService.getAudioProvider().tracks[current];
        this.existingTrack = track;
        var tracks = this._sharedDataService.getAudioProvider().tracks;
        this.playing = true;
  }`

however, this doesn't work and i end up with the following error: Error: Uncaught (in promise): TypeError: Cannot convert undefined or null to object TypeError: Cannot convert undefined or null to object at Function.assign (<anonymous>) at AudioTrackComponent.ngOnInit (http://localhost:8100/build/main.js:62899:20) at checkAndUpdateDirectiveInline (http://localhost:8100/build/main.js:11112:19) at checkAndUpdateNodeInline (http://localhost:8100/build/main.js:12490:17) at checkAndUpdateNode (http://localhost:8100/build/main.js:12458:16) at debugCheckAndUpdateNode (http://localhost:8100/build/main.js:13087:59) at debugCheckDirectivesFn (http://localhost:8100/build/main.js:13028:13) at Object.eval [as updateDirectives] (ng:///AppModule/PodcastPlayItem.ngfactory.js:542:5) at Object.debugUpdateDirectives [as updateDirectives] (http://localhost:8100/build/main.js:13013:21) at checkAndUpdateView (http://localhost:8100/build/main.js:12425:14) at callViewAction (http://localhost:8100/build/main.js:12740:17) at execEmbeddedViewsAction (http://localhost:8100/build/main.js:12712:17) at checkAndUpdateView (http://localhost:8100/build/main.js:12426:5) at callViewAction (http://localhost:8100/build/main.js:12740:17) at execComponentViewsAction (http://localhost:8100/build/main.js:12686:13) at g (http://localhost:8100/build/polyfills.js:3:7133) at l (http://localhost:8100/build/polyfills.js:3:6251) at http://localhost:8100/build/polyfills.js:3:6805 at t.invokeTask (http://localhost:8100/build/polyfills.js:3:15213) at Object.onInvokeTask (http://localhost:8100/build/main.js:4489:37) at t.invokeTask (http://localhost:8100/build/polyfills.js:3:15134) at n.runTask (http://localhost:8100/build/polyfills.js:3:10390) at a (http://localhost:8100/build/polyfills.js:3:5313) at HTMLButtonElement.invoke (http://localhost:8100/build/polyfills.js:3:16210)

I don't really know at this point if this is even a viable option for what i am trying to accomplish or not

andrewlongdotcom commented 7 years ago

so just to follow up on my issue, it seems my approach was viable, but when i re-navigate to the page for an podcast that is the current item, i had to remove the audio-track component. i just bind the existing track that i retrieve in my page constructor to an audio-track-progress-bar

arielfaur commented 7 years ago

Could any of you maybe provide a link to a project to download and test this scenario?

chalosalvador commented 7 years ago

Hi, maybe you guys already found a solution to this but I want to post it here anyways. Thanks to Dzejms in #112 I found a solution. I added these lines to the constructor of my page component and the tracks list is being reseted. Hope it helps.

// RESET THE ARRAY OF TRACKS
if (this._audioProvider.tracks.length !== 0) {
  this._audioProvider.tracks[0].destroy();
  this._audioProvider.tracks.splice(0);
}
ehusaint commented 7 years ago

@chalosalvador - Thanks for the update but it seems like my issue was different. My scenario:

  1. Go to homepage.
  2. Navigate to Album A (has 4 tracks)
  3. constructor creates the id for all the track on this page and adds to the allTracks list.
  4. Navigate back to home page.
  5. Again click Album A (has same 4 tracks)
  6. Construcutor creates the new id for all the track on this same page. So now I have 8 tracks in allTrack list.

I had to avoid that.

chalosalvador commented 7 years ago

yeah, that looks exactly like my issue and adding those lines solved it. As far as I understand the allTracks variable is populated from the this._audioProvider.tracks property.

ehusaint commented 7 years ago

I'm not sure how that code would solve the problem. So you are saying that in the step "5" above, those 4 new tracks will not be created if I have this code? @chalosalvador

hvlads commented 7 years ago

I had the same problem and it helped me:

` createAlbumPlayList(tracks) { this.myTracks = []; for (let i = 0; i < tracks.length; i++) { let id = tracks[i]['id']; let s = tracks[i]['file']; let n = tracks[i]['name']; ..........

let src2 = this._audioProvider.tracks.map(function (e) { return e.src; }).indexOf(s); let track; if (src2 != -1) { track = this._audioProvider.tracks[src2]; } else { track = { id: id, title:n, src: s, artist: artist, art: art, preload: 'metadata' }; } this.myTracks.push(track); .... return this.myTracks; `

fdambrosio commented 7 years ago

Hi, I'm trying to use destroy() and stop() with a mp3 live streaming file.

In both case the audio stops to play, but the browser continues to download the file/track buffering it. How can I stop that file download?

arielfaur commented 7 years ago

Hey there! I just uploaded version 3.2.0 with some new features and examples such as basic playlist management. It would be great to get some feedback. Hopefully this one solves some of the issues you reported. Here's the link to the demo of the new version with playlist management: https://arielfaur.github.io/ionic-audio-demo/