• 拼接音频


    现有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

  • 相关阅读:
    Mac 下VirtualBox与Linux共享文件
    安装LAMP 环境Linux 16.04 + Apache2 + Php7.0
    Python调用OpenCV读写视频
    [tensorflow] FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated
    VS Qt国际化操作
    OpenCV--基于直线检测的文本图像倾斜校正
    Python调用OpenCV形态学
    Keras设置后端数据维度顺序
    Python调用OpenCV代码优化
    Python调用OpenCV滤波
  • 原文地址:https://www.cnblogs.com/chenjunbiao/p/2045783.html
Copyright © 2020-2023  润新知