Transcript
[ Music ]
[ Applause ]
>> Hello, everyone, and welcome.
My name is Betim Deva, and I'm
an engineer on the Apple Music
team, and I'm excited to share
with you some updates that we
have made to MusicKit.
MusicKit was announced last
year, and it enabled developers
like yourselves bring customized
music experiences within their
apps.
This year, we are announcing
Apple Music on the web, which
will allow you to bring the same
kind of music experiences for
your websites.
We have a great web player ready
for you to embed, and we are
introducing MusicKit for the
web, which will allow you to
integrate Apple Music into your
websites.
We will talk more about Apple
Music on the web in a little
bit, but first, let's take a
look at some exciting updates on
MusicKit.
It's been great to see how app
developers have incorporated
Apple Music into their apps.
For instance, we all know and
love making music videos with
musical.ly.
When you find new music in this
app, you can easily add it to a
playlist.
Houdini makes joining Apple
Music simple.
It allows you to transfer your
playlists to Apple Music.
And Stationhead turns your
playlists to radio stations.
It allows you to broadcast your
music and your voice to the
world.
And lastly, Ola is the biggest
ride-hailing service in India.
We have been partnering with
them to bring the Apple Music
experience within their fleet of
cars.
Since MusicKit was announced
last year, we got a lot of
feedback for providing a way to
look up content using the
International Standard Recording
Code known as ISRC.
I am happy to report that this
has been added, and it will
enable you to precisely match
songs and music videos in the
Apple Music catalog from
virtually any other source.
Another enhancement to MusicKit
is the addition of iCloud Music
Library APIs.
Once the user has given
authorization to your app, you
can now provide them with ways
to interact with their music
library from within your app.
These APIs enable your users to
browse, search, and add content
to their music library.
You can also provide a way for
your user to create playlists
and add songs to an existing
playlist, all from within your
app.
Last year, we gave you Apple
Music APIs for our catalog.
This year, we added the iCloud
Music Library APIs.
We think this is a great set of
music APIs.
If you have been using our
existing iTunes Search API, we
encourage you to migrate over to
Apple Music APIs now.
Now, I would like to invite my
colleague DJ to the stage to
talk about Apple Music on the
web.
Thank you.
[ Applause ]
>> Thank you, Betim.
This year, we're excited to be
announcing MusicKit on the web.
Last year, we talked all about
the great ways for you to add
Apple Music to your iOS apps.
This year, we're bringing all of
that same great functionality to
the web.
So let's talk about the
components that make up MusicKit
on the web.
Last year, we added access to
the entire Apple Music catalog
with a REST API.
This year, as Betim mentioned,
we're launching new additions to
that REST API that'll let you
access the iCloud Music Library
for the logged-in user.
We're also launching the
MusicKit JS library.
Makes it really easy to use both
of those REST APIs in the
browser, and it gives your users
the ability to play back full
songs from the Apple Music
catalog and from the iCloud
Music Library right in their
browser.
Before we dig into MusicKit JS,
I want to show you the Apple
Music web player.
A few weeks ago, we launched a
new embeddable player.
It works great both on the
desktop and on mobile browsers.
These embeddable players are a
simple way for you to add full
song playback from the Apple
Music catalog right to your
website.
We have players for a single
song, an album, or a whole
playlist.
You can find the embed code on
the Apple Music preview pages or
right within the embeddable
player itself.
All you have to do is copy and
paste into your own website.
These embeddable players are
great for full song playback on
third-party websites, and we've
also enabled that functionality
on the Apple Music preview
pages.
So the embeds are powered by
MusicKit JS, which we're also
releasing so you can build your
own great music experiences.
So let's talk about the
functionality.
First and most importantly,
you'll be able to play back full
songs from Apple Music in the
browser.
It works on all modern browsers
without the need for any plug
ins or external dependencies.
You can use it on its own or
with any JavaScript framework of
your choice.
So for playback, we need to
authorize the user.
We'll handle that for you to
ensure that the user is an Apple
Music subscriber.
The JavaScript library is going
to keep a queue of songs so you
can play back a full album or a
whole playlist.
Once you have that queue of
songs, you'll be able to
control.
You'll be able to play, pause,
and skip to the previous or skip
to the next track.
And we're also going to keep
track of the Now Playing
metadata for the song that's
currently playing or currently
loading so you can render your
UI off of it.
So let's talk about how we would
build a simple player for the
web.
We're going to include the
JavaScript library.
Then, you need to provide your
developer token.
You can generate this using your
private key.
We have a really great way to
use declarative HTML markup.
You can add some markup to your
page.
For example, buttons for sign
in, sign out, or playback
controls.
We'll handle wiring up those
elements to the appropriate
functions in MusicKit.
Then, we're going to add some
play buttons.
We'll use some content IDs or
some URLs from the Apple Music
catalog that'll let the users
start playback.
So let's take a look at the code
for this.
You're going to include the
JavaScript library, and we're
going to host this on our CDN
for you.
We're going to add some buttons
for signing in and signing out.
Some buttons to control
playback.
Here we have a play button, a
pause button, and a next track
button.
We'll add some elements that we
will render in metadata about
what's currently playing.
Here we can get the playlist
name, the title, and the artist
name, for example.
And then, we have some elements
that let you show the progress
through the track that's
currently playing -- the
playback duration, the playback
time, and the playback progress.
So I'd like to bring up Jae Hess
to the stage to show you how to
use the MusicKit JS to build
that simple player that we just
talked about.
[ Applause ]
>> Thanks, DJ.
So we're going to get started
here, and I have a basic HTML
template on the right side in
Xcode that's already linked to
the MusicKit JS library.
And on the left side, I have a
Safari window open that's
running a live reload server.
This way, any changes I make to
my markup will be reflected
directly on the left-hand side.
To get started with MusicKit JS,
the first thing we need to do is
configure it for our use.
And with declarative markup, we
have a very simple way to do
that using meta tags.
We can specify our application
name as well as provide our
developer token.
Next, to get the functionality
we want, we're going to put a
button on the page for the user
to click.
And when this button is clicked,
it's going to take a playlist
from the Apple Music catalog,
set a playback queue, and start
playback in the browser.
Here I'm feeding a content URL
that I got from iTunes on the
desktop for a specific playlist
I'd like to embed.
This playlist is the "Today at
Apple Music" playlist.
[ Music ]
And so with that 1 simple line
of code, we have full playback
of the "Today at Apple" playlist
in the browser.
While this is great and it
offers a really good solution,
we probably want to add more
controls and more functionality
for the user to use.
The first thing we want to do is
allow the users of your
application, which are
subscribers of Apple Music, to
log in and log out.
And we'll do that by adding
Authorize and Unauthorize
buttons to the page.
We use the Apple Music Authorize
and Unauthorize attribute, and
MusicKit JS manages the state of
displaying those buttons for me.
I've logged in previously, so
you see that the state reflects,
"Sign out of Apple Music."
Next, we want to add some
playback controls.
And we can specify these using
the Apple Music attribute, and
we can specify things like skip
to previous item, pause, play,
skip to next item.
We can add Now Playing
information for the user to see
the current playing item in the
queue.
And here I've specified the
playlist artwork URL, and I can
specify the height and width I
would like that to render.
And I also have access to any
data attribute that's available
on the media item.
So I can specify things like
playlist name, the title of the
track, as well as the artist
name.
Underneath, I've specified that
I would like the current
playback time to be loaded into
the HTML time element.
So when the page reloaded,
nothing's there for Now Playing.
That's because we aren't playing
anything, so let's fix that by
adding buttons that would allow
the user to queue up playlists.
I'm going to paste in 16
playlists.
And when the user--
[ Music ]
Now, using the playback
controls, I can pause playback.
I can skip to the next item.
[ Music ]
I could even go back to that.
Now, MusicKit JS offers great
solutions with a declarative
markup, but it also offers a
full JavaScript API, so I'd like
to bring DJ back up on stage to
go over the JavaScript API with
you.
Thank you.
[ Applause ]
>> Thank you, Jae.
The declarative markup is a very
straightforward way to add basic
functionality.
Let's talk about some more
advanced usage.
Here we're going to write some
JavaScript to interact with
MusicKit, and let's take a look
at a couple examples.
We can fetch metadata from the
catalog by ID.
We can search for content within
the Apple Music catalog.
We can browse the iCloud Music
Library for the logged-in user,
and search also works within a
library scope.
We can set and control that
queue of songs directly.
And we can react to playback
events, and we drive our UI off
of this.
So we're going to look at some
code.
First, we're going to use the
MusicKit getInstant method.
MusicKit is a singleton because
you can only play back a single
song at a time, so we're going
to assign this to that music
variable, and we'll use that
throughout the rest of these
examples.
You can look up a song by ID.
The song method takes the ID,
and then you need to supply a
callback.
And this is a promise.
You'll see that promise model
used throughout MusicKit.
You then get a content object
back, and this content object
shows you the attributes of that
song and any relationships --
for example, the artist and the
album.
As Betim talked about earlier,
if you don't have a content ID,
you can do the exact same lookup
with a query filter for the
ISRC.
The objects that get returned
are the same as the previous
example.
We have a batch API if you want
to return a array of song
objects with a single network
call, and this also works for
albums and playlists.
We can let the user play back
content from within their iCloud
Music Library.
So these APIs live under the
library scope.
You can get a list of songs,
albums, and playlists.
These APIs are paginated, so you
can fetch just a subset
[inaudible] manner, and you can
unload more in as the user pages
through or scrolls through your
application.
You could search the Apple Music
catalog.
Here we're going to search for
just songs, and then the second
example, we'll search for both
songs and albums at the same
time.
You can also supply a limit to
limit the number of results
returned.
You can do the same query, but
scope it to within the user's
iCloud Music Library.
Here we're using the exact same
search method with the same
parameters, but we're doing it
under the library scope.
Next up, we have authorization.
We're always going to handle
authorization right before it's
needed -- when playback's
starting or when you're trying
to access the iCloud Music
Library for the current
logged-in user.
You could also trigger it
yourself if you'd like.
Perhaps you want to force that
at the beginning when someone
comes to your website.
When the user presses a button,
you can start playback.
You do this using the setQueue
method.
Here we're supplying the idea of
an album, and MusicKit will
handle fetching the metadata and
then setting that queue.
If you have a content object
that we saw previously, you can
pass that in directly, and it
will figure out what to do.
setQueue returns a promise.
When the queue is fully loaded,
you can start playback.
Here we're going to start
playback automatically with
music.play.
Once those songs are playing,
you might want to be able to
control that.
You can skip to the next or
previous item.
You can pause.
You can present actions in your
UI that will let a user quickly
add those songs, albums, or
playlists they're browsing to
their own iCloud Music Library.
We have an addToLibrary method
here.
You can do that same, you can do
those same 3 calls in batch.
Here we're adding those same 4
items as the top example, but
we're going to do it in a single
network call.
So let's look at events next.
MusicKit's going to fire events
that you use to drive your UI
from.
We do this because MusicKit
needs to own the audio element
in order to do that full song
playback.
Here we're going to use
addEventListener, which is going
to be a very familiar pattern if
you've done DOM scripting in the
past.
We're going to dive into just a
couple of the events to give you
an example.
The mediaItem WillChange and the
mediaItem DidChange events fire
when the Now Playing item in the
queue changes, when the first
song you're playing transitions
to the second song.
You can use this to trigger an
update to your UI that shows the
song that's currently playing.
When you actually begin
playback, the playbackState
changes events are fired.
Here we have a will and a did
change event again.
For example, you can know when a
song is loading, when it's
playing, or when it's paused,
and then you would update your
UI appropriately.
This event is going to give you
the old state and then the new
state that it's being
transitioned to.
As the song is playing, you'll
get playback progress change
events, and this event has the
current playback progress as a
percentage.
You can use this to update a
progress UI.
And you're also going to listen
for any media playback errors.
The mediaPlaybackError event
will fire.
You can catch that and then
present the appropriate error
messaging to the user.
So I'd like to bring up Jae back
to the stage.
He's going to take the player we
just built, and we're going to
show you how to use some of
those JavaScript APIs to add
search for the Apple Music
catalog, search within the
iCloud Music Library, and we're
also going to use events to
build a simple progress bar.
Jae?
>> Thanks, DJ.
[ Applause ]
As DJ mentioned, we're going to
take the previous example and
we're going to extend it to add
playlist search.
Now, I've taken the, off stage,
I've removed a lot of the stuff
that we did from the previous
example, but I've left some
things in the page.
I've also included an
application JavaScript file that
we'll be adding our JavaScript
to in a moment, but I wanted to
walk through quickly the HTML
again.
The major change we've done is
we've added an input element for
the user to search as well as 2
DOM containers that we can put
those search results into.
MusicKit JS doesn't offer an
opinion on a library or a
framework that you would be
using with your application, so
for this example, our CSS has
been prebuilt off screen.
We have some template helpers
that we've built in a separate
file as well.
And we'll notice that our markup
looks a little weird on the
left-hand side.
We got a couple of buttons that
are magically floating, and the
artwork is obviously empty.
And this is because MusicKit JS
assumes that if you're
configuring it with the meta
tags, that you want declarative
markup enabled.
When you don't provide that
configuration, it assumes you're
running JavaScript and you don't
want declarative markup.
But we provide a hook for you to
re-enable that with JavaScript.
We can configure MusicKit JS by
listening to the MusicKit loaded
event that's fired on the
document.
This lets us know that MusicKit
JS is ready to be used and
configured and playback can
happen.
We can configure our application
name just like we did with the
meta tags, but we now have an
attribute that says
declarativeMarkup that we can
set to true, which lets MusicKit
JS know that we're running in a
mixed mode and we want those
declarative markup features to
be enabled.
Next, I'm going to add a search
handler.
This is straight JavaScript.
It's not specific to MusicKit
JS, but I did want to walk
through that when the user
presses Enter on the search box
is when we're going to fire our
callback to do the search.
And we can implement that by
using the search method off of
MusicKit's API property.
This will perform the search
against the Apple Music API, and
we can specify any query
parameters that the Apple Music
API accepts with a configuration
object.
So we can specify we want to
search, we want to limit the
search to playlists and that we
want our results to be limited
to 8.
We have our custom templating,
but I want to highlight these 3
lines, which is where we tell
our MusicKit instance to take
the artwork that the user has
clicked on, and we want to set
the playback queue to that
playlist ID.
That returns a promise where we
can call music.play, which will
start playback for the user.
And then, we have our custom
rendering as well.
I perform a search for "a list."
We'll see 8 catalog results from
the Apple Music catalog for A
list playlists.
It would be nice if the same
search could apply to my
personal iCloud library as well.
And we can do that in almost the
exact same manner, except the
search method is off of the
library property instead of the
API property.
This lets MusicKit JS know
you're looking for the cloud
library.
Set playlists and set the same
for 8.
And then, the code looks exactly
the same with setting the queue
and starting playback.
If I perform that same search,
we'll see my iCloud Music
Library results as well as the
catalog library results.
And I can click, and we get
playback of the cloud library
item as well.
[ Music ]
Looking at the Now Playing
screen, or the Now Playing
information at the bottom makes
me realize that it's missing a
progress indicator to let me
know how far through the current
playing track we are.
And we can add something like
that by simply listening for the
playbackProgress DidChange event
that MusicKit JS provides.
Here we add an event listener to
the MusicKit instance, listen
for playbackProgress DidChange,
and have a custom renderer to
render progress when we get that
event.
So we can look for A list again.
And this time, when I play that
song, we see our custom progress
bar rendering.
Now, there's a lot more we could
get into with MusicKit JS, but
I'd like to bring DJ back up to
kind of summarize what we've
gone over today.
[ Applause ]
>> You can now bring great music
experiences to your websites.
You can use the declarative
markup to quickly add simple
functionality or you can use the
JavaScript APIs directly to
build a more advanced
application.
We're looking forward to seeing
what you can build with it.
We have some great documentation
available, and we have a lab
coming up right after this
session in Technology Lab 3.
Happy to answer any questions
you have.
Thank you.
[ Applause ]