File size: 7,541 Bytes
5779747
 
 
 
 
 
8e725cb
5779747
 
 
 
2ad1d64
5779747
2ad1d64
 
5779747
8e725cb
5779747
 
 
 
 
 
 
 
 
 
2ad1d64
 
 
 
 
 
5779747
 
 
 
8e725cb
5779747
 
 
 
 
 
 
8e725cb
5779747
 
 
 
 
 
 
8e725cb
5779747
 
2ad1d64
8e725cb
2ad1d64
8e725cb
2ad1d64
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5779747
8e725cb
 
5779747
 
 
 
 
 
 
 
8e725cb
5779747
8e725cb
5779747
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
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!")