汉疆唐土34 2025-01-04 21:33 采纳率: 66.7%
浏览 10

基于Flask框架的人工智能的音乐创作辅助系统执行时,当前端网页传递数据出错,如何解决?

基于Flask框架的人工智能的音乐创作辅助系统执行时,当前端网页显示

img


出现报错
报错提示就是

img


估计就是前端或后端传递数据传错了。

前端代码

project/template/xx.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>生成旋律</title>
    <link rel="stylesheet" href="../static/layui/css/layui.css">
    <style>
        /* 自定义样式 */
        body {
            background-image: url("../static/images/background.webp");
            background-size: cover;
            background-position: center;
            background-attachment: fixed;
            opacity: 0;
            animation: fadeIn 0.5s ease-out forwards;
        }

        .layui-card {
            background-color: rgba(255, 255, 255, 0.8);
            border-radius: 10px;
            padding: 20px;
        }

        .layui-card-header {
            font-size: 24px;
            font-weight: bold;
            color: #333;
        }

        .layui-card-body {
            color: #555;
        }

        .footer {
            text-align: center;
            margin-top: 40px;
            color: #666;
            font-size: 14px;
        }

        /* 动画:body 渐显 */
        @keyframes fadeIn {
            from {
                opacity: 0;
            }
            to {
                opacity: 1;
            }
        }
    </style>
</head>
<body>
<div class="layui-container">
    <!-- 页面标题 -->
    <div class="layui-row">
        <div class="layui-col-xs12">
            <div class="layui-card">
                <div class="layui-card-header">生成旋律</div>
                <div class="layui-card-body">
                    <p>请选择旋律风格和长度,然后点击“生成旋律”按钮。</p>

<div class="layui-form">
    <label class="layui-form-label">风格</label>
    <div class="layui-input-block">
    <select id="style" class="layui-select">
        <option value="">请选择风格</option> <!-- 提供默认空选项 -->
        <option value="Pop">流行 (Pop)</option>
        <option value="Rock">摇滚 (Rock)</option>
        <option value="Jazz">爵士 (Jazz)</option>
        <option value="Classical">古典 (Classical)</option>
        <option value="Electronic">电子 (Electronic)</option>
        <option value="Folk">民谣 (Folk)</option>
        <option value="Hip-Hop">嘻哈 (Hip-Hop)</option>
        <option value="Blues">蓝调 (Blues)</option>
        <option value="Country">乡村 (Country)</option>
        <option value="World">世界音乐 (World)</option>
    </select>
</div>
    <label class="layui-form-label">长度</label>
    <div class="layui-input-block">
        <input id="length" type="number" value="16" class="layui-input" min="1" max="128">
    </div>
    <button id="generate-button" class="layui-btn layui-btn-normal" style="margin-top: 15px;">生成旋律</button>
</div>

                    <!-- 显示生成结果 -->
                    <div id="result" style="margin-top: 20px;"></div>
                </div>
            </div>
        </div>
    </div>
</div>

<!-- 页脚 -->
<div class="footer">
    © 2024 贵池威廉 | 基于人工智能的音乐创作辅助系统
</div>

<!-- 引入 Layui JS -->
<script src="../static/layui/layui.js"></script>
<script>
document.getElementById('generate-button').addEventListener('click', function() {
    const styleSelect = document.getElementById('style');
    const styleIndex = styleSelect.value; // 获取选中的索引值
    const style = styleSelect.options[styleIndex]?.text?.trim(); // 获取对应的文本值

    const lengthInput = document.getElementById('length').value;
    const length = parseInt(lengthInput, 10);

    // 校验输入
    if (isNaN(length) || length <= 0) {
        document.getElementById('result').innerHTML = `<p style="color: red;">错误: 长度必须是正整数!</p>`;
        return;
    }

    if (!style) {
        document.getElementById('result').innerHTML = `<p style="color: red;">错误: 请选择一个有效的风格!</p>`;
        return;
    }

    // 发送请求
    fetch('/melody_generation', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            style: style,  // 确保传递的是真实的风格名称
            length: length
        })
    })
    .then(response => response.json())
    .then(data => {
        if (data.code === 0) {
            document.getElementById('result').innerHTML = `<p style="color: green;">生成的旋律: ${data.melody.join(', ')}</p>`;
        } else {
            document.getElementById('result').innerHTML = `<p style="color: red;">错误: ${data.msg}</p>`;
        }
    })
    .catch(error => {
        document.getElementById('result').innerHTML = `<p style="color: red;">请求失败: ${error.message}</p>`;
    });
});

// 使用 layui 渲染表单
layui.use(['form'], function() {
    const form = layui.form;
    form.render(); // 渲染表单
});


</script>
</body>
</html>

music_logic.py


import os
import time
import logging
import torch


# 初始化日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)


class LSTMAIModel(torch.nn.Module):
    def __init__(self, input_size, hidden_size, num_layers, output_size):
        super().__init__()  # 正确调用父类的 __init__ 方法
        self.lstm = torch.nn.LSTM(input_size, hidden_size, num_layers)
        self.fc = torch.nn.Linear(hidden_size, output_size)

    def forward(self, x):
        out, _ = self.lstm(x)
        out = self.fc(out)
        return out

    # 添加一个 generate_audio 方法 (stub)
    def generate_audio(self, melody_tensor, style):
        # 假设该方法生成音频的张量作为返回值
        # 这里只是一个示例,您需要根据实际需求实现生成逻辑
        logger.info(f"Generating audio for style: {style}")
        return torch.randn(44100 * 10).numpy()  # 假设 10 秒的音频


class MusicLogic:
    SUPPORTED_STYLES = [
        "Pop", "Rock", "Jazz", "Classical", "Electronic",
        "Folk", "Hip-Hop", "Blues", "Country", "World"
    ]

    def __init__(self, model, output_dir="output"):
        """
        初始化 MusicLogic 实例
        :param model: AI音乐生成模型实例
        :param output_dir: 生成的音乐文件存储目录
        """
        self.model = model
        self.output_dir = output_dir

        # 确保输出目录存在
        os.makedirs(self.output_dir, exist_ok=True)

    def validate_inputs(self, melody, style):
        """
        验证输入的旋律和风格是否有效。
        :param melody: 原始旋律
        :param style: 音乐风格
        :raises ValueError: 如果输入无效
        """
        # 检查 melody 是否为 None 或空张量/列表
        if melody is None:
            raise ValueError("Melody must be provided.")
        if isinstance(melody, torch.Tensor) and melody.numel() == 0:  # 检查张量是否为空
            raise ValueError("Melody tensor cannot be empty.")
        if isinstance(melody, (list, tuple)) and len(melody) == 0:  # 检查列表是否为空
            raise ValueError("Melody list cannot be empty.")

        # 检查 style 是否提供并支持
        if not style:
            raise ValueError("Style must be provided.")
        if style not in self.SUPPORTED_STYLES:
            raise ValueError(f"Unsupported style '{style}'. Supported styles are: {self.SUPPORTED_STYLES}")

    def generate_melody(self, melody, style):
        try:
            logger.debug(f"Received melody:{melody},style:{style}")
            file_name = f"music_{int(time.time())}.wav"
            file_path = os.path.join(self.output_dir, file_name)

            # 验证输入
            self.validate_inputs(melody, style)

            # 将输入的旋律转换为 PyTorch 张量
            if isinstance(melody, torch.Tensor):
                melody_tensor = melody.clone().detach()
            else:
                # 确保 melody 是一个可迭代对象且元素可转换为 float32 类型
                if not isinstance(melody, (list, tuple)):
                    raise ValueError("Melody must be a list or tuple.")
                if len(melody) == 0:
                    raise ValueError("Melody list cannot be empty.")
                melody_tensor = torch.tensor([float(item) for item in melody], dtype=torch.float32).clone().detach()

            # 确保模型和张量在 CUDA 上,如果 CUDA 可用
            device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
            self.model = self.model.to(device)
            melody_tensor = melody_tensor.to(device)

            # 调用 generate_audio 方法生成音频
            audio_data = self.model.generate_audio(melody_tensor, style)

            # 将音频数据转换为 NumPy 数组
            audio_data = torch.tensor(audio_data).cpu().numpy()

            # 保存音频数据到文件
            with open(file_path, "wb") as f:
                f.write(audio_data.tobytes())

            return file_path
        except Exception as e:
            logger.error(f"Error during melody generation: {str(e)}")
            raise RuntimeError(f"Error during melody generation: {str(e)}")

    def generate_audio_stream(self, melody, style):
        """
        流式生成音频数据。
        :param melody: 原始旋律(字符串或其他表示形式)
        :param style: 音乐风格(字符串)
        :yield: 音频数据块
        """
        self.validate_inputs(melody, style)

        try:
            logger.info(f"Starting stream generation for melody: {melody} with style: {style}")
            # 将输入的旋律转换为 PyTorch 张量
            if isinstance(melody, torch.Tensor):
                melody_tensor = melody.clone().detach()
            else:
                # 确保 melody 是一个可迭代对象且元素可转换为 float32 类型
                if not isinstance(melody, (list, tuple)):
                    raise ValueError("Melody must be a list or tuple.")
                melody_tensor = torch.tensor([float(item) for item in melody], dtype=torch.float32).clone().detach()

            # 确保模型和张量在 CUDA 上,如果 CUDA 可用
            device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
            self.model = self.model.to(device)
            melody_tensor = melody_tensor.to(device)

            # 调用AI模型生成完整音频
            full_audio = self.model.generate_audio(melody_tensor, style)

            # 模拟将音频分成小块流式输出
            chunk_size = len(full_audio) // 10  # 分为10段
            for i in range(10):
                time.sleep(0.1)  # 模拟生成延迟
                start = i * chunk_size
                end = (i + 1) * chunk_size if i < 9 else len(full_audio)
                logger.info(f"Streaming chunk {i + 1}/10")
                yield full_audio[start:end]
        except Exception as e:
            logger.error(f"Error during audio stream generation: {str(e)}")
            raise RuntimeError(f"Error during audio stream generation: {str(e)}")
  • 写回答

3条回答 默认 最新

  • 道友老李 JWE233286一种基于机器视觉的水表指针读数识别及修正的方法 专利发明者 2025-01-04 22:00
    关注
    让【道友老李】来帮你解答,本回答参考通义千问大模型编写,并整理提供,如果还有疑问可以点击头像关注私信或评论。
    如果答案让您满意,请采纳、关注,非常感谢!
    根据报错提示和前端代码分析,可能是前端页面传递的数据格式不正确或者后端接收数据的方式发生了错误。首先,建议检查前端页面中传递数据的方式和格式是否正确,并确保与后端接口的数据格式一致。 在前端代码中,我们可以看到一个
  • 标签,其中的<option>标签用来定义下拉选项,每个</option><option>标签都有一个value属性用来表示选项的值。在这里,可能是传递的选项值与后端接口的要求不符合导致报错。 在Flask后端代码中,需要相应地接收前端传递的数据,并进行处理。可以通过request对象获取前端传递的数据,然后进行逻辑处理。如果数据格式有问题,可能导致报错。 下面是一个简单的示例代码,用来演示Flask后端如何接收前端传递的数据: ```python from flask import Flask, request app = Flask(__name) @app.route('/generate_melody', methods=['POST']) def generate_melody(): data = request.get_json() # 获取前端传递的json数据 style = data.get('style') # 从数据中获取风格信息 length = data.get('length') # 从数据中获取长度信息 # 进行音乐生成逻辑处理 # ... return 'Melody generated successfully' if __name__ == '__main__': app.run() ``` 在这个示例中,我们通过`request.get_json()`方法获取前端传递过来的json数据,然后从中提取出所需的风格和长度信息。从而进行音乐生成的逻辑处理。 希望以上内容能帮助您定位并解决问题。如果问题仍然存在,请进一步检查前后端数据传递过程中是否存在其他问题,并调试代码以找出根本原因。 </option>
评论

报告相同问题?

问题事件