拼接音频

现有AMR的语音音频n段,要求在HTML5浏览器上播放,并且是在输出流时即进行拼接,不需在浏览器用脚本进行分段播放。根据 AMR文件格式分析 可知,拼接时需要将从第2段开始的amr字节流中去掉前6个字节"#!AMR "。以下两个例子分别是指定Content-Length和使用chunked方式输出,其中chunked方式在移动设备浏览器中不可用。

chunked输出方式:

public class AudioHandler : IHttpHandler
{

public void ProcessRequest(HttpContext context)
{
//参数验证
string voiceUrl = Path.GetFileNameWithoutExtension(context.Request.Url.LocalPath);
if (string.IsNullOrEmpty(voiceUrl))
{
context.Response.StatusCode
= 404;
context.Response.End();
return;
}

//获取音频地址
IAudioContract audio = AudioManager.Create();
GetAudioUrlsArgs args
= new GetAudioUrlsArgs(){ VoiceUrl = voiceUrl};
var result
= audio.GetAudioUrls(args);
if (result == null && result.Status != ExecuteStatus.OK && result.Data == null &&
result.Data.AddressList
== null && result.Data.AddressList.Count <= 0)
{
context.Response.StatusCode
= 404;
context.Response.End();
return;
}

//输出配置
context.Response.ContentType = "audio/amr";
context.Response.BufferOutput
= false;

//输出音频, 移动设置不支持chunked
List<string> filePaths = result.Data.AddressList;
int count = filePaths.Count;
for (int i = 0; i < count; i++)
{
OutputChunkedAudio(context, filePaths[i], (i
== 0) ? true : false);
}
context.Response.Flush();

}

public bool IsReusable
{
get { return false; }
}

private void OutputChunkedAudio(HttpContext context, string filePath, bool first)
{
bool deleted = first ? true : false;

Stream outputStream
= context.Response.OutputStream;
using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
byte[] buffer = new byte[6];
while (true)
{
int count = fileStream.Read(buffer, 0, 6);
if (count == 0)
{
return;
}
if (!deleted)
{
deleted
= true;
continue;
}

//context.Response.Write(Encoding.UTF8.GetString(buffer));
outputStream.Write(buffer, 0, count);
}

}
}

}

指定Content-Length的方式:

public class AudioHandler : IHttpHandler
{

public void ProcessRequest(HttpContext context)
{
//参数验证
string voiceUrl = Path.GetFileNameWithoutExtension(context.Request.Url.LocalPath);
if (string.IsNullOrEmpty(voiceUrl))
{
context.Response.StatusCode
= 404;
context.Response.End();
return;
}

//获取音频地址
IAudioContract audio = AudioManager.Create();
GetAudioUrlsArgs args
= new GetAudioUrlsArgs(){ VoiceUrl = voiceUrl};
var result
= audio.GetAudioUrls(args);
if (result == null && result.Status != ExecuteStatus.OK && result.Data == null &&
result.Data.AddressList
== null && result.Data.AddressList.Count <= 0)
{
context.Response.StatusCode
= 404;
context.Response.End();
return;
}

//输出配置
context.Response.ContentType = "audio/amr";
context.Response.BufferOutput
= false;

//输出音频
List<byte> data = new List<byte>();
List
<string> filePaths = result.Data.AddressList;
int count = filePaths.Count;
for (int i = 0; i < count; i++)
{
LoadFullAudio(filePaths[i], (i
== 0) ? true : false, ref data);
}
context.Response.AppendHeader(
"Content-Length", data.Count.ToString());
context.Response.OutputStream.Write(data.ToArray(),
0, data.Count);
context.Response.Flush();

}

public bool IsReusable
{
get { return false; }
}

private void LoadFullAudio(string filePath, bool first, ref List<byte> data)
{
bool deleted = first ? true : false;

using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
byte[] buffer = new byte[6];
while (true)
{
int count = fileStream.Read(buffer, 0, 6);
if (count == 0)
{
return;
}
if (!deleted)
{
deleted
= true;
continue;
}

for (int i = 0; i < count; i++)
{
data.Add(buffer[i]);
}

}

}
}

}

f

posted @ 2011-05-13 18:51  chenjunbiao  阅读(995)  评论(1编辑  收藏  举报