Alright. I’ve now tried creating a simple custom component based on these instructions: Code snippet: create Components without any frontend tooling (no React, Babel, Webpack, etc)
My index.html is below, and mostly functioning. It is posting two messages to the console log for on each segment change, one from within “sendDataToPython” and one from within “hls.on(Hls.Events.FRAG_CHANGED…”
But I am still not receiving a value with Streamlit itself.
<html>
<head>
<style>
#video-container {
position: relative;
width: 100vw;
height: 100vh;
}
#segment-info {
position: absolute;
top: 10px;
left: 10px;
color: #fff;
padding: 5px;
font-family: Arial, sans-serif;
font-size: 14px;
border-radius: 5px;
background-color: rgba(0, 0, 0, 0.5);
}
</style>
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
</head>
<body>
<div id="video-container">
<video id="video" controls autoplay style="width:100vw; height:100vh; object-fit: contain; margin:auto"></video>
<div id="segment-info"></div>
</div>
<script>
function sendMessageToStreamlitClient(type, data) {
var outData = Object.assign({
isStreamlitMessage: true,
type: type,
}, data);
window.parent.postMessage(outData, "*");
}
function init() {
sendMessageToStreamlitClient("streamlit:componentReady", {apiVersion: 1});
}
function setFrameHeight(height) {
sendMessageToStreamlitClient("streamlit:setFrameHeight", {height: height});
}
function sendDataToPython(data) {
console.log("Sending data to Python:", data); // Debugging log
sendMessageToStreamlitClient("streamlit:setComponentValue", data);
}
//var myInput = document.getElementById("myinput");
//function onDataFromPython(event) {
// if (event.data.type !== "streamlit:render") return;
// myInput.value = event.data.args.my_input_value; // Access values sent from Python here!
//}
//myInput.addEventListener("change", function() {
// sendDataToPython({
// value: myInput.value,
// dataType: "json",
// });
//})
//window.addEventListener("message", onDataFromPython);
init();
// Hack to autoset the iframe height.
window.addEventListener("load", function() {
window.setTimeout(function() {
setFrameHeight(document.documentElement.clientHeight)
}, 0);
});
setFrameHeight(535);
document.addEventListener('DOMContentLoaded', function () {
init();
var video = document.getElementById('video');
var videoSrc = 'https://globalbroadcasthub.net/stream/hls/reuters/index.m3u8';
if (Hls.isSupported()) {
var hls = new Hls();
hls.loadSource(videoSrc);
hls.attachMedia(video);
hls.on(Hls.Events.MANIFEST_PARSED, function() {
video.play();
});
hls.on(Hls.Events.FRAG_CHANGED, function(event, data) {
var segmentInfo = document.getElementById('segment-info');
segmentInfo.textContent = 'Current Segment: ' + data.frag.url;
var message = 'Playing Segment: ' + data.frag.url;
console.log('Sending message:', message);
sendDataToPython(data.frag.url);
});
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
video.src = videoSrc;
video.addEventListener('loadedmetadata', function() {
video.play();
});
}
});
let retryCount = 0;
function retrySendingData(data) {
if (retryCount < 5) {
console.log("Retrying to send data:", data); // Debugging log
sendDataToPython(data);
retryCount++;
setTimeout(() => retrySendingData(data), 1000);
}
}
</script>
</body>
</html>
I’ve tried implementing in my Streamlit app with these two lines of codes, after first having created an init.py, which successfully render the video player which is posting the console log messages:
player_message = my_component()
st.write("Received:", player_message)
But again, Streamlit is not receiving the data.