Player Integration
Complete guide to integrate Stream API with video players. Supports Widevine DRM.
Note: Widevine DRM requires HTTPS and a supported browser (Chrome, Firefox, Edge).
Supported Players
Shaka Player
Recommended
Google's open-source player with excellent DRM support.
Video.js
Popular player with EME plugin for DRM.
ExoPlayer
Android native player with Widevine support.
Integration Examples
1. Include Shaka Player
html
<script src="https://cdnjs.cloudflare.com/ajax/libs/shaka-player/4.7.11/shaka-player.compiled.min.js"></script>
<video id="video" width="100%" controls></video>2. Initialize Player
javascript
const API_URL = 'https://stream-api-production-f4f7.up.railway.app';
const API_KEY = 'YOUR_API_KEY';
async function playChannel(epgId, channelId) {
// 1. Get stream data from API
const response = await fetch(
`${API_URL}/api/stream/${epgId}?ch=${channelId}`,
{ headers: { 'X-API-Key': API_KEY } }
);
const data = await response.json();
// 2. Initialize Shaka Player
const video = document.getElementById('video');
const player = new shaka.Player(video);
// 3. Configure DRM
player.configure({
drm: {
servers: {
'com.widevine.alpha': data.drm.server
},
advanced: {
'com.widevine.alpha': {
headers: data.drm.headers
}
}
}
});
// 4. Handle errors
player.addEventListener('error', (e) => {
console.error('Player error:', e.detail);
});
// 5. Load and play
await player.load(data.manifest);
video.play();
}3. Complete HTML Example
html
<!DOCTYPE html>
<html>
<head>
<title>Stream Player</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/shaka-player/4.7.11/shaka-player.compiled.min.js"></script>
<style>
video { width: 100%; max-width: 800px; }
</style>
</head>
<body>
<video id="video" controls></video>
<script>
const API_URL = 'https://stream-api-production-f4f7.up.railway.app';
const API_KEY = 'YOUR_API_KEY';
async function init() {
// Get channels
const channels = await fetch(`${API_URL}/api/channels`, {
headers: { 'X-API-Key': API_KEY }
}).then(r => r.json());
// Play first live channel
const channel = channels.live[0];
if (channel) {
playChannel(channel.epgId, channel.channelId);
}
}
async function playChannel(epgId, channelId) {
const data = await fetch(
`${API_URL}/api/stream/${epgId}?ch=${channelId}`,
{ headers: { 'X-API-Key': API_KEY } }
).then(r => r.json());
const player = new shaka.Player(document.getElementById('video'));
player.configure({
drm: {
servers: { 'com.widevine.alpha': data.drm.server },
advanced: { 'com.widevine.alpha': { headers: data.drm.headers } }
}
});
await player.load(data.manifest);
}
init();
</script>
</body>
</html>Error Handling
javascript
player.addEventListener('error', (event) => {
const error = event.detail;
switch (error.code) {
case shaka.util.Error.Code.LICENSE_REQUEST_FAILED:
console.error('DRM license request failed');
// Refresh stream data and retry
break;
case shaka.util.Error.Code.LOAD_INTERRUPTED:
console.error('Stream loading interrupted');
break;
default:
console.error('Player error:', error.message);
}
});Auto Token Refresh
Stream tokens expire after ~1 hour. Implement auto-refresh for long viewing sessions:
javascript
let refreshInterval;
async function startStream(epgId, channelId) {
await playChannel(epgId, channelId);
// Refresh every 15 minutes
refreshInterval = setInterval(async () => {
const currentTime = player.getMediaElement().currentTime;
await playChannel(epgId, channelId);
player.getMediaElement().currentTime = currentTime;
}, 15 * 60 * 1000);
}
function stopStream() {
clearInterval(refreshInterval);
player.unload();
}