【问题标题】:Take Binary data and save it as an .mp3 file Javascript获取二进制数据并将其保存为 .mp3 文件 Javascript
【发布时间】:2012-08-21 14:45:06
【问题描述】:

所以我有一个 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');

【问题讨论】:

  • 如果您提供文件供下载,为什么还要使用 XMLHttpRequest?
  • 我正在向将文本转换为语音的 node.js 服务器发出发布请求。 javascript 文件从页面中提取文本并在 POST 中发送,它从 node.js 服务器接收二进制 mp3 数据作为响应。
  • 添加的代码可能会有所帮助。
  • 您是否在提醒 mp3 数据?您实际上是在强制将 mp3 数据显示为警告框中的文本。
  • 那只是调试用的,我知道哈哈。

标签: javascript node.js download


【解决方案1】:

您可以尝试使用数据 URL:

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

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

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


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

【讨论】:

  • 我无法在服务器上为脚本以外的任何内容分配任何空间。每天至少会有几千人使用它,因此还需要额外的时间为服务器编写脚本来对所有 mp3 文件进行排序。我会尝试使用数据 URL,但我不确定它的浏览器是否支持这个。
猜你喜欢
  • 2013-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多