#!/usr/bin/env python3 """ 录音后端服务 - HTTPS 版本 """ from flask import Flask, request, jsonify, send_from_directory from flask_cors import CORS from werkzeug.utils import secure_filename import os import ssl from datetime import datetime app = Flask(__name__) CORS(app) # 配置 UPLOAD_FOLDER = '/home/ubuntu/nanocode/audio-recorder/uploads' ALLOWED_EXTENSIONS = {'webm', 'mp4', 'wav', 'mp3', 'ogg'} MAX_CONTENT_LENGTH = 100 * 1024 * 1024 # 100MB app.config['MAX_CONTENT_LENGTH'] = MAX_CONTENT_LENGTH # 确保上传目录存在 os.makedirs(UPLOAD_FOLDER, exist_ok=True) def allowed_file(filename): return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS @app.route('/api/upload', methods=['POST']) def upload_audio(): """接收音频文件上传""" if 'audio' not in request.files: return jsonify({'error': '没有文件'}), 400 file = request.files['audio'] if file.filename == '': return jsonify({'error': '文件名为空'}), 400 if file and allowed_file(file.filename): timestamp = datetime.now().strftime('%Y%m%d_%H%M%S') filename = f"recording_{timestamp}.webm" filepath = os.path.join(UPLOAD_FOLDER, filename) file.save(filepath) file_size = os.path.getsize(filepath) return jsonify({ 'success': True, 'filename': filename, 'filepath': filepath, 'size': file_size, 'size_human': f"{file_size / 1024:.1f} KB", 'timestamp': timestamp }), 200 return jsonify({'error': '不支持的文件类型'}), 400 @app.route('/api/recordings', methods=['GET']) def list_recordings(): """列出所有录音文件""" recordings = [] for filename in sorted(os.listdir(UPLOAD_FOLDER), reverse=True): if allowed_file(filename): filepath = os.path.join(UPLOAD_FOLDER, filename) stat = os.stat(filepath) recordings.append({ 'filename': filename, 'size': stat.st_size, 'size_human': f"{stat.st_size / 1024:.1f} KB", 'created': datetime.fromtimestamp(stat.st_mtime).isoformat() }) return jsonify({ 'count': len(recordings), 'recordings': recordings }) @app.route('/api/recordings/', methods=['GET']) def get_recording(filename): """获取单个录音文件""" return send_from_directory(UPLOAD_FOLDER, filename) @app.route('/api/health', methods=['GET']) def health_check(): """健康检查""" return jsonify({ 'status': 'ok', 'upload_folder': UPLOAD_FOLDER, 'recordings_count': len([f for f in os.listdir(UPLOAD_FOLDER) if allowed_file(f)]) }) @app.route('/') def index(): return send_from_directory('../frontend', 'index.html') @app.route('/') def static_files(path): return send_from_directory('../frontend', path) if __name__ == '__main__': context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) context.load_cert_chain('/home/ubuntu/nanocode/audio-recorder/cert.pem', '/home/ubuntu/nanocode/audio-recorder/key.pem') print(f"🎙️ HTTPS 录音服务启动中...") print(f"📁 上传目录: {UPLOAD_FOLDER}") print(f"🔒 HTTPS 地址: https://129.211.173.87:8891") print(f"⚠️ 由于是自签名证书,浏览器会显示安全警告,请点击'高级'->'继续访问'") app.run( host='0.0.0.0', port=8891, ssl_context=context, debug=False )