Search code examples
iosiphoneaudiosoundcloudsoundmanager2

Soundcloud mp3 not streaming through Chrome iphone app


I have a music web app that is responsive to allow for mobile use. I'm not able to get the soundcloud streaming to work on the iphone in the chrome or safari browsers.

The song loads (it loads the track name) but it just sits there like so:

soundcloud error

I've tested that the song is indeed an mp3 with my client id ({"http_mp3_128_url":"https://cf-media.sndcdn.com/u8ouac3FqckU.128.mp3?).

What might be causing the song not to play in the mobile browser?

Code backing it is like so:

<i class="fa fa-play falist" ng-click="player.play(show, $index)" ng-show="$index != trackPlayingIndex"></i>
            <i class="fa fa-pause falist" ng-click="player.pause(show, $index)" ng-show="$index == trackPlayingIndex"></i></span>

controller/service:

 SC.stream(track.properties.stream_url, function(sound){

          if (playingSound) {
           playingSound.stop();
         }

          sound.play({
            whileplaying: function () {
              player.duration = Math.floor(this.durationEstimate / 1000);
              player.position = Math.floor(this.position / 1000);
              player.progress = (this.position / this.durationEstimate) * 100;
              $rootScope.$broadcast('statusChanged', true);
            },
            onfinish: function () {
              $rootScope.$broadcast('finished');
            }
          });

It works fine in the web browser so I must be missing something for the mobile browser.


Solution

  • To play audio/video on mobile devices you need direct, physical and synchronous interaction from the user. The SC.stream() function is asynchronous and therefore breaks one of the requirements for playback.

    There are a few crappy ways to work around this issue depending on how your app works. If you know all the songs that should be playable on the page you can call SC.stream() on each song when the page loads and then only call .play() on the sound instance when the user actually presses the play button.

    If you don't know all the songs that should be playable then you're left with two even crappier options. First, I believe that you can pass jQuery ajax options to SC.stream() or SC.get() which would allow you to make the request synchronous *shudder* by providing the following options { async: false }.

    The last option would be to setup an event listener on the entire body for the 'ontouchstart' event inside your SC.stream() callback function. That event listener would then trigger the call to sound.play() itself. This means that a user would have to first press the play button, and then touch anywhere on the page (even to scroll) after the SC.stream callback fired. Most users wouldn't even realize this was a requirement as scrolling is such a common thing to do on mobile.