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:
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.
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 thesound
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()
orSC.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 yourSC.stream()
callback function. That event listener would then trigger the call tosound.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 theSC.stream
callback fired. Most users wouldn't even realize this was a requirement as scrolling is such a common thing to do on mobile.