awacke1's picture
Update app.py
29c477e verified
raw
history blame
7.09 kB
import streamlit as st
import pandas as pd
from datetime import datetime
import os
import base64
from io import BytesIO
from PIL import Image
# 🌟πŸ”₯ Initialize session state like a galactic DJ spinning tracks!
if 'file_history' not in st.session_state:
st.session_state['file_history'] = []
# πŸ“œπŸ’Ύ Save to history like a time-traveling scribe! | πŸ“…βœ¨ save_to_history("πŸ–ΌοΈ Image", "pic.jpg", img_data) - Stamps a pic in the history books like a boss!
def save_to_history(file_type, file_path, img_data):
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
with open(file_path, "wb") as f:
f.write(base64.b64decode(img_data.split(',')[1]))
st.session_state['file_history'].append({
"Timestamp": timestamp,
"Type": file_type,
"Path": file_path
})
# πŸŽ›οΈ Sidebar config like a spaceship control panel!
with st.sidebar:
st.header("πŸŽšοΈπŸ“Έ Snap Shack")
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("πŸ“Έ Live Camera Snap Craze")
# πŸ“ΈπŸ“· JS live camera zone!
st.header("πŸ“ΈπŸŽ₯ Live Snap Zone")
live_camera_html = """
<div>
<select id="cameraSelect"></select>
<button id="startBtn" onclick="toggleStream()">πŸ“· Start Live</button>
<button onclick="takeSnapshot()">πŸ“Έ Snap Now</button>
<video id="video" autoplay playsinline style="width:100%;"></video>
<canvas id="canvas" style="display:none;"></canvas>
</div>
<script>
let stream = null;
const video = document.getElementById('video');
const canvas = document.getElementById('canvas');
let autoCaptureInterval = null;
let isStreaming = false;
// πŸ“ΉπŸ” 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}`;
select.appendChild(option);
});
if (videoDevices.length === 0) {
select.innerHTML = '<option>No cameras found</option>';
}
}
// πŸ“ΈπŸŽ₯ Toggle live stream like a broadcast pro!
async function toggleStream() {
const startBtn = document.getElementById('startBtn');
if (isStreaming) {
stopStream();
startBtn.textContent = 'πŸ“· Start Live';
isStreaming = false;
} else {
const cameraId = document.getElementById('cameraSelect').value;
if (!cameraId) {
alert('No camera selected or available!');
return;
}
const constraints = { video: { deviceId: { exact: cameraId } } };
try {
stream = await navigator.mediaDevices.getUserMedia(constraints);
video.srcObject = stream;
startBtn.textContent = '⏹️ Stop Live';
isStreaming = true;
autoCaptureInterval = setInterval(takeSnapshot, 10000); // Auto-save every 10s
} catch (e) {
alert('Failed to start camera: ' + e.message);
}
}
}
// πŸ“Έβœ‚οΈ Snap a pic like a stealthy paparazzi!
function takeSnapshot() {
if (!stream) return;
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
canvas.getContext('2d').drawImage(video, 0, 0);
const dataUrl = canvas.toDataURL('image/jpeg');
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;
video.srcObject = null;
clearInterval(autoCaptureInterval);
}
}
// 🎬 Kick off the camera party!
enumerateCameras();
</script>
"""
st.markdown(live_camera_html, unsafe_allow_html=True)
# πŸ“ΈπŸ“₯ Handle snapshots from JS
def handle_snapshot():
if "snapshot" in st.session_state:
snapshot_data = st.session_state["snapshot"]
filename = f"snap_{datetime.now().strftime('%Y%m%d_%H%M%S')}.jpg"
save_to_history("πŸ–ΌοΈ Image", filename, snapshot_data)
st.image(Image.open(BytesIO(base64.b64decode(snapshot_data.split(',')[1]))), caption="Latest Snap", use_container_width=True)
del st.session_state["snapshot"]
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()
# πŸ“‚ Upload zone like a media drop party!
st.header("πŸ“₯πŸŽ‰ Drop Zone")
uploaded_files = st.file_uploader("πŸ“Έ Toss Pics", accept_multiple_files=True, type=['jpg', 'png'])
if uploaded_files:
for uploaded_file in uploaded_files:
file_path = f"uploaded_{uploaded_file.name}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.jpg"
save_to_history("πŸ–ΌοΈ Image", file_path, base64.b64encode(uploaded_file.getvalue()).decode())
st.image(Image.open(uploaded_file), caption=uploaded_file.name, use_container_width=True)
# πŸ–ΌοΈ 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]:
if os.path.exists(img['Path']):
st.image(img['Path'], caption=img['Path'], use_container_width=True)
with open(img['Path'], "rb") as f:
img_data = f.read()
st.markdown(f'<a href="data:image/jpeg;base64,{base64.b64encode(img_data).decode()}" download="{os.path.basename(img["Path"])}">πŸ“₯ Snag It!</a>', unsafe_allow_html=True)
else:
st.warning(f"🚨 Missing file: {img['Path']}")
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!")