Stream Player · Android · Deep link demo
The player below streams from a public URL. The Open in app button does the same thing using a deep link — and the panels underneath show every step the Android system performs on the way.
Play in the browser, then send the exact same stream to the Android app.
https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8
If the app is not installed, Android reports that nothing can open the link. On a desktop browser the click is simply ignored.
streamplayer://play?url=…
Scan with the camera app. The code contains the custom-scheme link, so the phone opens the app directly — no web server, no network round trip. Your phone just needs Stream Player installed.
The QR updates whenever you switch streams.
Six steps from a web page to a playing video, and the code behind each one.
The page points at a URL with a custom scheme. Android does not treat it as a web address.
<a href="streamplayer://play?url=…" >
The browser cannot render the scheme, so it asks the system for an app that can.
startActivity(Intent(ACTION_VIEW, data))
Android matches the intent filter and picks the app. The filter declares the scheme.
<data android:scheme="streamplayer" />
The launcher activity gets the URI. singleTask means a second tap reuses it.
intent.data → MainActivity
The resolver pulls the real stream URL out of the link, plus any extra headers.
DeepLinkResolver.resolve(uri)
Media3 picks the source type from the extension and starts buffering.
PlayerActivity → ExoPlayer
The real app, on a real phone. Three screens and the moment the link lands.
The app is supported by ads. Here is exactly where they appear.
An adaptive banner sits under the recent list. It stays hidden while it has no fill, so there is never an empty grey strip.
A stream opened through a deep link shows a ten second countdown. When it reaches zero the “Stream Now” button becomes available and the advertisement plays — then the video plays again.
Opening the app from the launcher can show an app open ad. A deep link is never interrupted by one, because the user asked for a specific stream.
Both are wired up and can be triggered from the Advertising section in Settings while you are testing.
Every ad in this build uses Google's official test ad units, so nothing is served to real users and no impressions are recorded.
The builder generates links; the inspector runs the app's own parsing rules on anything you paste.
Pick a shape. The stream above is used automatically.
—
This runs the same rules as DeepLinkResolver.kt.
The custom scheme works immediately. App Links need a domain you control.
| Shape | Example | Notes |
|---|---|---|
streamplayer://play?url=… |
streamplayer://play?url=https%3A%2F%2Fhost%2Fx.m3u8 |
URL-encoded parameter |
streamplayer://play/… |
streamplayer://play/https://host/x.m3u8 |
Stream URL inside the path |
streamplayer://… |
streamplayer://https://host/x.m3u8 |
Raw, no key needed |
https://host/?url=… |
https://player.yourdomain.com/?url=https%3A%2F%2Fhost%2Fx.m3u8 |
App Link — needs assetlinks.json |
https://host/play/… |
https://player.yourdomain.com/play/https%3A%2F%2Fhost%2Fx.m3u8 |
App Link, path form |
https://host/x.m3u8 |
https://player.yourdomain.com/media/x.m3u8 |
Direct media link, no parameter |
&header=Name:Value |
…&header=Referer:https://example.com |
Extra HTTP request header, repeatable |
Media3 selects the parser from the file extension.
Fire a deep link at a connected device.
adb shell am start -a android.intent.action.VIEW \
-d "streamplayer://play?url=https%3A%2F%2Fhost%2Fx.m3u8" \
com.streamplayer.app
adb shell am start -a android.intent.action.VIEW \
-d "https://player.yourdomain.com/play/…" \
com.streamplayer.app