Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import os | |
| import json | |
| import time | |
| from filelock import FileLock | |
| from datetime import datetime | |
| # 定义评价标准 | |
| CRITERIA = ["画质清晰度", "物理真实感", "流畅度", "色彩表现", "整体观感"] | |
| # 数据保存路径 | |
| RESULTS_FILE = "results.json" | |
| LOCK_FILE = "results.json.lock" | |
| def save_result(left_video, right_video, selections): | |
| """保存用户的评价结果到文件,使用 FileLock 确保并发安全""" | |
| result = { | |
| "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"), | |
| "left_video": left_video, | |
| "right_video": right_video, | |
| "selections": selections | |
| } | |
| # 确保文件存在 | |
| if not os.path.exists(RESULTS_FILE): | |
| with open(RESULTS_FILE, 'w') as f: | |
| json.dump([], f) | |
| # 使用 FileLock 保证并发安全 | |
| lock = FileLock(LOCK_FILE, timeout=60) # 设置 60 秒超时 | |
| try: | |
| with lock: | |
| # 读取现有数据 | |
| with open(RESULTS_FILE, 'r') as f: | |
| data = json.load(f) | |
| # 添加新结果 | |
| data.append(result) | |
| # 写入更新后的数据 | |
| with open(RESULTS_FILE, 'w') as f: | |
| json.dump(data, f, indent=2) | |
| return True | |
| except Exception as e: | |
| # 如果发生异常,尝试使用备用方法保存 | |
| try: | |
| backup_file = f"backup_{int(time.time())}.json" | |
| with open(backup_file, 'w') as bf: | |
| json.dump([result], bf, indent=2) | |
| return True | |
| except: | |
| return False | |
| def submit_evaluation(left_video, right_video, *selections): | |
| """处理用户提交的评价""" | |
| selections_dict = {} | |
| for i, criterion in enumerate(CRITERIA): | |
| selections_dict[criterion] = "左侧" if selections[i] == "左侧视频更好" else "右侧" | |
| success = save_result(left_video, right_video, selections_dict) | |
| if success: | |
| return "感谢您的评价!您的反馈已成功保存。" | |
| else: | |
| return "保存失败,请稍后再试。" | |
| def create_ui(): | |
| """创建Gradio界面""" | |
| with gr.Blocks(css=""" | |
| .container {max-width: 1200px; margin: 0 auto;} | |
| .header {text-align: center; margin-bottom: 20px;} | |
| .videos {display: flex; gap: 20px;} | |
| .video-container {flex: 1; text-align: center;} | |
| .criteria {margin-top: 30px;} | |
| .criterion {margin-bottom: 15px; padding: 10px; background: #f7f7f7; border-radius: 8px;} | |
| .submit-btn {margin-top: 30px;} | |
| footer {margin-top: 50px; text-align: center; font-size: 0.8em; color: #666;} | |
| """) as demo: | |
| gr.Markdown("# 视频比较评价系统", elem_classes=["header"]) | |
| gr.Markdown("### 请观看下方两个视频,并根据各项标准选择您认为更好的一个", elem_classes=["header"]) | |
| with gr.Row(elem_classes=["videos"]): | |
| with gr.Column(elem_classes=["video-container"]): | |
| gr.Markdown("### 视频 A") | |
| left_video = gr.Video(label="左侧视频", value="./videos/test/test1.mp4") | |
| with gr.Column(elem_classes=["video-container"]): | |
| gr.Markdown("### 视频 B") | |
| right_video = gr.Video(label="右侧视频", value="./videos/test/test2.mp4") | |
| selections = [] | |
| with gr.Group(elem_classes=["criteria"]): | |
| gr.Markdown("## 评价标准") | |
| for criterion in CRITERIA: | |
| with gr.Row(elem_classes=["criterion"]): | |
| gr.Markdown(f"### {criterion}") | |
| selection = gr.Radio( | |
| ["左侧视频更好", "右侧视频更好"], | |
| label="您的选择", | |
| info="请选择您认为在此标准下表现更好的视频" | |
| ) | |
| selections.append(selection) | |
| submit_btn = gr.Button("提交评价", variant="primary", elem_classes=["submit-btn"]) | |
| result = gr.Markdown() | |
| submit_btn.click( | |
| fn=submit_evaluation, | |
| inputs=[left_video, right_video] + selections, | |
| outputs=result | |
| ) | |
| gr.Markdown( | |
| "---\n" | |
| "© 2023 视频比较评价系统 | 感谢您的参与", | |
| elem_classes=["footer"] | |
| ) | |
| return demo | |
| if __name__ == "__main__": | |
| demo = create_ui() | |
| demo.launch() |