bokesyo's picture
Update app.py
b61a481 verified
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Hugging Face Spaces 版本 - LiveKit 实时音视频对话
"""
import gradio as gr
import os
def main():
# 获取 Hugging Face Space 的配置
space_id = os.getenv('SPACE_ID', 'unknown')
with gr.Blocks(
title="LiveKit 实时音视频对话",
css="""
/* 简单清理样式,避免滚动条 */
html, body {
margin: 0 !important;
padding: 0 !important;
overflow: hidden !important;
}
/* 隐藏 Gradio 默认内容区域 */
.gradio-container {
position: relative !important;
overflow: hidden !important;
}
/* iframe 使用固定定位填满整个视口 */
#fullscreen-iframe {
position: fixed !important;
top: 0 !important;
left: 0 !important;
right: 0 !important;
bottom: 0 !important;
width: 100vw !important;
height: 100vh !important;
border: none !important;
margin: 0 !important;
padding: 0 !important;
z-index: 9999 !important;
}
""",
head="""
<script>
// 动态调整 iframe 以适配 Hugging Face Spaces
document.addEventListener('DOMContentLoaded', function() {
document.documentElement.style.overflow = 'hidden';
document.body.style.overflow = 'hidden';
function adjustIframe() {
const iframe = document.querySelector('#fullscreen-iframe');
if (!iframe) return;
// 查找 Hugging Face 顶部导航栏
const hfHeader = document.querySelector('header');
const gradioContainer = document.querySelector('.gradio-container');
let topOffset = 0;
// 计算顶部偏移量
if (hfHeader) {
topOffset = hfHeader.offsetHeight;
console.log('🔍 检测到 HF 导航栏高度:', topOffset + 'px');
} else if (gradioContainer) {
const rect = gradioContainer.getBoundingClientRect();
topOffset = rect.top;
console.log('🔍 使用 Gradio 容器顶部偏移:', topOffset + 'px');
}
// 设置 iframe 位置和大小,避开顶部导航
iframe.style.top = topOffset + 'px';
iframe.style.height = 'calc(100vh - ' + topOffset + 'px)';
console.log('✅ iframe 已调整 - 顶部偏移:', topOffset + 'px', '高度: calc(100vh - ' + topOffset + 'px)');
}
// 多次尝试调整
setTimeout(adjustIframe, 50);
setTimeout(adjustIframe, 200);
setTimeout(adjustIframe, 500);
setTimeout(adjustIframe, 1000);
setTimeout(adjustIframe, 2000);
// 监听窗口大小变化
window.addEventListener('resize', adjustIframe);
console.log('✅ Hugging Face Spaces iframe 自适应已启动');
});
// 模式切换功能(通过键盘)
document.addEventListener('keydown', function(e) {
const iframe = document.querySelector('#fullscreen-iframe');
if (!iframe) return;
// 数字键 0 - 音频模式
if (e.key === '0') {
iframe.src = 'https://openbmb.github.io/MiniCPM-o-Demo/';
console.log('切换到音频模式');
}
// 数字键 1 - 视频模式
else if (e.key === '1') {
iframe.src = 'https://openbmb.github.io/MiniCPM-o-Demo/';
console.log('切换到视频模式');
}
// 数字键 1 - 测试模式
else if (e.key === '3') {
iframe.src = 'https://openbmb.github.io/MiniCPM-o-Demo/';
console.log('切换到视频模式');
}
// R 键 - 刷新
else if (e.key === 'r' || e.key === 'R') {
iframe.src = iframe.src;
console.log('刷新 iframe');
}
});
</script>
"""
) as demo:
# 全屏 iframe,使用 fixed 定位填满可用空间
gr.HTML(f"""
<iframe
id="fullscreen-iframe"
src="https://openbmb.github.io/MiniCPM-o-Demo/"
allowfullscreen
allow="camera; microphone; autoplay; encrypted-media; fullscreen; display-capture; geolocation"
title="LiveKit 实时音视频对话"
onload="console.log('🎙️ LiveKit 应用在 Hugging Face 中加载完成');"
onerror="console.error('❌ LiveKit 应用加载失败');">
</iframe>
<!-- 隐藏的信息面板,按 I 键显示 -->
<div id="info-panel" style="position: fixed; top: 10px; left: 10px; background: rgba(0,0,0,0.8); color: white; padding: 15px; border-radius: 10px; font-size: 12px; z-index: 999999; display: none;">
<h4 style="margin: 0 0 10px 0;">🎙️ LiveKit 实时音视频对话</h4>
<p style="margin: 5px 0;">🏠 Hugging Face Space: {space_id}</p>
<p style="margin: 5px 0;">🌐 嵌入应用: minicpm-omni.openbmb.cn/</p>
<p style="margin: 5px 0;">⌨️ 快捷键:</p>
<p style="margin: 2px 0 2px 20px;">• 0 - 音频模式</p>
<p style="margin: 2px 0 2px 20px;">• 1 - 视频模式</p>
<p style="margin: 2px 0 2px 20px;">• R - 刷新应用</p>
<p style="margin: 2px 0 2px 20px;">• I - 显示/隐藏此面板</p>
</div>
<script>
// I 键显示/隐藏信息面板
document.addEventListener('keydown', function(e) {{
if (e.key === 'i' || e.key === 'I') {{
const panel = document.querySelector('#info-panel');
if (panel) {{
panel.style.display = panel.style.display === 'none' ? 'block' : 'none';
}}
}}
}});
</script>
""", show_label=False)
return demo
if __name__ == "__main__":
demo = main()
print("🎙️ LiveKit Hugging Face Spaces 版本")
print("=" * 50)
print("🌐 嵌入应用: https://35.226.63.1:8008/")
print("🚀 部署平台: Hugging Face Spaces")
print("📱 访问地址: http://localhost:7860")
print("⌨️ 快捷键: 0(音频) 1(视频) R(刷新) I(信息)")
print("=" * 50)
# Hugging Face Spaces 部署配置
demo.launch(
server_name="0.0.0.0",
server_port=7860,
share=False,
show_error=True,
# Hugging Face Spaces 优化配置
)