warhawkmonk commited on
Commit
bf97fde
·
verified ·
1 Parent(s): 2fb5675

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +116 -0
app.py ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from streamlit_webrtc import webrtc_streamer, VideoTransformerBase
3
+ import av
4
+ import threading
5
+ import numpy as np
6
+ from PIL import Image
7
+ import time
8
+ import base64
9
+ from io import BytesIO
10
+ import uuid
11
+
12
+ def get_new_uuid():
13
+ # Generate a random UUID (UUID4) and convert it to a string
14
+ return str(uuid.uuid4())
15
+
16
+ # Usage
17
+
18
+ def numpy_image_to_base64(img_array, format="PNG"):
19
+ # Convert NumPy array to PIL Image
20
+ pil_img = Image.fromarray(img_array)
21
+ # Save PIL Image to a bytes buffer
22
+ buff = BytesIO()
23
+ pil_img.save(buff, format=format)
24
+ # Encode bytes to base64 string
25
+ img_str = base64.b64encode(buff.getvalue()).decode("utf-8")
26
+ return img_str
27
+ def base64_to_image(base64_string):
28
+ # Decode the Base64 string to bytes
29
+ image_data = base64.b64decode(base64_string)
30
+ # Wrap bytes in a BytesIO buffer
31
+ image_buffer = BytesIO(image_data)
32
+ # Open image with PIL
33
+ img = Image.open(image_buffer)
34
+ return img
35
+
36
+ # Initialize session state keys if not present
37
+ if 'current_image' not in st.session_state:
38
+ st.session_state['current_image'] = None
39
+ if 'on' not in st.session_state:
40
+ st.session_state['on'] = False
41
+ if "new_id" not in st.session_state:
42
+ st.session_state["new_id"] = get_new_uuid()
43
+ class VideoTransformer(VideoTransformerBase):
44
+ def __init__(self, params):
45
+ self.frame_lock = threading.Lock()
46
+ self.params = params
47
+ self.buffer_size = 2
48
+ self.frame_buffer = [None] * self.buffer_size
49
+ self.cv = 0 # Circular buffer index
50
+
51
+ def transform(self, frame: av.VideoFrame) -> np.ndarray:
52
+ # Convert frame to numpy array in BGR format
53
+ img = frame.to_ndarray(format="bgr24")
54
+
55
+ # Store frame in circular buffer thread-safely
56
+ with self.frame_lock:
57
+ self.frame_buffer[self.cv] = img
58
+ self.cv = (self.cv + 1) % self.buffer_size
59
+ self.params['current_image'] = img
60
+
61
+ return img
62
+
63
+ def get_latest_frame(self) -> np.ndarray:
64
+ with self.frame_lock:
65
+ idx = (self.cv - 1) % self.buffer_size
66
+ return self.frame_buffer[idx]
67
+
68
+ # Layout with two columns
69
+
70
+ col1, col2 = st.columns(2)
71
+
72
+ with col1:
73
+ # Start the webrtc streamer with audio disabled
74
+ st.code(st.session_state['new_id'])
75
+ ctx = webrtc_streamer(
76
+ key="example",
77
+ video_transformer_factory=lambda: VideoTransformer(st.session_state),
78
+ media_stream_constraints={"video": True, "audio": False},
79
+ async_transform=True,
80
+ )
81
+
82
+ with col2:
83
+ # st.title("Live Video Frame Display")
84
+ text_value = st.text_area(label="Add room id",placeholder="please paste id")
85
+ # Button to toggle frame display on/off
86
+ toggle = st.button("Toggle Frame Display")
87
+
88
+ if toggle:
89
+ st.session_state['on'] = not st.session_state['on']
90
+
91
+ image_placeholder = st.empty()
92
+
93
+ # Display loop: show frames from buffer at ~30 fps when toggled on
94
+ if ctx.video_transformer and st.session_state['on']:
95
+ while True:
96
+ frame = ctx.video_transformer.get_latest_frame()
97
+ if frame is not None:
98
+ # Convert BGR to RGB for correct color display
99
+ value = numpy_image_to_base64(frame)
100
+ with open(st.session_state['new_id']+".txt","w") as write:
101
+ write.write(value)
102
+ # frame_rgb = frame[:, :, ::-1]
103
+ with open(st.session_state['new_id']+".txt","w") as write:
104
+ write.write(value)
105
+ with open(st.session_state['new_id']+".txt") as read:
106
+ temp = read.read()
107
+ img = base64_to_image( temp)
108
+ img = np.array(img)
109
+ img=img[:, :, ::-1]
110
+ image_placeholder.image(img, channels="RGB")
111
+ else:
112
+ image_placeholder.text("Waiting for frames...")
113
+
114
+ time.sleep(1/30) # ~30 fps
115
+ else:
116
+ image_placeholder.text("Click 'Toggle Frame Display' to start showing frames.")