HTML5 Audio And Angular — Day 4 Final Project
Today we split up again in the morning and I was on my own trying to figure out how to be able to play the audio which we’ve gotten from our API call on the page for 1 second. Pretty easy stuff right?
Play Track For One Second
This I discovered how to do on Tuesday and was surprisingly straightforward. You can set start and end times to any audio URL by adding
#t=<start-time>,<finish-time>
to the end of the URL.
Our example we wanted to play from the very start of the track so we leave <start-time> blank.
#t=,<finish-time>
So all we did was add this to our track preview we get from Spotify API and there you go.
https://p.scdn.co/mp3-preview/6d00206e32194d15df329d4770e4fa1f2ced3f57#t=,1
Here’s a good resource for looking at all things HTML5 media.
https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Using_HTML5_audio_and_video
Also adding autoplay meant that the track would play the second the partial view was loaded.
<audio id=”AudioSong” autoplay>
<source src=”https://p.scdn.co/mp3-preview/6d00206e32194d15df329d4770e4fa1f2ced3f57#t=,1”>
</audio>
It was working and I was pretty pleased.
Interpolating URLs in Angular
So I was able to get the audio to play but I’d hardcoded the url. Next was to interpolate the url from a value in the controller. It didn’t matter right now what value once it was a previewUrl, we could figure out exactly how we were going to store the current song later.
I tried doing my moustaches around both sides {{ }}.
<audio id=”AudioSong” autoplay>
<source src=”{{controller.songs[0].previewUrl}}” type=>
</audio>
and got this super fun error in my console.
ionic.bundle.js:26771 Error: [$interpolate:noconcat] Error while interpolating: ”{{controller.songs[0].previewUrl}}”
Strict Contextual Escaping disallows interpolations that concatenate multiple expressions when a trusted value is required. See http://docs.angularjs.org/api/ng.$sce
http://errors.angularjs.org/1.5.3/$interpolate/noconcat?p0=%E2%80%9D%7B%7Bcontroller.songs%5B0%5D.previewUrl%7D%7D%E2%80%9D
Looking at the Angular documentation linked wasn’t incredibly enlightening so off to Google with me.
As with any problem there were tons of solutions out there with no consensus on best approach. The one that worked for me was this one. I injected $sceDelegateProvider into my routing.js file and added the domain I wanted to whitelist
\\www/js/routing.js
angular.module(‘introGame.routing’, [‘ui.router’])
.config(function($sceDelegateProvider, $stateProvider, $urlRouterProvider){
$sceDelegateProvider.resourceUrlWhitelist([
‘self’,
‘https://p.scdn.co/mp3-preview'
No more error messages!
Except it still wasn’t working!!!
HTML5 Media Browser Weirdness?
Finally everything was interpolating correctly but the stupid track still wouldn’t play. When I inspected elements in Chrome the interpolation looked fine and the only difference was that type=”audio/mpeg” moved before src.


This made no sense to me whatsoever. The order of these in HTML shouldn’t matter one iota. I confirmed this by replicating it in my sandbox project. type could come before or after src and everything should still work.
After yet more googling I discovered that there were lots of complicated answers including iframes, but finally I found there was an issue filed in github for it. They very helpfully provided solution. All I needed to do was move source into the initial audio tag and it worked.
<audio id=”AudioSong” ng-src=”{{controller.songs[0].previewUrl}}”>
</audio>I was a bit concerned today I hadn’t gotten very much done but writing out the above takes me through there was quite a bit of weirdness in today. I was pleased with my persistence and research skills to get to the bottom of the issues.
Shuffle Function
We came back together as a three after lunch and ploughed into a shuffle function. This was going to take the array of songs in an album and put them in a random order. We would then pop off the last song each time which would be the song the player will need to guess. Initially we tried using underscore, but then thought better of adding yet more external things to our project and went with finding a shuffle function we could add ourselves.
This version attributed to Fisher-Yates seemed to meet our needs and we understood each line of code which was good.
I was driving and was very pleased we managed to implement tiny TDD, red, green, refactor steps in order to write the code. When using these frameworks often its just ages of figuring out how to do something, then three times as long working out how we possibly unit test it. However making changes to an array was really easy to test (even if we couldn’t really test shuffle). It was very satisfying end to the day.
This is part of my daily blog series while I attend Makers Academy coding bootcamp. If you’d like to read more you can find them here.
Makers Academy Week10 Day4