2

所以我有一个Node.js脚本和一个 Javascript 文件相互通信,除了Node.js应该返回.mp3文件数据外,一切正常。

数据是二进制的,看起来像乱码,我将如何获取它返回的数据并允许用户使用 Javascript 在网页上下载它?

它顺便获取数据http.responseText

Node.js 代码

//initilization
var querystring = require('querystring');
var http = require('http');
var url = require('url');
var fileSystem = require('fs');
var path = require('path');
var util = require('util');

//convert function
function convert(voiceToUse, textToConvert, response)
{
    console.log("Sending Convert Request...");

    //data to send as a query
    var data = querystring.stringify(
    {
        username: 'user',
        password: 'pass',
        action: 'convert',
        voice: voiceToUse,
        text: textToConvert
    });

    //options to use
    var options = {
        host: 'ws.ispeech.org',
        port: 80,
        path: '/api/rest/1.5',
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Content-Length': data.length
        }
    };

    //http post request
    var req = http.request(options, function (res)
    {
        res.setEncoding('utf8');
        res.on('data', function (chunk)
        {
            console.log("Body: " + chunk);
            var fileId = chunk.substr(chunk.indexOf("fileid") + 7);
            console.log("Converting File...");
            download(fileId.substr(0, fileId.search("&")), response);

        });
    });


    req.on('error', function (e)
    {
        console.log('problem with request: ' + e.message);
    });

    req.write(data);
    req.end();
}

//download function
function download(id, response)
{

    //data to send as a query
    var data = querystring.stringify(
    {
        username: 'user',
        password: 'pass',
        action: 'download',
        fileid: id
    });

    //options to use
    var options = {
        host: 'ws.ispeech.org',
        port: 80,
        path: '/api/rest/1.5',
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Content-Length': data.length
        }
    };

    //http post request
    var req = http.request(options, function (res)
    {
        res.on('data', function (chunk)
        {
            if (JSON.stringify(res.headers).indexOf("audio/mp3") != -1)
            {
                console.log("Downloading Chunk...");
                /*var fs = require('fs'),
                   str = 'string to append to file';
                fs.open('test.mp3', 'a', 666, function (e, id)
                {
                    fs.write(id, chunk, 0, chunk.length, 0, function ()
                    {
                        fs.close(id, function ()
                        {
                        });
                    });
                });*/
                response.write(chunk, "binary");
            }
            else
            {
                download(id, response);
            }

        });

        res.on('end', function ()
        {   
            if (JSON.stringify(res.headers).indexOf("audio/mp3") != -1){
            response.end();
            }
        });
    });


    req.on('error', function (e)
    {
        console.log('problem with request: ' + e.message);
    });

    req.write(data);
    req.end();
}
http = require('http');
fs = require('fs');
server = http.createServer( function(req, res) {

    console.dir(req.param);

    if (req.method == 'POST') {
        console.log("POST");
        var body = '';
        req.on('data', function (data) {
            body += data;
            console.log("Partial body: " + body);
        });
        req.on('end', function () {
            console.log("Body: " + body);
            if(body){
                convert('engfemale1', body, res);
                res.writeHead(200, {
                    'Content-Type': 'audio/mp3', 
                    'Content-Disposition': 'attachment; filename="tts.mp3"'
                });
            }
        });

    }
});

port = 8080;
server.listen(port);
console.log('Listening at port ' + port);

Javascript代码

console.log('begin');
        var http = new XMLHttpRequest();
        var params = "text=" + bodyText;
        http.open("POST", "http://supersecretserver:8080", true);

        http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        //http.setRequestHeader("Content-length", params.length);
        //http.setRequestHeader("Connection", "close");

        http.onreadystatechange = function() {
            console.log('onreadystatechange');
            if (http.readyState == 4 && http.status == 200) {
                alert(http.responseText);//response text is binary mp3 data
            }
            else {
                console.log('readyState=' + http.readyState + ', status: ' + http.status);
            }
        }

        console.log('sending...')
        http.send(params);
        console.log('end');
4

1 回答 1

1

您可以尝试使用数据 URL:

<a href="data:audio/mpeg3;charset=utf-8;base64,Zm9vIGJhcg==">mp3 download</a>

虽然不是最好的浏览器支持。

也可以直接在音频标签中使用数据 URL。


更好的解决方案是将 mp3 保存在您的服务器上的某个地方,并返回一个指向它的链接以供 mp3 播放器使用。

于 2012-08-21T15:21:21.353 回答