app.config['MAX_CONTENT_LENGTH'] = 100 * 1024 * 1024 # 100MB limit
用女服务员绑架烧瓶:
from waitress import serveserve
(app, host="127.0.0.1", port=5000, max_request_body_size=100 * 1024 * 1024)
limit_request_field_size = 0
limit_request_line = 0
timeout = 300
worker_connections = 1000
尽管进行了这些更改,但提交了较大的请求(音频的30秒)仍然触发413错误。 我排除的是:
小型音频文件(〜100 kb)工作正常。
MACOS防火墙被禁用。 我不使用nginx.
代码片段
frontend(JavaScript) - 录制和提交音频
function processRecording() {
let audioBlob = new Blob(audioChunks, { type: 'audio/webm' });
let reader = new FileReader();
reader.readAsDataURL(audioBlob);
reader.onloadend = function () {
audioDataInput.value = reader.result;
document.querySelector('form').submit();
};
}
@app.route('/speaking_task_submit', methods=['POST'])
def speaking_task_submit():
print(f"Flask MAX_CONTENT_LENGTH: {app.config.get('MAX_CONTENT_LENGTH')} bytes")
print(f"Received Content-Length: {request.content_length} bytes")
if request.content_length and request.content_length > app.config.get('MAX_CONTENT_LENGTH'):
return jsonify({"error": "Request size exceeded!"}), 413
audio_data = request.form['audio_data']
if not audio_data or "," not in audio_data:
return jsonify({"error": "Invalid or missing audio data"}), 400
# Save audio as .webm
audio_content = audio_data.split(",")[1]
audio_file_path = f"uploads/candidate_audio.webm"
with open(audio_file_path, "wb") as audio_file:
audio_file.write(base64.b64decode(audio_content))
return jsonify({"message": "Audio received successfully"})
MACOSMONTEREY
Python3.10Flask3.1.0
WAITRESS3.0.2吉尼康23.0.0
在女服务员,枪支或烧瓶中还有另一个隐藏的限制 我很想念?
from flask import (
Flask,
Response,
abort,
current_app,
render_template,
redirect,
request,
stream_with_context,
url_for
)
from collections import namedtuple
from glob import glob
from mimetypes import add_type, guess_extension, guess_type
from werkzeug.utils import secure_filename
import os
add_type('audio/aac', '.m4a', strict=True)
Record = namedtuple('Record', ('filename', 'created_at'))
app = Flask(__name__)
app.config.from_mapping(
MAX_CONTENT_LENGTH=100*1024*1024,
UPLOAD_FOLDER='uploads',
)
os.makedirs(
os.path.join(
app.instance_path,
app.config.get('UPLOAD_FOLDER', 'uploads')
),
exist_ok=True
)
@app.route('/')
def audio_index():
patterns = [
'*.m4a',
'*.wav',
'*.weba'
]
path = os.path.join(
current_app.instance_path,
current_app.config.get('UPLOAD_FOLDER', 'uploads')
)
records = [
Record(fn[len(path)+1:], os.path.getctime(fn)) \
for ptrn in patterns for fn in glob(os.path.join(path, ptrn))
]
return render_template('index.html', records=records)
@app.post('/audio-upload')
def audio_upload():
if 'audio_file' in request.files:
file = request.files['audio_file']
extname = guess_extension(file.mimetype)
if not extname:
abort(400)
# Check for allowed file extensions.
i = 1
while True:
dst = os.path.join(
current_app.instance_path,
current_app.config.get('UPLOAD_FOLDER', 'uploads'),
secure_filename(f'audio_record_{i}{extname}'))
if not os.path.exists(dst): break
i += 1
file.save(dst)
return redirect(url_for('audio_index'))
@app.route('/audio/stream/<path:filename>')
def audio_download(filename):
@stream_with_context
def generator(src):
CHUNK_SIZE = 8*1024
with open(src, 'rb') as fp:
while True:
data = fp.read(CHUNK_SIZE)
if not data: break
yield data
src = os.path.join(
current_app.instance_path,
current_app.config.get('UPLOAD_FOLDER', 'uploads'),
filename
)
if not os.path.exists(src):
return abort(404)
mime,_ = guess_type(src)
return app.response_class(generator(src), mimetype=mime)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Audio Index</title>
</head>
<body>
<div class="rec-container">
<div class="rec-column rec-column-1">
<button class="rec-btn" id="toggle-rec-btn">Record</button>
</div>
<div class="rec-column rec-column-2">
{% for record in records|sort(attribute='created_at', reverse=True) -%}
<div class="rec-item">
<div class="content">
<span class="rec-title">{{ record.filename }}</span>
<audio
controls
src="{{ url_for('audio_download', filename=record.filename) }}"
></audio>
</div>
</div>
{% endfor -%}
</div>
</div>
<script type="text/javascript">
(function(uploadURL) {
const startButton = document.getElementById('toggle-rec-btn');
startButton.addEventListener('click', function() {
if (!navigator.mediaDevices) {
console.error('MediaDevices not supported.')
return;
}
if (!MediaRecorder.isTypeSupported('audio/webm;codecs=opus')) {
console.error('Unsupported media type.');
return;
}
const constraints = { audio: true };
navigator.mediaDevices.getUserMedia(constraints)
.then(function(stream) {
let chunks = []
const options = { mimeType: 'audio/webm;codecs=opus' };
const recorder = new MediaRecorder(stream, options);
recorder.ondataavailable = event => {
chunks.push(event.data);
};
recorder.onstop = event => {
console.log('Recording stopped.');
let blob = new Blob(chunks, { type: recorder.mimeType });
chunks = [];
startButton.disabled = false;
let formData = new FormData();
formData.append('audio_file', blob);
fetch(uploadURL, {
method: 'POST',
cache: 'no-cache',
body: formData
}).then(resp => {
if (!resp.ok) {
throw new Error('Something went wrong.');
}
window.location.reload(true);
}).catch(err => {
console.error(err);
});
};
recorder.onstart = event => {
console.log('Recording started.');
startButton.disabled = true;
setTimeout(function() { recorder.stop(); }, 30000);
};
recorder.start();
})
.catch(function(err) {
console.error(err);
});
});
})({{ url_for('audio_upload') | tojson }});
</script>
</body>
</html>