Spaces:
Sleeping
Sleeping
import streamlit as st | |
import pandas as pd | |
from datetime import datetime | |
import os | |
import threading | |
import time | |
import base64 | |
# ππ₯ Initialize session state like a galactic DJ spinning tracks! | |
if 'file_history' not in st.session_state: | |
st.session_state['file_history'] = [] | |
if 'auto_capture_running' not in st.session_state: | |
st.session_state['auto_capture_running'] = False | |
if 'snapshot_data' not in st.session_state: | |
st.session_state['snapshot_data'] = None | |
# ππΎ Save to history like a time-traveling scribe! | π β¨ save_to_history("πΌοΈ Image", "pic.jpg") - Stamps a pic in the history books like a boss! | |
def save_to_history(file_type, file_path): | |
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") | |
st.session_state['file_history'].append({ | |
"Timestamp": timestamp, | |
"Type": file_type, | |
"Path": file_path | |
}) | |
# πΈβ° Auto-capture every 10 secs like a sneaky shutterbug! | |
def auto_capture(): | |
if st.session_state['auto_capture_running'] and st.session_state['snapshot_data']: | |
snapshot_data = st.session_state['snapshot_data'] | |
filename = f"auto_snap_{datetime.now().strftime('%Y%m%d_%H%M%S')}.jpg" | |
with open(filename, "wb") as f: | |
f.write(base64.b64decode(snapshot_data.split(',')[1])) | |
save_to_history("πΌοΈ Image", filename) | |
threading.Timer(10, auto_capture).start() | |
# ποΈ Sidebar config like a spaceship control panel! | |
with st.sidebar: | |
st.header("ποΈπΈ Snap Shack") | |
if st.button("β° Start Auto-Snap"): | |
st.session_state['auto_capture_running'] = True | |
auto_capture() | |
if st.button("βΉοΈ Stop Auto-Snap"): | |
st.session_state['auto_capture_running'] = False | |
# π Sidebar file outline with emoji flair! | |
st.subheader("π Snap Stash") | |
if st.session_state['file_history']: | |
images = [f for f in st.session_state['file_history'] if f['Type'] == "πΌοΈ Image"] | |
if images: | |
st.write("πΌοΈ Images") | |
for img in images: | |
st.write(f"- {img['Path']} @ {img['Timestamp']}") | |
else: | |
st.write("π³οΈ Empty Stash!") | |
# ππ¨ Main UI kicks off like a cosmic art show! | |
st.title("πΈ WebRTC Snap Craze") | |
# πΈπ· WebRTC camera snap zone! | |
st.header("πΈπ₯ Snap Zone") | |
webrtc_html = """ | |
<div> | |
<select id="cameraSelect"></select> | |
<button onclick="startStream()">π· Start Stream</button> | |
<button onclick="takeSnapshot()">πΈ Snap It!</button> | |
<button onclick="stopStream()">βΉοΈ Stop Stream</button> | |
<video id="video" autoplay playsinline></video> | |
<canvas id="canvas" style="display:none;"></canvas> | |
<img id="snapshot" style="display:none;"> | |
</div> | |
<script> | |
let stream = null; | |
let peerConnection = null; | |
const config = { iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] }; | |
// πΉπ Enumerate cameras like a tech detective! | |
async function enumerateCameras() { | |
const devices = await navigator.mediaDevices.enumerateDevices(); | |
const videoDevices = devices.filter(device => device.kind === 'videoinput'); | |
const select = document.getElementById('cameraSelect'); | |
select.innerHTML = ''; | |
videoDevices.forEach((device, index) => { | |
const option = document.createElement('option'); | |
option.value = device.deviceId; | |
option.text = device.label || `Camera ${index + 1}`; | |
select.appendChild(option); | |
}); | |
} | |
// πΈπ₯ Start streaming like a live broadcast pro! | |
async function startStream() { | |
if (stream) stopStream(); | |
const cameraId = document.getElementById('cameraSelect').value; | |
const constraints = { video: { deviceId: cameraId ? { exact: cameraId } : undefined } }; | |
stream = await navigator.mediaDevices.getUserMedia(constraints); | |
const video = document.getElementById('video'); | |
video.srcObject = stream; | |
peerConnection = new RTCPeerConnection(config); | |
stream.getTracks().forEach(track => peerConnection.addTrack(track, stream)); | |
peerConnection.onicecandidate = event => { | |
if (event.candidate) console.log('ICE Candidate:', event.candidate); | |
}; | |
const offer = await peerConnection.createOffer(); | |
await peerConnection.setLocalDescription(offer); | |
// Simulate remote answer (self-loop for demo) | |
await peerConnection.setRemoteDescription(offer); | |
} | |
// πΈβοΈ Snap a pic like a stealthy paparazzi! | |
function takeSnapshot() { | |
const video = document.getElementById('video'); | |
const canvas = document.getElementById('canvas'); | |
const snapshot = document.getElementById('snapshot'); | |
canvas.width = video.videoWidth; | |
canvas.height = video.videoHeight; | |
canvas.getContext('2d').drawImage(video, 0, 0); | |
const dataUrl = canvas.toDataURL('image/jpeg'); | |
snapshot.src = dataUrl; | |
snapshot.style.display = 'block'; | |
// Send snapshot to Python via session state | |
window.parent.postMessage({ type: 'snapshot', data: dataUrl }, '*'); | |
} | |
// βΉοΈπ΄ Stop the stream like a broadcast kill switch! | |
function stopStream() { | |
if (stream) { | |
stream.getTracks().forEach(track => track.stop()); | |
stream = null; | |
} | |
if (peerConnection) { | |
peerConnection.close(); | |
peerConnection = null; | |
} | |
document.getElementById('video').srcObject = null; | |
document.getElementById('snapshot').style.display = 'none'; | |
} | |
// π¬ Kick off the camera party! | |
enumerateCameras(); | |
</script> | |
""" | |
st.markdown(webrtc_html, unsafe_allow_html=True) | |
# πΈπ₯ Handle snapshots from JS | |
def handle_snapshot(): | |
if "snapshot" in st.session_state: | |
st.session_state['snapshot_data'] = st.session_state["snapshot"] | |
filename = f"snap_{datetime.now().strftime('%Y%m%d_%H%M%S')}.jpg" | |
with open(filename, "wb") as f: | |
f.write(base64.b64decode(st.session_state['snapshot_data'].split(',')[1])) | |
save_to_history("πΌοΈ Image", filename) | |
st.image(filename, caption="Latest Snap", use_column_width=True) | |
del st.session_state["snapshot"] # Clear after saving | |
# Listen for JS messages | |
st.components.v1.html( | |
""" | |
<script> | |
window.addEventListener('message', function(event) { | |
if (event.data.type === 'snapshot') { | |
window.streamlitAPI.setComponentValue({snapshot: event.data.data}); | |
} | |
}); | |
</script> | |
""", | |
height=0 | |
) | |
handle_snapshot() | |
# πΌοΈ Gallery like a media circus! | |
st.header("πͺ Snap Show") | |
if st.session_state['file_history']: | |
images = [f for f in st.session_state['file_history'] if f['Type'] == "πΌοΈ Image"] | |
if images: | |
st.subheader("πΌοΈ Pic Parade") | |
cols = st.columns(3) | |
for i, img in enumerate(images): | |
with cols[i % 3]: | |
st.image(img['Path'], caption=img['Path'], use_column_width=True) | |
st.markdown(f'<a href="data:image/jpeg;base64,{base64.b64encode(open(img["Path"], "rb").read()).decode()}" download="{os.path.basename(img["Path"])}">π₯ Snag It!</a>', unsafe_allow_html=True) | |
else: | |
st.write("π« No snaps yet!") | |
# π History log like a time machine! | |
st.header("β³ Snap Saga") | |
if st.session_state['file_history']: | |
df = pd.DataFrame(st.session_state['file_history']) | |
st.dataframe(df) | |
else: | |
st.write("π³οΈ Nothing snapped yet!") |