Alright so now what we want to do is start adding some listeners to our YouTube Player,
so that we can get some feedback when various things happen.
Now the YouTube Player can respond to a number of different events, things like a video playing, pausing,
or being stopped, and can also notify us when the ads that appear at the start of many YouTube videos, start to play.
Now Google have separated these into two different types of events: events that are associated with the playing
of a video, and those that represent a change in the state of the video.
Now this'll make more sense when you see the two listeners that we're going to create.
So I'm going to go ahead with the code and talk about it afterwards,
but firstly what we want to do is create a new playbackEventListener, to handle the playback events.
So what I'm going to do is put that after the onInitializationFailure function.
Down here I'm going to put private val
playback event listener equals object colon YouTubePlayer.Playback
EventListener, and I'm going to add a code block.
Now the playbackEventListener is an interface,
so we have to implement all the methods defined by that interface,
and that's why we've actually got this error over here at the moment, that "object is not abstract and doesn't
implement the abstract member for onSeek". As always Android Studio can automatically create a stub for each
of the functions that we have to implement.
So I'm going to make sure my cursor is inside the code block and do a control I, and I'm going to select all the
methods and click on OK.
And you can see now that we've done that, the error that was an object is now disappeared. Now so that we can
see these methods being called, what I'm going to do is add a Toast message to the onPlaying and onPaused methods.
We're not going to be using the onSeek and onBuffered functions, but we will have to delete the call to TODO,
otherwise our app's going to crash when those functions get called.
So let's go ahead and do that, so we're going to delete this one here, onSeek, delete that,
and also onBuffering, we'll delete, and also onStopped, we'll delete.
Well that leaves the two here, the first one in onPlaying, we will use that, and I'm going to make a Toast message,
so Toast.makeText parentheses, pass
this as the context. But we're going to do something slightly different, we're going to put at, and notice that
there's an option there, this, and then this at YoutubeActivity.
So I'm going to select that second option,
comma double quotes, "Good video is playing OK", and
then Toast.LENGTH_SHORT and new parentheses dot show.
So that's the first one for onPlaying, and let's replace the onPaused with the same code but just change
the text a little bit. Instead of putting "Good video is was playing OK",
we'll put "Video has paused".
So what we've got here is just a listener, like we've attached to buttons for example.
Now I've declared it this way because there's quite a lot of code, and it would look very messy if we added
all this code to the function calls that set the listeners.
So this listener provides the YouTubePlayer with functions that it'll call when the various events happen.
And when a video starts playing for example, it'll call the onPlaying function, and onPaused if we
pause the video, and so on.
So it's really up to you as to what you want to do with these functions. They're not required for the player
to play videos, but this could be an app, perhaps, providing a company's training course for example.
And in that case you could record the fact that the user has watched a video and how far they are through it,
and maybe record it on their employee training plan by adding code in the onStop method.
There's another event that we'll look at next that you could use to record that they'd actually watched
the entire video.
Now the YouTube Player's API is tracking the playback of the video, and giving us the ability to process events when they happen.
So that's the playbackEventListener. So let's actually add the StateChangeListener and see what that does now:
private val playerStateChangeListener equals object colon. This time it's going to be YouTubePlayer.Player
as PlayerStateChangeListener, and now the code block,
and we're going to use control I, making sure your cursor's inside the code block.
We're going to implement all the functions, which then stops the error from appearing now. And we're
going
to actually add some Toast messages to three of them, just so you can see when they're called.
So onAdStarted, let's start with that one,
and I'll paste the old Toast message in, leaving the 'this' at YoutubeActivity, and I'm going to change the
text though for that to be "Click Ad now, make the video creator rich!". OK ,and I'll just take a copy of that.
Now onLoading, we won't bother with that so I'll just delete the TODO in there for that.
onVideoStarted, let's do something for that one.
I'm going to replace that with the Toaster.makeText,
but in terms of the actual text that we're going to display on the screen and the Toast message, we'll
just make it "Video has started". OK so that leaves a few more, so we've still got
onLoaded here, onLoaded we'll delete for now,
so it's got no TODO, onVideoEnded, that's a good spot for another one so let's change the code for that. I'm going to
change the text for that, and the text for the onVideoEnded will be "Congratulations,
"Congratulations! You've completed another video".
OK, we've got one error. Let's delete the code on our error as well.
Now to get a better idea on what these functions are all about,
let's switch back to the Google documentation page of my browser, and I really do recommend that you
actually do this.
Check out the documentation to find out more about the functions you use, because that's how you really
get the hang of what's going on.
And you'll also find out about other things you can do, like that error dialogue that we saw when we looked
at the documentation for the initialization results. Now on the left hand side here, is a table, a sort
of a table of contents for YouTubePlayer, and there's the PlaybackEventListener.
And there it is there, so I'm going to click on that now, PlaybackEventListener, and once I've clicked that, that gives us a
bit of an overview of what the various functions do.
And you probably could have guessed most of this from the names of the functions,
but it's interesting that the onStop method in the PlaybackEventListener's also called then.
So that implies we should get both functions called when the video plays all the way to the end.
Now it's subtle things like this that you'll find out when you read the documentation. Method names and parameters
are generally well chosen and will give you a good idea of what they do,
but you'll only get the full picture
by doing research on line, and the documentation's a great place to start with that.
So after reading that, what I'm going to do is add a Toast message to the onStopped method as well, so
that we can see if we're right
and both methods get called. So back to the onStopped method, and let's paste in some code there, and we'll put "Video has stopped"
there as well.
Alright so we've now set up the listeners that'll respond to the various events,
but at this point we haven't yet told the player to call them.
In fact, Android Studio is showing our two variables in grey, as
you can see here, and also the one further up,
to indicate that they're not actually used anywhere.
So what we need to do is, in the onInitializationSuccess function, we just call set functions
and tell the player where to find the functions you'll need to call back when the events happen.
So we're going to do that in the onInitializationSuccess as I mentioned, and where we want to put this
is before the if not wasRestored code.
So in here we're going to put youTubePlayer question mark dot setPlayerStateChangeListener parentheses, and
that's going to be playerStateChangeListener, then youTubePlayer again,
Question mark dot set, this time it's playbackEventListener parentheses, and
it's going to be playbackEventListener.
So that tells the player again where to find the functions that it'll need to call back when those events
are triggered, or actually, when they actually happen.
Now using anonymous classes inside those calls to setPlayerStateChangeListener and setPlayback
EventListener, would have made the code very messy, which is why we declared variables for them instead.
Alright, so let's actually try running the app and seeing our Toast messages appearing:
Initialized successfully, and Video has stopped, as you can see.
Now when I come over here and tap on the play icon, we got a message, as you can see, a Toast message to say
that the 'Video has played', 'Good video is playing OK', appeared as well.
I'm just going to pause for a minute now, and you can see it says 'Video has paused', and if I start it again,
'Good video is playing OK' again, so we've got that message.
Likewise when I pause, we've got 'Video has paused' again.
And if I actually also go forward a little bit, you can see that we've got that message again, and we can play it again,
'Good video is playing OK' as you can see, so it's actually working quite nicely for us.
The other thing I'll do though now, is skip forward to a few seconds from the end, just so you can see what
happens when the video finishes.
So we got to about the 4:16, play, 'Congratulations you've completed another video'.
You saw that appear, and then 'Video has stopped' also.
So we do get both messages as you can see. The onVideoEnded function of the playerStateChangeListener
displays it's Toast, and then we got the Toast from the onStopped function or the playbackEventListener.
Alright so that's how you use the YouTubePlayer API to play videos in your own apps.
Now we haven't had to write a great deal of code to play the videos, because we used Google's YouTube
API to take care of all the technical details for us.
Now we have covered some important concepts though, including how to add an external library to our code, and also
how to write callback functions that external code calls, when it needs to notify our apps of important events.
Now we've seen callbacks earlier, because a button click event also calls a callback function in our
code to let us respond to the button click, and we're going to be using them a lot in the course, so you'll
get plenty of examples of both callbacks and interfaces. And we'll try to explain them differently each time.
If they don't make sense now they soon will.
Alright so in the next video, we need to make a couple of improvements to the app.
So I'll see you in the next video.