The player isn't a black box.It's code you control.
An iframe plays the video and stops there. The player SDK opens the box: your code tells it to play, pause, and seek, listens to every event the viewer triggers, and reads the state at any moment. Web in JavaScript, native in Expo / React Native, the same player becoming a piece of your product on both.
The iframe delivers the video.The experience around it, it won't let you touch.
In the app, the player is part of the product, and the user makes you pay dearly for it. Faced with a bad app experience, 34% switch to the competitor (Compuware, 3,534 consumers). When your player is a closed box, it's your experience that's held hostage by it.
Without the SDK, you're stuck with the controls the iframe came with and the position it decided on. Want a button of your own, a bar of your own, a next step at the end of the lesson? There's no way in. The experience around the video belongs to the box, not to your product.
How the SDK solves itThe viewer pressed play, skipped, reached the end. All of that happens inside the iframe and never reaches your code. Without the events, you can't sync your interface, can't trigger the next step, and end up guessing what happened on screen.
How the SDK solves itWrap an iframe in a webview and call it a native app, and the user notices on the first scroll. In the app the bar is set higher, and the punishment is immediate: the experience stutters, and the person moves on to the next one.
How the SDK solves itThe player becomes yours.On both sides.
The player SDK gives your code three things: command playback, listen to every event, and read the state when you need it. On web it's window.Moviie; on native it's @moviie/player-expo. The names change, the contract is the same, and the player starts obeying your product.
Your code drives the player. Play, pause, seek.
Grab the player and tell it to play, pause, jump to a point, change the speed, go fullscreen. On the site, through window.Moviie; in the app, through the player from useMoviiePlayer. Your button is in command, not the one that came with the default controls.
- play, pause, and seek from your code
- Jump to any second
- Speed, volume, and fullscreen
- The same intent on web and native
The player notifies your UI. In real time.
Subscribe to ready, play, pause, timeupdate, ended and keep your interface in sync with what the viewer does. Paint the bar on timeupdate, open the next step on ended, log whatever you want. getState() gives you a full snapshot of the player at any moment.
- on / once / off to subscribe to events
- ready, play, pause, timeupdate, ended
- getState() for the full state
- Sync your UI with the player
In the app, it's a native component. Not a webview.
@moviie/player-expo runs on top of expo-video, with a truly native player on Expo and React Native, not a wrapped iframe. MoviieProvider at the top, useMoviiePlayer on the screen, MoviieVideo rendering. Native features like Picture-in-Picture and Cast come in through the same door.
- Native player on top of expo-video
- MoviieProvider + useMoviiePlayer + MoviieVideo
- Picture-in-Picture and Cast
- Publishable key mvi_pub_, the secret one stays on the server
The iframe alone,or the iframe with the SDK.
The same player. The difference is who commands it and how much your code can see.
| Iframe only | With the SDK | |
|---|---|---|
| Control play, pause, and seek | through the default controls | through your code |
| Events in your UI | don't arrive | ready, play, timeupdate, ended |
| Read the player's state | no way | getState() any time |
| In the native app | webview | component on top of expo-video |
| Sync your interface | guessing | in real time |
| Picture-in-Picture and Cast | out of your reach | through the same SDK |
The video, both play it the same. The control, only one gives you.
One SDK.The whole platform behind it.
Real documentation
Every method, event, and property in the docs, with examples that run. It's not a 2019 PDF: it's docs.moviie.ai/player-api and player-expo.
The server-side counterpart
The SDK handles the client; the REST api.moviie.ai/v1 and the webhooks handle the data. Both sides talk, each in its own place.
Private video, in your control
Link signed by a short JWT, embed locked by domain. The SDK plays where you allowed it, and your backend is the one that signs.
Subtitles and dubbing
Subtitle and audio tracks arrive in the playback. Your app reads and offers them, with no need to build a subtitle player from scratch.
Stable contract
The player API is versioned: a breaking change only lands on a major version bump. Your code doesn't wake up broken.
Starts fast
The first frame shows almost on the click, delivered from the global network. Your code steps into a player that's already fast.
What you can doand what you can't yet.
Native today is through @moviie/player-expo, for Expo and React Native, running on top of expo-video with a truly native player. A pure Swift SDK for iOS is in development, and Kotlin for Android comes next. The web SDK in JavaScript already runs on any page.
The embed exposes window.Moviie on the page. You grab the player with Moviie.getPlayer(iframe) and call play(), pause(), seek(), and the other methods. Wait for the ready event before commanding it, and from there the player obeys your code.
The entire playback cycle: ready, play, pause, timeupdate, ended, among others. You subscribe with on, once, and off, and use getState() to read a full snapshot of the player at any moment. That's what keeps your UI in sync with the viewer.
No, and on purpose. The player SDK runs on the client, controls playback, and listens to events. The REST api.moviie.ai/v1 and the webhooks run on the server, with your secret key, and handle the data and the backend events. Whoever builds a serious app uses both, each on its own side.
Grab a key.Build the player into your app today.
14-day trial to put the player inside your product: control by code, events in your UI, web and native. The docs are at docs.moviie.ai, with examples that run.