简体   繁体   中英

How to send audio file from express(node js) server to flask server?

I uploaded a audio file(ex> wav) at frontend( react) , and succeed sending this file to backend(express / nodejs).

this is my frontend code (App.js)

import React, { useRef, useEffect , useState } from 'react'
import VexFlow from 'vexflow'
import './App.css'
import axios from "axios";
import { Piano } from './components/Piano.js';
import { MIDINOTE } from './global/midinote';

const VF = VexFlow.Flow
const { Formatter, Renderer, Stave, StaveNote } = VF

const clefAndTimeWidth = 60        

export default function App() 
{
  const container = useRef() 
  const rendererRef = useRef()

  let clef = 'treble';
  let timeSignature = '2/4';
  let width = 450;
  let height = 150;

  const [check, setcheck] = useState(0);
  const countUp = ()=>{
    console.log('in countUp' + check);
    setcheck(check+1);
  }

  const [staves, setStaves] = useState([])
  async function getNoteData(){ //get data from Node JS server using axios
    await axios.get("http://172.10.18.168:80/aaa")
    .then((res)=>{
     
    })
    
    axios.get("http://172.10.18.168:80/data/")
    .then((res)=>{
      
      var lists =[]
      for(var i=0;i<Object.keys(res.data).length ; i++){
        var notes = MIDINOTE[res.data['note'+String(i)]['code']]
        //console.log(notes);
        lists.push(notes)
      }
      //staves = lists;
      setStaves([lists])
    });
    console.log(staves)
  }

  useEffect(() => {
    if (rendererRef.current == null) {
      rendererRef.current = new Renderer(
        container.current,
        Renderer.Backends.SVG
      )
    }
    const renderer = rendererRef.current
    renderer.resize(width, height)
    const context = renderer.getContext()
    context.setFont('Arial', 10, '').setBackgroundFillStyle('#eed')
    const staveWidth = (width - clefAndTimeWidth) / staves.length

    let currX = 0
    
    staves.forEach((notes, i) => {
      const stave = new Stave(currX, 0, staveWidth)
      if (i === 0) {
        stave.setWidth(staveWidth + clefAndTimeWidth)
        stave.addClef(clef).addTimeSignature(timeSignature)
      }
      currX += stave.getWidth()
      stave.setContext(context).draw()

      const processedNotes = notes
        .map(note => (typeof note === 'string' ? { key: note } : note))
        .map(note =>
          Array.isArray(note) ? { key: note[0], duration: note[1] } : note
        )
        .map(({ key, ...rest }) =>
          typeof key === 'string'
            ? {
                key: key.includes('/') ? key : `${key[0]}/${key.slice(1)}`,
                ...rest,
              }
            : rest
        )
        .map(
          ({ key, keys, duration = 'q' }) =>
            new StaveNote({
              keys: key ? [key] : keys,
              duration: String(duration),
            })
        )
      Formatter.FormatAndDraw(context, stave, processedNotes, {
        auto_beam: true,
      })
    })
  }, [check,staves])

  const [file,setFile] = useState();
  const [fileName,setFileName] = useState("");

  const saveFile = (e)=>{
    setFile(e.target.files[0]);
    setFileName(e.target.files[0].name);
  };
  const uploadFile = async(e)=>{
    const formData = new FormData();
    formData.append("file" ,file);
    formData.append("fileName" , fileName);
    try{
      const res = await axios.post(
        "http://172.10.18.168:80/upload",
        formData
      );
      console.log(res);
    }catch(ex){
      console.log(ex);
    }
  };

  return (
    <div className="App">
      <div ref={container} />
      <input type="file" onChange ={saveFile}/>
      <button onClick={uploadFile}>Upload</button>
      <button onClick ={countUp} >show music sheet</button>
      <button onClick ={getNoteData} >update music</button>
      <header className="App-header">
        <Piano/>
      </header>
    </div>
  ) 
}

At backend, I received this file and saved at my project directory. this is my backend code. (app.js)

import express, { response } from "express";      
const router = express.Router();
import cors from 'cors';
const app = express();
const port = 80;
import path from 'path'
const __dirname = path.resolve();
import aa from "./testAPI.js";
import { notedata } from "./testAPI.js"; // data from testAPI.js
import fileupload from 'express-fileupload'
import axios from "axios"; 

app.use(cors());
app.use(fileupload());
app.use(express.static("files"));

app.post('/upload' , (req,res)=> {
    console.log('file arrives at backend')

    const newpath = __dirname + "/files"; 
    const file = req.files.file; 
    const filename = file.name;   
    //console.log(__dirname); 

    file.mv(`${newpath}/${filename}`, (err)=>{
        if(err){
            console.log('failed!!')
        }
    });
    
});

app.get('/aaa', (req,res) => {
    aa.getTest();
    res.send('getTest /aaa') 
});

app.get('/bbb', (req,res) => {
    aa.postTest();
    res.send('postTest /bbb')
});

app.get('/data' , (req,res)=>{
    res.json(notedata); 
    console.log('node js ')
    console.log(notedata);
})

app.listen(port, (res) => {
    console.log("connecting");
})

I want to know how to send this received file to flask server. This is my flask code

from flask import Flask, jsonify, request
from flask_restx import Resource, Api, reqparse
import main

app = Flask(__name__)
api = Api(app)
app.config['DEBUG'] = True


@app.route('/ddd')
def index():
    return 'Hello world'


@api.route('/test')
class testAPI(Resource):
    def get(self):

        notes = main.get_notes()
        data = {}
        i = 0
        for n in notes:
            tmp = {
                'second': n[0],
                'code': n[1]
            }
            data['note' + str(i)] = tmp
            i = i + 1

        data = jsonify(data)
        return data

    def post(self):

        parsed_request = request.files.get('content')
        notes = main.post_notes(parsed_request)
        data = {}
        i = 0
        for n in notes:
            tmp = {
                'second': n[0],
                'code': n[1]
            }
            data['note' + str(i)] = tmp
            i = i + 1

        data = jsonify(data)
        return data


if __name__ == '__main__':
    app.run(host="0.0.0.0", port="5000",  debug=True)

It is the same as sending a file from your React app to the Express server. (Just use FormData)

First, create a endpoint in your Flask server to receive the file.

@app.route('/upload_express_to_flask', methods=['POST'])
    def upload_express_to_flask():
        file = request.form['file']
        file_name = request.form['fileName']

        // do something with the received file

Then, use axios in your Express server to send the file to your Flask server. In this case, your Express server acts as a client.

The code below is very simillar from your React app's uploadFile function.

I have added it to your existing /upload endpoint. This will send the file to the Flask server as soon as it receives the file from your React app.

app.post('/upload', async (req, res) => {
    
    // existing code for receiving the file

    const formData = new FormData();
    formData.append('file', file);
    formData.append('fileName', fileName);

    try {

        const res = await axios.post(
            'http://FLASK SERVER URL/upload_express_to_flask',
            formData
        );

        console.log(res);

    } catch(e) {

        console.log(e);

    }
    
});

Also, to use FormData in a Node.js app (Different from React because it is not running on a browser), you should use the form-data package.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM