You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 03:15:08