I am trying to build a small streaming project using the MediaSource API.
I have a segmented video called earth into 6 segments of around 6 seconds each.
With the current project structure
vids/
earth/
playlist.json
segments/
segment-000.mp4
segment-001.mp4
segment-002.mp4
segment-003.mp4
segment-004.mp4
segment-005.mp4
segment-006.mp4
index.js
index.html
the playlist.json
file is as such
{
"segments": [
{
"url": "http://localhost:3000/vids/earth/segments/segment-000.mp4"
},
{
"url": "http://localhost:3000/vids/earth/segments/segment-001.mp4"
},
{
"url": "http://localhost:3000/vids/earth/segments/segment-002.mp4"
},
{
"url": "http://localhost:3000/vids/earth/segments/segment-003.mp4"
},
{
"url": "http://localhost:3000/vids/earth/segments/segment-004.mp4"
},
{
"url": "http://localhost:3000/vids/earth/segments/segment-005.mp4"
},
{
"url": "http://localhost:3000/vids/earth/segments/segment-006.mp4"
}
]
}
The index.js file is the server code
const express = require('express');
const path = require('path');
const app = express();
const PORT = 3000;
app.get('/index', (req, res)=> res.sendFile(path.join(__dirname, 'index.html')));
app.get('/earth', (req, res)=> res.sendFile(path.join(__dirname, 'earth.mp4')))
app.use('/vids', express.static(path.join(__dirname, 'vids')));
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}`);
});
Finally the index.html file
<!DOCTYPE html>
<html>
<head>
<title>Streaming App</title>
<style>
video {
width: 100%;
max-width: 800px;
}
</style>
</head>
<body>
<h1>Streaming App</h1>
<div id="video-container">
<video id="video-player" controls></video>
</div>
<script>
const videoPlayer = document.getElementById('video-player');
let playlist;
let currentSegmentIndex = 0;
let mediaSource = null;
let sourceBuffer = null;
// Fetch playlist
fetch('/vids/earth/playlist.json')
.then(response => response.json())
.then(data => {
playlist = data;
initMediaSource();
})
.catch(error => console.error('Error fetching playlist:', error));
// Initialize the MediaSource API
function initMediaSource() {
mediaSource = new MediaSource();
videoPlayer.src = URL.createObjectURL(mediaSource);
mediaSource.addEventListener('sourceopen', () => {
sourceBuffer = mediaSource.addSourceBuffer('video/mp4; codecs="avc1.42E01E"');
loadNextVideoSegment();
});
}
// Load the next video segment
function loadNextVideoSegment() {
if (currentSegmentIndex < playlist.segments.length) {
const segmentUrl = playlist.segments[currentSegmentIndex].url;
fetch(segmentUrl)
.then(response => response.arrayBuffer())
.then(data => {
sourceBuffer.appendBuffer(data);
currentSegmentIndex++;
})
.catch(error => console.error('Error loading video segment:', error));
} else {
mediaSource.endOfStream();
}
}
// Move to the next segment when the current one ends
videoPlayer.addEventListener('ended', () => {
loadNextVideoSegment();
});
</script>
</body>
</html>
With this code when clicking the play button, in FF it displays an unending loading screen