Project Title: “The Weather Man’s Interactive Forecast with Insertable Streams API”
Level: Advanced (Secure context required: https:// or http://localhost)
Description
“The Weather Man” (2005) stars Nicolas Cage as David Spritz, a weather forecaster who struggles with his professional and personal life. This project, “The Weather Man’s Interactive Forecast,” utilizes the Insertable Streams for MediaStreamTrack API to create an interactive weather forecast application where users can add real-time audio commentary to the forecast. This reflects David Spritz’s role as a weatherman, making the weather report more dynamic and engaging.
“Interactive Forecast” allows users to record their weather commentary, process it using insertable streams, and then stream it in real-time, demonstrating the power of the Insertable Streams API for enhancing web applications with media streams.
Starting Code
Beginner Hints:
- Create a single
index.htmlfile. - Copy the full HTML code block into that file.
- Open
index.htmlin your browser. If something doesn’t work, try a local server likepython -m http.server. - Open DevTools Console to spot errors and typos quickly.
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>The Weather Man's Interactive Forecast</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f0f0f0;
color: #333;
text-align: center;
padding: 20px;
}
.container {
background-color: #fff;
padding: 20px;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
max-width: 600px;
margin: 0 auto;
}
h1 {
font-size: 2em;
margin-bottom: 0.5em;
}
button {
padding: 10px 20px;
margin: 10px;
background-color: #007bff;
color: #fff;
border: none;
border-radius: 4px;
cursor: pointer;
}
button:disabled {
background-color: #ccc;
}
button:hover:not(:disabled) {
background-color: #0056b3;
}
#recordingsList {
margin-top: 20px;
}
</style>
</head>
<body>
<div class="container">
<h1>The Weather Man's Interactive Forecast</h1>
<p>Record your weather commentary and see it in action!</p>
<button id="startButton">Start Recording</button>
<button id="stopButton" disabled>Stop Recording</button>
<div id="recordingsList"></div>
</div>
<script>
let mediaRecorder;
let recordedChunks = [];
const startButton = document.getElementById('startButton');
const stopButton = document.getElementById('stopButton');
const recordingsList = document.getElementById('recordingsList');
startButton.addEventListener('click', async () => {
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
if (!('MediaStreamTrackProcessor' in window) || !('MediaStreamTrackGenerator' in window)) {
alert('Insertable Streams API not supported in this browser.');
return;
}
const audioTrack = stream.getAudioTracks()[0];
const processor = new MediaStreamTrackProcessor({ track: audioTrack });
const generator = new MediaStreamTrackGenerator({ kind: 'audio' });
const source = processor.readable;
const sink = generator.writable;
const transformer = new TransformStream({
start() {
console.log('Transformer started');
},
transform(chunk, controller) {
// Process audio data here (e.g., apply filters or effects)
controller.enqueue(chunk);
},
flush() {
console.log('Transformer flush');
}
});
source.pipeThrough(transformer).pipeTo(sink);
const processedStream = new MediaStream([generator]);
mediaRecorder = new MediaRecorder(processedStream, { mimeType: 'audio/webm' });
mediaRecorder.ondataavailable = (event) => {
if (event.data.size > 0) {
recordedChunks.push(event.data);
}
};
mediaRecorder.onstop = () => {
const blob = new Blob(recordedChunks, { type: 'audio/webm' });
const url = URL.createObjectURL(blob);
const audio = document.createElement('audio');
audio.src = url;
audio.controls = true;
recordingsList.appendChild(audio);
recordedChunks = [];
};
mediaRecorder.start();
startButton.disabled = true;
stopButton.disabled = false;
});
stopButton.addEventListener('click', () => {
mediaRecorder.stop();
startButton.disabled = false;
stopButton.disabled = true;
});
</script>
</body>
</html>
References
- Film: “The Weather Man” (2005)
- API: Insertable Streams for MediaStreamTrack API