You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Streamlit项目中实现眼动检测触发的MP3启停控制

解决方案:Streamlit眼部检测联动音频播放

问题根源

st.audio 组件是静态渲染的,无法实时响应视频流中眼部检测状态的动态变化,必须通过前端JS结合Streamlit状态管理来实现播放/暂停的逻辑。

可行实现方案

核心思路:用Streamlit session_state 跟踪眼部检测状态,通过自定义HTML5音频元素+JavaScript来实时控制播放行为,替代原生st.audio。

修改后的完整代码:

import streamlit as st
import streamlit_webrtc as webrtc
import cv2

def data_page():
    st.header("Focus Page")
    
    # 初始化状态变量,跟踪眼睛检测状态
    if "eye_detected" not in st.session_state:
        st.session_state.eye_detected = True

    class VideoTransformer(webrtc.VideoTransformerBase):
        def __init__(self):
            self.eye_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_eye.xml')
            self.current_eye_state = True  # 默认检测到眼睛

        def transform(self, frame):
            img = frame.to_ndarray(format="bgr24")
            gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
            eyes = self.eye_cascade.detectMultiScale(gray, scaleFactor=1.3, minNeighbors=5)

            # 更新检测状态
            self.current_eye_state = len(eyes) > 0

            if not self.current_eye_state:
                cv2.putText(img, "No eyes detected", (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 255), 2, cv2.LINE_4)
            else:
                for (x, y, w, h) in eyes:
                    cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)

            return img

    webrtc_ctx = webrtc.webrtc_streamer(
        key="example", 
        mode=webrtc.WebRtcMode.SENDRECV,
        video_transformer_factory=VideoTransformer
    )

    # 实时同步检测状态到session_state
    if webrtc_ctx.state.playing:
        st.session_state.eye_detected = webrtc_ctx.video_transformer.current_eye_state

    # 自定义音频控件+JS控制逻辑
    # 替换为你的本地MP3文件路径,建议放在与脚本同目录下
    mp3_file_path = "alert.mp3"
    # 读取音频文件为base64(避免跨路径问题)
    import base64
    with open(mp3_file_path, "rb") as f:
        audio_bytes = f.read()
    audio_base64 = base64.b64encode(audio_bytes).decode()

    # 渲染HTML音频元素和控制脚本
    st.markdown(f"""
    <audio id="alert-audio" controls loop style="display:none">
        <source src="data:audio/mp3;base64,{audio_base64}" type="audio/mp3">
    </audio>

    <script>
        const audio = document.getElementById('alert-audio');
        // 监听Streamlit状态变化
        function checkEyeState() {{
            const eyeDetected = {st.session_state.eye_detected};
            if (!eyeDetected && audio.paused) {{
                audio.play();
            }} else if (eyeDetected && !audio.paused) {{
                audio.pause();
                audio.currentTime = 0; // 重置到开头
            }}
        }}
        // 定时检查状态,间隔500ms
        setInterval(checkEyeState, 500);
    </script>
    """, unsafe_allow_html=True)

if __name__ == "__main__":
    data_page()

关键细节说明

  • 状态同步:通过webrtc_ctx.video_transformer.current_eye_state获取实时检测结果,同步到session_state中
  • 音频处理:将本地MP3转为Base64嵌入HTML,避免文件路径访问问题;隐藏原生控件,通过JS自动控制
  • 播放逻辑:JS定时检查状态,未检测到眼睛时自动播放,检测到后暂停并重置音频
  • 性能优化:500ms的检查间隔平衡了实时性和前端性能

内容的提问来源于stack exchange,提问作者Umar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 10:23:11