State machine and bundles in Amazon video player (2019 edition)
Today I had an hour of my free time to learn how Amazon Prime Video Player is working. I’ll show you my small investigation of what I found.
Where is the main script
Playing and pausing is the core functionality of the player. Therefore it’s easy to get where the main script is situated by doing the following:
- Pause the player
- Find
<video>
tag inDevTools > Elements
. It could be 2 video elements, you need the one which is both 100% width and height
- You need
DevTools > Console
to mock standard play method having current video:
1$0.play = () => {2 debugger;3};
-
Then you try to play video using player controls
-
Having
Call Stack
you can go to the file, which initiated a methodplay
-
You now know the main script name, which Amazon Prime pointed at the moment of the debugging to
blob:https://www.amazon.com/1a511ffb-e998-43b9-be96-51b11a55ab37
, you can see it inSources > Page
What can you find interesting inside the script
Private properties
In comparison to Google and Closure Compiler, Amazon Player developers do NOT minify private properties, which is why everybody can read most of the script code without problem, even if you don’t have Source Maps.
State Machine
You can also find this.stateMachine
, this means that all the states and transitions between them are declared inside, not all transitions are allowed though. Anyway it’s better for controlling, testing and debugging (at least better than having a lot of flags with names like isPlaying
, isPause
etc.)
Key is the current state, values are the states which are available for the current state to have a transition to.
Loading a bundle
If you reload the page several times, you can see that a bundle blob:https://www.amazon.com/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
has different names. It means there is a loader where you can find a way to load the script with different names. In DevTools > Network
you can see Initiator
and go from file to file:
- ATVWebPlayer.js
- WebLoader.js
- Inlined script which is added with type
application/json
and has an id —av-wconf-dv-web-player-cfg
, which has a link to a loader
In WebLoader
there is hardcoded AppLoaderConfig
. After reloading several times I couldn’t find a difference. Looks like config of stable version of modules which are used for different purposes. The config looks like that:
A bundle which we had a look into was loaded from ATVWebPlayer.js
as a string of 6MB
size!!! The string is taken from IndexedDB. The object after completed transaction is the following:
From the given string we can create a Blob
, create object url as a script:
And we come back to the script which code initiated play
when we debugged it in the first section. The name of the module is ATVWebCascadesPlayer