John
Deutscher
 Azure媒体服务首席项目经理

随着媒体设备的增多,一项日益增长的需求是,视频流服务能够向用户提供超高音频质量和具有 5.1
环绕音响的优质内容。通过 Azure媒体服务使用
Dolby® Digital Plus多声道环绕音响给您的高清内容进行编码,现可交付到多个平台上,包括智能电视、Xbox、Windows
8 设备、移动设备等。

Dolby®Digital Plus或
Enhanced AC-3(E-AC-3)是一种专为高质量音频而设计的高级环绕音响音频编解码器。此编解码器基于核心
Dolby Digital 技术,是用于影院、广播和家庭影院环绕音响的一种成熟标准,超过 21亿款产品均支持该技术。在本博文中,我将介绍如何通过媒体服务使用此编解码器使您的内容提供优质的音频体验。

概述

在此示例中,编码到
Dolby® Digital Plus 涉及下列步骤:

1.    将源内容上传到您的
Azure媒体服务帐户并创建一个资源

2.    构建自定义编码预设,并将其保存到文件中

3.    提交使用自定义预设对上述资源进行编码的任务

4.    发布输出资源,并创建一个
SAS URL

5.    在应用程序中演示播放

开始之前,让我描述下每个步骤并提供我使用的示例代码。

运行示例代码后,您会获得一个标准
MP4 文件的 URL,文件包含
H.264 视频和 Dolby Digital Plus音频。接下来,您可以使用此
URL在支持 Dolby Digital Plus解码的设备上播放此视频流。Windows
8和 Xbox都有内置的
Dolby Digital Plus解码器,但 Apple设备目前不内置支持此编解码器。我的建议是遵循关于如何使用
Windows 8和 Player Framework测试环绕音响解码的指南。如果您想要在充分环绕音响下播放文件,则需要将
PC连接到能够进行 5.1播放的
AV接收器

上传源内容

开始之前,您需要首先将一些包含高清视频和多声道音频的源内容上传到您的媒体服务帐户。建议使用下列文件格式

  • MPEG-2传输流,使用
    AC-3(也称为 Dolby® Digital)编码的
    5.1音频流

  • ISO MPEG-4 (MP4)文件,包含使用
    AAC编码的 5.1音频

  • WMV文件,包含使用
    WMA Professional编码的 5.1音频

参考CreateAssetAndUploadSingleFile()中的上传源文件的示例代码。

构建自定义预设

如果这是您第一次创建自定义预设,我鼓励您阅读我之前的文章高级编码功能,了解关于如何创建自定义预设的详细信息。

接下来,我将介绍一种自定义预设,可将您的源转码为
MP4 文件,此 MP4文件包含以
4.5 Mbps传输率编码的 720p视频以及传输率为
512 kbps的 5.1声道
Dolby Digital Plus音频。此自定义预设基于“H264宽带
720p
”预设改编。此预设的<AudioProfile>部分经修改使用Dolby
Digital Plus设置

注意:有关如何调整音频编码设置(如此示例中,使用低于 512kbps的比特率)的详细信息,请参阅http://msdn.microsoft.com/zh-cn/library/dn296500.aspx

完成的 XML自定义预设如下,且应保存到本地文件中以用于编码。我使用的名称为“Dolby
Audio Preset.xml”

<?xml version="1.0"encoding="utf-16"?>

<Presets>

<Preset

Version="5.0">

<MediaFile

DeinterlaceMode="AutoPixelAdaptive"

ResizeQuality="Super"

VideoResizeMode="Stretch">

<OutputFormat>

<MP4OutputFormat

StreamCompatibility="Standard">

<VideoProfile>

<MainH264VideoProfile

BFrameCount="3"

EntropyMode="Cabac"

RDOptimizationMode="Speed"

HadamardTransform="False"

SubBlockMotionSearchMode="Speed"

MultiReferenceMotionSearchMode="Balanced"

ReferenceBFrames="False"

AdaptiveBFrames="True"

SceneChangeDetector="True"

FastIntraDecisions="False"

FastInterDecisions="False"

SubPixelMode="Quarter"

SliceCount="0"

KeyFrameDistance="00:00:02"

InLoopFilter="True"

MEPartitionLevel="EightByEight"

ReferenceFrames="4"

SearchRange="64"

AutoFit="True"

Force16Pixels="False"

FrameRate="0"

SeparateFilesPerStream="True"

SmoothStreaming="False"

NumberOfEncoderThreads="0">

<Streams

AutoSize="False"

FreezeSort="False">

<StreamInfo

Size="1280, 720">

<Bitrate>

<ConstantBitrate

Bitrate="4500"

IsTwoPass="False"

BufferWindow="00:00:05" />

</Bitrate>

</StreamInfo>

</Streams>

</MainH264VideoProfile>

</VideoProfile>

<AudioProfile>

<DolbyDigitalPlusAudioProfile

Codec="DolbyDigitalPlus"

EncoderMode="DolbyDigitalPlus"

AudioCodingMode="Mode32"

LFEOn="True"

SamplesPerSecond="48000"

BandwidthLimitingLowpassFilter="True"

DialogNormalization="-31">

<Bitrate>

<ConstantBitrate

Bitrate="512"

IsTwoPass="False"

BufferWindow="00:00:00" />

</Bitrate>

</DolbyDigitalPlusAudioProfile>

</AudioProfile>

</MP4OutputFormat>

</OutputFormat>

</MediaFile>

</Preset>

</Presets>

转码您的源内容

您可以使用
Windows Azure MediaEncoder 转码您的源内容,将自定义预设内容作为配置字符串传输到任务。查看下文示例代码中的
Transcode() 方法,了解涉及的步骤。任务产生的输出资产包含一个 MP4文件,文件中包含与
H.264编码的视频交错的 Dolby Digital Plus音频。

发布输出资源

内容转码之后,您就能为输出资源创建
SAS 定位。查看下文示例代码中的 CreateSASLocator(),了解涉及的步骤。SAS
URI 可传递到您的播放器应用程序中。

示例代码

请注意,本主题中的代码使用Azure媒体服务
.NET SDK扩展
。媒体服务
.NET SDK 扩展是一组扩展方法和帮助功能,可简化您的代码,以简化利用媒体服务进行的开发。

示例代码的
App.Config 文件如下所示

<?xmlversion="1.0" encoding="utf-8"?>

<configuration>

<startup>

<supportedRuntimeversion="v4.0" sku=".NETFramework,Version=v4.5" />

</startup>

<appSettings>

<addkey="MediaServicesAccountName"value="<MediaAccountName>" />

<add key="MediaServicesAccountKey"value="<MediaAccountKey>" />

</appSettings>

<runtime>

<assemblyBindingxmlns="urn:schemas-microsoft-com:asm.v1">

<dependentAssembly>

<assemblyIdentityname="Microsoft.WindowsAzure.Storage"publicKeyToken="31bf3856ad364e35" culture="neutral" />

<bindingRedirectoldVersion="0.0.0.0-4.1.0.0" newVersion="4.1.0.0" />

</dependentAssembly>

</assemblyBinding>

</runtime>

在上述
App.Config 中,将<MediaAccountName><MediaAccountKey>替换为您的媒体服务帐户名称和密钥

此外,我采用了
Dolby 提供的动画短片“Silent”的以下示例
5.1 环绕音响文件。

您可以在此处下载源
MP4 文件
以供您的测试使用。

(©Dolby – Silent由
Dolby提供)

采用的示例代码如下所示。

usingSystem;

usingSystem.Linq;

using System.Configuration;

usingSystem.IO;

usingSystem.Text;

usingSystem.Threading;

usingSystem.Threading.Tasks;

usingSystem.Collections.Generic;

usingSystem.Diagnostics;

usingSystem.Globalization;

usingMicrosoft.WindowsAzure;

using Microsoft.WindowsAzure.MediaServices.Client;

namespaceDeliveringPremiumAudio

{

/// <summary>

///

/// </summary>

class Program

{

//
从 App.config文件中读取值。

private static readonly string_mediaServicesAccountName =

ConfigurationManager.AppSettings["MediaServicesAccountName"];

private static readonly string_mediaServicesAccountKey =

ConfigurationManager.AppSettings["MediaServicesAccountKey"];

private static readonly string_storageConnectionString =

ConfigurationManager.AppSettings["StorageConnectionString"];

private static CloudMediaContext_context = null;

private static MediaServicesCredentials_cachedCredentials = null;

//指向示例文件的指针,以及保存的自定义预设
XML

private static readonly string _sampleFile =@"C:\temp\sintel.wmv";

private static readonly string_customPreset = @"C:\temp\Dolby Audio Preset.xml";

static void Main(string[] args)

{

try

{

//在静态类变量中创建和缓存媒体服务凭据

_cachedCredentials =new MediaServicesCredentials(_mediaServicesAccountName,_mediaServicesAccountKey);

//
使用缓存的凭据创建 CloudMediaContext

_context = newCloudMediaContext(_cachedCredentials);

//
步骤 1.上传示例内容并创建资源

IAsset inputAsset =CreateAssetAndUploadSingleFile(AssetCreationOptions.None, _sampleFile);

//
步骤 2.将自定义预设加载到配置字符串中

string configuration =File.ReadAllText(_customPreset);

//
步骤 3.将输入转码

IAsset outputAsset =Transcode(inputAsset, configuration);

//
步骤 4.为输出资源创建
SAS 定位并打印到控制台

if (null != outputAsset)CreateSASLocator(outputAsset);

//
上述方法创建的定位符有效期为 30天

//
测试完成后,您应考虑删除定位

}

catch (Exception ex)

{

Console.WriteLine(ex.Message);

}

}

///<summary>

///
此功能将创建一个空资源

/// </summary>

static private IAssetCreateEmptyAsset(string assetName, AssetCreationOptions assetCreationOptions)

{

var asset =_context.Assets.Create(assetName, assetCreationOptions);

Console.WriteLine("Assetname:" + asset.Name);

Console.WriteLine("Timecreated:" + asset.Created.Date.ToString());

return asset;

}

/// <summary>

///
此功能创建了一个资源,并将输入文件上传至其中

/// </summary>

static public IAssetCreateAssetAndUploadSingleFile(AssetCreationOptions assetCreationOptions,string singleFilePath)

{

var fileName =Path.GetFileName(singleFilePath);

//
创建唯一的资源名称

var assetName = fileName +DateTime.UtcNow.ToString();

var asset =CreateEmptyAsset(assetName, assetCreationOptions);

var assetFile =asset.AssetFiles.Create(fileName);

Console.WriteLine("CreatedassetFile {0}", assetFile.Name);

//为上传文件,我们需要具有适当访问政策的定位

var accessPolicy = _context.AccessPolicies.Create(assetName,TimeSpan.FromDays(30),

AccessPermissions.Write | AccessPermissions.List);

var locator =_context.Locators.CreateLocator(LocatorType.Sas, asset, accessPolicy);

assetFile.Upload(singleFilePath);

Console.WriteLine("Doneuploading {0}", assetFile.Name);

Console.WriteLine("");

long size =assetFile.ContentFileSize;

locator.Delete();

accessPolicy.Delete();

return asset;

}

///<summary>

///
此功能使用提供的预设将源资源转码,并返回输出资源

/// </summary>

static public IAsset Transcode(IAssetsourceAsset, string preset)

{

//
申报新作业。

IJob job = _context.Jobs.Create("TranscodingJob for " + sourceAsset.Name);

//
获取 Windows Azure MediaEncoder参考,向其传递

//
此特定任务使用的处理器名称。

IMediaProcessor processor =GetLatestMediaProcessorByName("Windows Azure Media Encoder");

//使用字符串预设创建一个包含编码详细信息的任务。

ITask task = job.Tasks.AddNew("Transcoding Task for "+ sourceAsset.Name,

processor,

preset,

Microsoft.WindowsAzure.MediaServices.Client.TaskOptions.None);

//
指定要编码的源资源。

task.InputAssets.Add(sourceAsset);

//
添加输出资源,以包含作业结果。

//
输出指定为AssetCreationOptions.None,这表示

//
输出资源未加密。

task.OutputAssets.AddNew("Output asset", AssetCreationOptions.None);

//使用下面的事件处理程序查看作业进度。

job.StateChanged += new

EventHandler<JobStateChangedEventArgs>(StateChanged);

//启动作业。

job.Submit();

//检查作业执行情况,等待作业完成。

Task progressJobTask =job.GetExecutionProgressTask(CancellationToken.None);

progressJobTask.Wait();

//获取更新的作业参考。

job = GetJob(job.Id);

//如果作业状态为错误,作业进度的事件处理

//方法应该会记录错误。这里我们查找

//错误状态并在需要时退出。

if (job.State == JobState.Error)

{

Console.WriteLine("Transcode() failed, exiting...");

return null;

}

//
从作业中获取输出资产的参考。

IAsset outAsset = job.OutputMediaAssets[0];

return outAsset;

}

/// <summary>

///
此功能返回指定媒体处理器最新版本的参考

/// </summary>

private static IMediaProcessorGetLatestMediaProcessorByName(string mediaProcessorName)

{

var processor =_context.MediaProcessors.Where(p => p.Name == mediaProcessorName).

ToList().OrderBy(p => newVersion(p.Version)).LastOrDefault();

if (processor == null)

throw new ArgumentException(string.Format("Unknownmedia processor", mediaProcessorName));

return processor;

}

/// <summary>

///
处理事件的帮助程序方法

/// </summary>

private static void StateChanged(objectsender, JobStateChangedEventArgs e)

{

Console.WriteLine("Job statechanged event:");

Console.WriteLine(" 
Previous state:" + e.PreviousState);

Console.WriteLine(" 
Current state:" + e.CurrentState);

switch (e.CurrentState)

{

case JobState.Finished:

Console.WriteLine();

Console.WriteLine("********************");

Console.WriteLine("Jobis finished.");

Console.WriteLine("Please wait while local tasks or downloadscomplete...");

Console.WriteLine("********************");

Console.WriteLine();

Console.WriteLine();

break;

case JobState.Canceling:

case JobState.Queued:

case JobState.Scheduled:

case JobState.Processing:

Console.WriteLine("Please wait...\n");

break;

case JobState.Canceled:

case JobState.Error:

//将发送者转换为作业。

IJob job = (IJob)sender;

//必要时显示或记录错误详细信息。

LogJobStop(job.Id);

break;

default:

break;

}

}

/// <summary>

///
记录失败作业信息的帮助程序方法

/// </summary>

private static void LogJobStop(stringjobId)

{

StringBuilder builder = newStringBuilder();

IJob job = GetJob(jobId);

builder.AppendLine("\nThe jobstopped due to cancellation or an error.");

builder.AppendLine("***************************");

builder.AppendLine("JobID:" + job.Id);

builder.AppendLine("JobName:" + job.Name);

builder.AppendLine("JobState:" + job.State.ToString());

builder.AppendLine("Jobstarted (server UTC time):" + job.StartTime.ToString());

//记录任何存在的作业错误。

if (job.State == JobState.Error)

{

builder.Append("ErrorDetails:\n");

foreach (ITask task injob.Tasks)

{

foreach (ErrorDetail detailin task.ErrorDetails)

{

builder.AppendLine(" TaskId:" + task.Id);

builder.AppendLine("   ErrorCode:" + detail.Code);

builder.AppendLine("   ErrorMessage:" + detail.Message + "\n");

}

}

}

builder.AppendLine("***************************\n");

Console.Write(builder.ToString());

}

/// <summary>

///
此功能为给定资源创建
SAS 定位

/// </summary>

private static voidCreateSASLocator(IAsset asset)

{

Console.WriteLine("Publishingasset " + asset.Name);

//
创建原始定位,发布输出资源。

//确定只读访问策略并

//指定资源可访问的时限为
30天。

_context.Locators.Create(

LocatorType.Sas,

asset,

AccessPermissions.Read,

TimeSpan.FromDays(30));

//
为此 MP4文件生成
SAS定位符。

var mp4AssetFile =asset.AssetFiles.ToList().Where(f => f.Name.EndsWith(".mp4",StringComparison.OrdinalIgnoreCase)).FirstOrDefault();

Uri mp4Uri =mp4AssetFile.GetSasUri();

Console.WriteLine("Output isnow available for progressive download: ");

Console.WriteLine(mp4Uri.OriginalString);

return;

}

}

}

播放演示

演示播放的一个简单方法是在
Windows 8.1 上启动 Windows Media Player应用程序,转至
File\Open URL(文件\打开
URL),输入编码后的资源的 SAS路径。

如果您的 PC已连接到能够进行
5.1播放的 AV接收器,您将能够听到完整
5.1环绕音响输出。

您可以在此处下载我的编码成果示例。

注意事项

使用立体声进行编码

如果您的输入资源是立体声,则
Azure Media Encoder 会在环绕声道中插入静音 –输出资源仍然包含
5.1音频。请注意,仅当以 Smooth Streaming格式交付输出内容时才建议插入静音。

或者,您也可以修改 <DolbyDigitalPlusAudioProfile>元素,参考编码成
Dolby Digital Plus 立体声

XML 记录的设置,从而使编码为立体声输出。

通过 Smooth Streaming进行
Dolby Digital Plus音频的流式传输

可以将
Dolby Digital Plus 音频传送到 Windows 8.1上的现代化应用程序或者通过
Smooth Streaming传送到 Xbox One。为实现这一点,您需要对示例代码进行如下修改

之后,您将需要使用针对 Windows 8的
Smooth Streaming客户端 SDK构建一个
Windows 8现代化应用程序。有关使用 Smooth Streaming客户端
SDK构建应用程序以播放 Dolby内容的详细信息,请阅读文章“如何构建
Smooth Streaming Windows Store 应用程序

目前并非所有平台(如 Apple iOS)都支持
Dolby 解码器,但市场上有很多其他的客户端框架支持机顶盒和智能电视等设备上的 Dolby
解码。如果您想要使用其他设备,则需要向设备制造商确认支持的解码器。

启用 Dolby Professional Loudness Metering

过去,很多使用多声道音频的广播公司都碰到过原声带平均音量高于或低于其他节目音量的问题。您可能也遇见过此问题,比如在节目间歇听到了声音很大的商业广告。另外,当环绕音响内容以立体或单声道音频输出形式在电视机上播放时,也会出现问题。如
Dolby 的此报告中所述,使用多声道音频的一个常见问题是在不同节目之间保持音量稳定一致的问题。要解决这个问题,建议的做法是在
Dolby Digital Plus 流中指定对话音量参数(也称为对话规范化或 DialNorm)。该值将音频音量设置为预设水平,可帮助解码器在不同节目之间进行音量水平的匹配,并摆脱烦人的音量变化。

上文提供的预设假设源内容的默认对话规范化值为 -31 dB。请参阅“使用
Dolby Professional Loudness Metering (DPLM) 支持
”部分,了解如何测量源内容对话的实际音量以及如何为对话规范化设置正确的值。

要了解有关 Dolby Digital Plus技术的更多内容,请在此Dolby页面查看我们合作伙伴提供的详细信息。

如果你有任何疑问,欢迎访问MSDN社区,由专家来为您解答Windows
Azure各种技术问题,或者拨打世纪互联客户服务热线400-089-0365/010-84563652咨询各类服务信息。

本文翻译自:http://azure.microsoft.com/blog/2014/09/03/delivering-premium-audio-experiences-with-dolby-digital-plus/

利用 Dolby® Digital Plus 提供优质音频体验的更多相关文章

  1. Camel Games借助AWS在爆发式增长中提供优质游戏体验

    关于Camel Games Camel Games 成立于2009年,是中国首家得到google市场官方认证的顶尖开发公司.长期以来,Camel Games始终依靠于率先的技术背景,致力于成为国际一流 ...

  2. 提升 RTC 音频体验 - 从搞懂硬件开始

    前言 RTC(实时音视频通信)技术的快速发展,助力了直播.短视频等互动娱乐形式的普及:在全球疫情持续蔓延的态势下,云会议需求呈现爆发式增长,进一步推动了 RTC 行业的快速发展.为了给客户提供稳定可靠 ...

  3. 利用纯java捕获和播放音频

    参考: 1.http://www.cjsdn.net/doc/jdk60/javax/sound/sampled/package-summary.html 2.http://www.cjsdn.net ...

  4. 优质办公体验,掌上OA一机hold住全场

    20多年前,人们希望可以脱离文件满天飞的办公办公环境,OA办公自动化出现了:随后.人们希望能在不同部门.不同分支机构间互通有无,打破信息孤岛.应用孤岛.数据孤岛,协同OA出现了:今天,人们梦想随时随地 ...

  5. bilibili携手WeTest,保障视频类应用优质适配体验

    WeTest 导读 中国移动视频用户规模越来越大,各类移动视频APP也百家争鸣, B站作为国内知名的年轻人文化社区,bilibili在推出移动端时,除了坚持自身的独特定位以外,对其APP的质量也十分重 ...

  6. SpringCloud03 Ribbon知识点、 Feign知识点、利用RestTemplate+Ribbon调用远程服务提供的资源、利用feign调用远程服务提供的资源、熔断

    1 远程服务资源的调用 1.1 古老的套路 在微服务出现之前,所有的远程服务资源必须通过RestTemplate或者HttpClient进行:但是这两者仅仅实现了远程服务资源的调用,并未提供负载均衡实 ...

  7. 苹果XR手机的音频体验测试总结

    苹果XR手机的音频   苹果XR算是苹果手机历史上一个里程碑的型号了,是苹果憋了两年的大招,连苹果9的称号就不要了.直接是X.说明苹果对它给予的希望很大.作为一个音频算法工程师,一直想体验一下XR的音 ...

  8. 利用Effmpeg 提取视频中的音频(mp3)

    在B站看到一个up发的病名为爱的钢琴曲,感觉很好听,然后当然是要加入歌单啊.然而不知道怎么转换成mp3,找来找去找到了EFFmpeg 这篇只是达到了我简单的需求,以后可能会有EFFmpeg更详细的使用 ...

  9. 利用WINDOWS活动目录提供LDAP的方案

    Windows Server 2008 R2 活动目录服务安装 http://blog.sina.com.cn/s/blog_622de9390100kgv3.html WINDOWS 2008 域控 ...

随机推荐

  1. 开发日志系列:一个表单页面的呈现与提交(一)——JSON的操作

    JSON操作 引子 最近在做一个表单页面,大概是这个样子的 这里打算用一个JSON存储所有的信息,我们可以理解为,所有东西都存在一个字符串里面.方便,快捷,易读,数据库操作也方便了.甚至,可以将很多不 ...

  2. bat文件的妙用1-一键开启所有开发软件

    每天早上来的第一件事情,就是打开电脑,然后开一堆的软件 1.wamp 开发环境 2.钉钉   通讯工具 3.PHPstrom 开发工具 4.nodejs.bat Nodejs的扩展(node D:/w ...

  3. WIN7中oracle10g的安装注意事项

    1.本次安装数据库版本为10.2.0.1,操作系统版本为windows7 32位 2.注意在"setup.exe"中以右键属性后,设置以兼容模式及以管理员身份运行该程序:在%安装文 ...

  4. dynamic 动态获取object数据

    1.替代XXX.GetType().GetProperty("YYY").GetValue(XXX) static object GetPerson() { return new ...

  5. fedora 非root用户访问socket 没用权限

    在非root用户下执行基于Libpcap库编写的应用程序时不能正常运行,原因是由于libpcap库使用raw socket的套接字.而Raw Socket的使用需要root权限,否则raw socke ...

  6. smarty模板的基础搭建

    1.下载smarty模板,官方即有 2.解压即可.你会得这样的目录 除了libs文件夹其余都可以删掉(不知道有啥用). 3.在当前目录下分别创建templates.templates_c.cache. ...

  7. Oracle job procedure

    Oracle job procedure 存储过程定时任务 oracle job有定时执行的功能,可以在指定的时间点或每天的某个时间点自行执行任务. 一.查询系统中的job,可以查询视图 --相关视图 ...

  8. pyshp操作shapefile

    ESRI的shp文件自1998发布技术文档以来,shp作为GIS文件的基本交换文件广为使用. 工作中使用shp文件的机会比较多,pyshp是Python操作shapefile的包. 先来说shp文件的 ...

  9. Angular js总结

    之前看过一些angular js的相关技术文档,今天在浏览技术论坛的时候发现有问angular js是做什么用的? 于是有了一个想法,对于自己对angular js 的认知做一个总结. 总结: ang ...

  10. 一般处理程序(ashx)和页面处理程序(aspx)的区别

    客官请看图   图中的Httphandler就是处理程序.   两者的共同点 如果把aspx处理程序和ashx处理程序放到上图中,他们是处在相同的位置的, 他们都实现了IHttphandler接口.实 ...