Spaces:
Sleeping
Sleeping
| 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!") |