배경 : audio/wav
의 MIME 유형으로 데이터를 반환하는 서비스를 사용하고 있습니다. 이 오디오 (현재 MVC 응용 프로그램으로 빌드 됨)에 대한 재생 메커니즘을 제공해야합니다. 예를 들어, 종단점은 다음과 같습니다. https://audio.fooservice.com/GetAudio?audioId=123
wav를 HTTP를 통해 mp3로 실시간으로 변환합니다.
오디오는 8kHz, 1 채널 u-law입니다.
HTML5 <audio>
태그를 사용할 때 다양한 형식의 브라우저가 지원되므로 Internet Explorer에서 재생하지 않기 때문에 원래의 u-law wav를 사용할 수 없습니다.
내 제안 된 솔루션은 소스 형식을 mp3로 실시간 변환하는 것입니다.
나는 여기에 여러 다른 질문에서와 NAudio 포럼에서 부분적으로 작업 솔루션을 함께 자갈길했지만, 아래의 코멘트에 언급 한 바와 같이이 예외가 발생합니다 : 내가 파고 봤는데
private void NAudioTest(string url)
{
Stream outStream = new MemoryStream();
var format = WaveFormat.CreateMuLawFormat(8000, 1);
using (Stream ms = new MemoryStream())
{
var request = (HttpWebRequest)WebRequest.Create(url);
request.KeepAlive = false;
request.ProtocolVersion = HttpVersion.Version10;
using (Stream stream = request.GetResponse().GetResponseStream())
{
using (var reader = new RawSourceWaveStream(stream, format))
{
// reader is not seekable; we need to convert to a byte array to seek
var bytes = reader.ToByteArray();
// create a new stream from the byte aray
var seekableStream = new MemoryStream(bytes);
// instantiating a WaveFileReader as follows will throw an exception:
// "System.FormatException: Not a WAVE file - no RIFF header"
using (var waveReader = new WaveFileReader(seekableStream))
{
using (var pcmStream = WaveFormatConversionStream.CreatePcmStream(waveReader))
{
var pcmBytes = pcmStream.ToByteArray();
var mp3 = pcmBytes.ToMp3();
}
}
}
}
}
}
public static class StreamExtensions
{
public static byte[] ToByteArray(this Stream stream)
{
var ms = new MemoryStream();
var buffer = new byte[1024];
int bytes = 0;
while ((bytes = stream.Read(buffer, 0, buffer.Length)) > 0)
ms.Write(buffer, 0, bytes);
return ms.ToArray();
}
}
public static class ByteExtensions
{
public static byte[] ToMp3(this byte[] bytes)
{
using (var outStream = new MemoryStream())
{
using (var ms = new MemoryStream(bytes))
{
using (var reader = new WaveFileReader(ms))
{
using (var writer = new LameMP3FileWriter(outStream, reader.WaveFormat, 64))
{
reader.CopyTo(writer);
return outStream.ToArray();
}
}
}
}
}
}
대부분의 하루 동안이 주변에서 나는 무언가에 불필요한 복잡성을 도입하는 것처럼 느낍니다. 은 매우 간단해야합니다.처럼 보입니다.
도움을 주시면 감사하겠습니다.
참고 : 소스 형식을 변경할 수 없으며 지원 IE가 필요합니다.
EDIT : RIFF 예외를 해결하고 MP3 스트림을 생성 할 수 있지만 화이트 노이즈 일뿐입니다. 잘하면 나는 그것을 해결할 수 있습니다. 새로운 코드는 다음과 같습니다.
[HttpGet]
public ActionResult GetMp3(string url)
{
if (String.IsNullOrWhiteSpace(url))
return null;
var muLawFormat = WaveFormat.CreateMuLawFormat(8000, 1);
var compressedStream = new MemoryStream();
using (var ms = new MemoryStream())
{
var request = (HttpWebRequest)WebRequest.Create(url);
request.KeepAlive = false;
request.ProtocolVersion = HttpVersion.Version10;
using (Stream webStream = request.GetResponse().GetResponseStream())
{
var buffer = new byte[4096];
int read;
while (webStream != null && (read = webStream.Read(buffer, 0, buffer.Length)) > 0)
ms.Write(buffer, 0, read);
}
ms.Position = 0;
using (WaveStream wav = WaveFormatConversionStream.CreatePcmStream(new RawSourceWaveStream(ms, muLawFormat)))
using (var mp3 = new LameMP3FileWriter(compressedStream, new WaveFormat(), LAMEPreset.MEDIUM_FAST))
wav.CopyTo(mp3);
}
compressedStream.Seek(0, 0);
return new FileStreamResult(compressedStream, "audio/mpeg");
}
소스의 실제 웨이브 형식을'LameMP3FileWriter' 생성자에 제공해야합니다. 'new WaveFormat() 대신'wav.WaveFormat'을 사용하십시오. 그렇지 않으면 잘못된 데이터를 읽게됩니다. – Corey
Corey에게 감사드립니다. 'CreatePcmStream' 메쏘드가 기본'WaveFormat' 생성자와 같은 형식으로 스트림을 리턴 할 것이라고 잘못 가정했습니다. 필자의 소스 스트림에 대한 문서 (및 MIME 형식)가 올바르지 않으며, 일주일 동안 아무 것도하지 않고 보냈다. – LiquidPony