Flask读取/static/uploads目录音频生成频谱图及报错解决
问题修复方案
错误根因
你遇到的TypeError: can only concatenate str (not "NoneType") to str核心触发点在/processing路由:你直接将初始化的None值和路径字符串拼接,自然报错。除此之外你的代码还存在多个逻辑漏洞:
- 上传路由只要被访问,无论是否是POST上传请求,都会直接清空上传目录,刚上传的文件刷新就丢失
- 上传路由开头直接调用
request.files['file'],GET请求没有文件参数时会直接抛出异常 render_template调用时模板名没有加引号,属于语法错误- 跳转到频谱生成页的表单没有传递已上传的文件名,后端无法定位要处理的音频文件
修复后代码
后端app.py
import os import shutil import time from flask import Flask, request, redirect, flash, render_template, session from werkzeug.utils import secure_filename # 自行替换成你的业务逻辑 ALLOWED_EXTENSIONS = {'wav', 'mp3', 'flac'} THIS_DIR = os.path.abspath(os.path.dirname(__file__)) UPLOAD_FOLDER = os.path.join(THIS_DIR,'static','uploads') app = Flask(__name__) # 必须设置SECRET_KEY才能使用session存储上传状态 app.secret_key = '替换为你自己的随机密钥字符串' app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER def allowed_file(filename): return '.' in filename and \ filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS @app.route('/', methods=['GET','POST']) def upload_files(): # 仅在POST上传请求时处理文件逻辑 if request.method == 'POST': if 'file' not in request.files: flash('No file part') return redirect(request.url) file = request.files['file'] if file.filename == '': error = 'No selected file' return render_template('error.html', error = error) if file and allowed_file(file.filename): # 确认有有效上传文件时再清空旧目录 if os.path.exists(UPLOAD_FOLDER): shutil.rmtree(UPLOAD_FOLDER) os.mkdir(UPLOAD_FOLDER) filename = secure_filename(file.filename) file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename)) # 用session存储已上传的文件名,避免前端传参被篡改 session['uploaded_filename'] = filename return render_template('index.html', filename=filename) # GET请求直接返回页面,filename为None return render_template('index.html', filename=None) @app.route("/processing", methods=["POST","GET"]) def processing(): # 先从session取已上传的文件名,不存在就跳回上传页 filename = session.get('uploaded_filename') if not filename: flash('请先上传音频文件') return redirect('/') # 拼接完整的本地文件路径 file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename) # 调用你自己的频谱生成逻辑 fig = create_spectrogram(file_path) # 后续业务逻辑自行补充 # .................................
前端index.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>音频频谱生成</title> </head> <body> <form method="POST" enctype="multipart/form-data"> <input type="file" name="file" accept=".wav,.mp3,.flac" /> <input type="submit" value="Upload" /> {% if filename %} <audio controls> <source src="{{ url_for('static', filename='uploads/' + filename) }}" type="audio/wav"> </audio> <!-- 仅上传成功后显示频谱生成按钮,避免无效提交 --> <form action = "/processing" method = "POST"> <input type = "submit" value="Discover!" > </form> {% endif %} </form> </body> </html>
内容的提问来源于stack exchange,提问作者be_real
相关产品推荐
相关产品推荐

