使用 asp.net mvc 核心保存 blob 文件 (audio/ogg)

save blob file (audio/ogg) using asp.net mvc core

一定是一个简单的问题,但我已经为它苦苦挣扎了一个星期。我有一个超级简单的基于 jquery 的音频捕获 - 我只想将它保存为基于控制器操作的文件。问题是我不知道如何将 blob 文件传递​​给控制器​​。这是我必须捕获音频的代码(见下文)。使用图像我可以使用

document.getElementById("canvas").toDataURL("image/png");

然后将其传递给控制器​​并将其保存为图像,如下所示:

   using (FileStream fs = new FileStream(fileNameWitPath, FileMode.Create))
    {
        using (BinaryWriter bw = new BinaryWriter(fs))
        {
            byte[] data = Convert.FromBase64String(imageData);
            bw.Write(data);
            bw.Close();
        }
        fs.Close();
    }

所以理想情况下,我想要类似于我保存图像的方式。

$(function () {
    $('body').append(
        $('<button/>')
            .attr("id", "start")
            .html("start")
    ).append(
        $('<button/>')
            .attr("id", "stop")
            .html("stop")
    ).append(
        $('<div/>').
            attr("id", "ul")
    )
 
    let log = console.log.bind(console),
        ul = $('#ul')[0],
        start = $('#start')[0],
        stop = $('#stop')[0],
        stream,
        recorder,
        counter = 1,
        chunks,
        media;
    media = {
        tag: 'audio',
        type: 'audio/ogg',
        ext: '.ogg',
        gUM: { audio: true }
    }
    navigator.mediaDevices.getUserMedia(media.gUM).then(_stream => {
        stream = _stream;
        recorder = new MediaRecorder(stream);
        recorder.ondataavailable = e => {
            chunks.push(e.data);
            if (recorder.state == 'inactive') makeLink();  
        };
        log('got media successfully');
    }).catch(log);


    start.onclick = e => {
        start.disabled = true;
        stop.removeAttribute('disabled');
        chunks = [];
        recorder.start();
    }


    stop.onclick = e => {
        stop.disabled = true;
        recorder.stop();
        start.removeAttribute('disabled');
    }
    function makeLink() {
        let blob = new Blob(chunks, { type: media.type })
            , url = URL.createObjectURL(blob)
            , div = document.createElement('div')
            , mt = document.createElement(media.tag)
            , hf = document.createElement('a')
            ;
        mt.controls = true;
        mt.src = url;
        hf.href = url;
        hf.download = `${counter++}${media.ext}`;
        hf.innerHTML = `donwload ${hf.download}`;
        div.appendChild(mt);
        ul.appendChild(div);
    }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

非常感谢

因此,以防万一其他人在上面遇到问题,正如预期的那样,它非常简单(不是最干净的代码,但您可以开始):

创建一个新的 Blob 值:

        recorder.ondataavailable = e => {
        chunks.push(e.data);
        superBuffer = new Blob(chunks, { type: 'audio/ogg' });
        if (recorder.state == 'inactive') makeLink(); //console.log(e.data)

然后使用Ajax发送到服务器:

            var reader = new window.FileReader();
            reader.readAsDataURL(superBuffer);

            reader.onloadend = function () {
                base64 = reader.result;
                base64 = base64.split(',')[1];

                $.ajax({
                    url: 'MyController/Action1',
                    type: 'POST',
                    data: {
                        audioname: "hello",//obviously change to something dynamic
                        chunks: base64
                    },
                    success: function (response) { console.log(response); },
                    error: function (response) { console.log(response); }
                });

然后在代码隐藏中:

        [HttpPost]
    public IActionResult Action1(string audioname, string chunks)
    {

        string fileNameWitPath = Path.Combine(_hostingEnvironment.WebRootPath, "audio", "test.ogg");

        using (FileStream fs = new FileStream(fileNameWitPath, FileMode.Create))
        {
            using (BinaryWriter bw = new BinaryWriter(fs))
            {
                byte[] data = Convert.FromBase64String(chunks);
                bw.Write(data);
                bw.Close();
            }
            fs.Close();
        }
     return Content(chunks) ;//this is for testing - sends back full chunk on success, would probably just want some confirm all is good message
    }

请注意,这显然是一项正在进行的工作,需要填补一些东西,但总的来说是可行的