使用 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
}
请注意,这显然是一项正在进行的工作,需要填补一些东西,但总的来说是可行的
一定是一个简单的问题,但我已经为它苦苦挣扎了一个星期。我有一个超级简单的基于 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
}
请注意,这显然是一项正在进行的工作,需要填补一些东西,但总的来说是可行的