AWS: 媒体连接构造库
本单元中更高层次的构件的API是实验性的并正在积极开发中. 在今后任何版本中,它们都须作非背向相容的修改或去除。 这些是 不适用 语义版本 模型和断开的更改 在发行笔记中宣布. 这意味着虽然你可能使用它们,但可能需要更新 当更新到此软件包的更新版本时,您的源代码.
AWS 元素介质连接
AWS Elemental MediaConnect是现场视频的优质运输服务. 它提供卫星和光纤的可靠性和安全性,再加上基于知识产权的网络的灵活性、灵活性和经济学。 MediaConnect使您能够在卫星或纤维服务的时间和成本的一分之一的时间和成本内构建对任务至关重要的视频直播工作流程.
此软件包包含用于与 AWS Elemental MediaConnect 合作的构造, 允许您定义 Flows, Bridges, Gateways, Router 输入器, Router 输出器, 以及 router 网络接口, 用于传输视频流 .
关于AWS元素介质连接的进一步信息,参见: 文件。 。 。 .
目录
路由器资源
MediaConnect路由器提供高性能,低纬度的视频路由能力来构建复杂的直播视频工作流程. 路由器资源包括网络接口,输入和输出.
路由器资源如何关联
路由器资源在管道中共同工作:
- A 类 路由网接口 定义网络连接(公共互联网或VPC)。 基于标准协议的输入和输出需要,但在直接连接到MediaLive输入或MediaConnect时不需要.
- A 类 路由器输入 是切入点——它通过协议(RTP,SRT,RIST)或从MediaConnect流接收源的视频.
- A 类 路由器输出 是退出点——它通过协议向目的地发送视频,向MediaLive输入,或向MediaConnect流量发送视频.
一个典型的相机到云的工作流程看起来像:
Camera → RouterNetworkInterface → RouterInput (SRT) → [Router] → RouterOutput (MediaLive) → MediaLive Channel
路由器坐落在中间,路由内容从投入到产出. 每一个输入都可以有很多输出——例如,一个相机的种子同时传送到MediaLive频道和一个MediaConnect流量.
端到端示例: SRT 源到 MediaLive
以下是一个完整的例子,说明如何通过路由器连接一个SRT源到MediaLive:
declare const stack: Stack;
declare const mediaLiveInput: medialive.IInput;
// 1. A public network interface for the SRT input
const networkInterface = new RouterNetworkInterface(stack, 'NetworkInterface', {
routerNetworkInterfaceName: 'camera-network',
configuration: RouterNetworkConfiguration.publicNetwork({
cidr: ['203.0.113.0/24'],
}),
});
// 2. A router input receiving SRT from an upstream encoder
const input = new RouterInput(stack, 'Input', {
routerInputName: 'camera-input',
maximumBitrate: Bitrate.mbps(10),
routingScope: RoutingScope.REGIONAL,
tier: RouterInputTier.INPUT_20,
configuration: RouterInputConfiguration.standard({
networkInterface,
protocol: RouterInputProtocol.srtListener({
port: 9000,
minimumLatency: Duration.millis(200),
}),
}),
});
// 3. A router output delivering to MediaLive
const output = new RouterOutput(stack, 'Output', {
routerOutputName: 'medialive-output',
maximumBitrate: Bitrate.mbps(10),
routingScope: RoutingScope.REGIONAL,
tier: RouterOutputTier.OUTPUT_20,
configuration: RouterOutputConfiguration.mediaLiveInput({
input: mediaLiveInput,
pipeline: MediaLivePipeline.PIPELINE_0,
}),
});
这给你一个完整的管道:编码器将SRT推向网络接口,路由器作为输入接收,路由器输出将其交付给MediaLive. 关于路由规则——包括比特率如何影响哪些产出可接收哪些投入——见 文档。 。 。 .
路由器网络接口
网络接口定义路由器输入和输出的网络连接:
公共网络接口
declare const stack: Stack;
const publicInterface = new RouterNetworkInterface(stack, 'PublicInterface', {
routerNetworkInterfaceName: 'public-interface',
configuration: RouterNetworkConfiguration.publicNetwork({
cidr: ['203.0.113.0/24'],
}),
});
私人网络接口
declare const stack: Stack;
declare const securityGroup: ec2.ISecurityGroup;
declare const subnet: ec2.ISubnet;
const privateInterface = new RouterNetworkInterface(stack, 'PrivateInterface', {
routerNetworkInterfaceName: 'private-interface',
configuration: RouterNetworkConfiguration.vpc({
securityGroups: [securityGroup],
subnet: subnet,
}),
});
路由器输入
路由器输入接收来自各种来源的视频流,并可供线路使用:
与 RTP 协议的标准输入
declare const stack: Stack;
declare const networkInterface: RouterNetworkInterface;
const input = new RouterInput(stack, 'RtpInput', {
routerInputName: 'rtp-input',
maximumBitrate: Bitrate.mbps(10),
routingScope: RoutingScope.REGIONAL,
// tier defaults to RouterInputTier.INPUT_20 (lowest cost)
configuration: RouterInputConfiguration.standard({
networkInterface: networkInterface,
protocol: RouterInputProtocol.rtp({
port: 5000,
}),
}),
});
失败输入配置
declare const stack: Stack;
declare const networkInterface: RouterNetworkInterface;
const input = new RouterInput(stack, 'FailoverInput', {
routerInputName: 'failover-input',
maximumBitrate: Bitrate.mbps(10),
routingScope: RoutingScope.REGIONAL,
tier: RouterInputTier.INPUT_20,
configuration: RouterInputConfiguration.failover({
networkInterface: networkInterface,
protocols: [
RouterInputProtocol.rist({
port: 5000,
recoveryLatency: Duration.millis(1000),
}),
RouterInputProtocol.rist({
port: 5002, // Must not be consecutive with primary port
recoveryLatency: Duration.millis(1000),
}),
],
sourcePriority: SourcePriorityConfig.primarySecondary(PrimarySource.FIRST_SOURCE),
}),
});
媒体频道输入
连接路由器输入到 MediaLive 频道 。 这个 outputName 必须匹配频道MediaConnect路由器输出组中配置的输出名称.
declare const stack: Stack;
declare const mediaLiveChannel: medialive.IChannel;
const input = new RouterInput(stack, 'ChannelInput', {
routerInputName: 'channel-input',
maximumBitrate: Bitrate.mbps(20),
routingScope: RoutingScope.REGIONAL,
tier: RouterInputTier.INPUT_20,
configuration: RouterInputConfiguration.mediaLiveChannel({
channel: mediaLiveChannel,
outputName: 'router-ts',
pipeline: MediaLivePipeline.PIPELINE_0,
}),
});
提示 : 将 MediaLive 频道接入MediaConnect路由器的全部实例(包括 中转加密,参见 MediaLive L2 README — MediaConnect路由器部分。 。 。 .
declare const stack: Stack;
declare const mediaLiveChannel: medialive.IChannel;
declare const transitSecret: Secret; // must hold the same value as the channel's MediaConnectRouterSettings.shared() secret
const input = new RouterInput(stack, 'ChannelInput', {
routerInputName: 'channel-input',
maximumBitrate: Bitrate.mbps(20),
routingScope: RoutingScope.REGIONAL,
tier: RouterInputTier.INPUT_20,
configuration: RouterInputConfiguration.mediaLiveChannel({
channel: mediaLiveChannel,
outputName: 'router-ts',
pipeline: MediaLivePipeline.PIPELINE_0,
sourceTransitDecryption: { secret: transitSecret },
}),
});
或为 MediaLive 连接准备路由器输入,而不指定频道(需要明确可用区):
declare const stack: Stack;
const input = new RouterInput(stack, 'ChannelInputNoConnection', {
routerInputName: 'channel-input-no-connection',
maximumBitrate: Bitrate.mbps(20),
routingScope: RoutingScope.REGIONAL,
tier: RouterInputTier.INPUT_20,
configuration: RouterInputConfiguration.mediaLiveChannelWithoutConnection({
availabilityZone: 'us-east-1a',
}),
});
MediaConnect 流量输入
连接路由器输入到已有的 MediaConnect 流量 :
declare const stack: Stack;
declare const flow: Flow;
declare const flowOutput: FlowOutput;
const input = new RouterInput(stack, 'FlowInput', {
routerInputName: 'flow-input',
maximumBitrate: Bitrate.mbps(20),
routingScope: RoutingScope.REGIONAL,
tier: RouterInputTier.INPUT_20,
configuration: RouterInputConfiguration.mediaConnectFlow({
flow: flow,
flowOutput: flowOutput,
}),
});
或为流量连接准备路由器输入而无需指定流量(需要明确可用区):
declare const stack: Stack;
const input = new RouterInput(stack, 'FlowInputNoConnection', {
routerInputName: 'flow-input-no-connection',
maximumBitrate: Bitrate.mbps(20),
routingScope: RoutingScope.REGIONAL,
tier: RouterInputTier.INPUT_20,
configuration: RouterInputConfiguration.mediaConnectFlowWithoutConnection({
availabilityZone: 'us-east-1a',
}),
});
路由器输出
路由器输出将视频流发送到各种目的地,包括标准协议,MediaLive输入,以及MediaConnect流量:
使用 SRT 协议的标准输出
declare const stack: Stack;
declare const networkInterface: RouterNetworkInterface;
const output = new RouterOutput(stack, 'SrtOutput', {
routerOutputName: 'srt-output',
maximumBitrate: Bitrate.mbps(10),
routingScope: RoutingScope.REGIONAL,
// tier defaults to RouterOutputTier.OUTPUT_20 (lowest cost)
configuration: RouterOutputConfiguration.standard({
protocol: RouterOutputProtocol.srtListener({
port: 9001,
minimumLatency: Duration.millis(200),
}),
networkInterface: networkInterface,
}),
});
说明: 这个
tier财产违约到最低(和最便宜)级:INPUT_20用于路由器输入和OUTPUT_20用于路由器输出。 该构造验证了maximumBitrate合成时不超过分层容量(20、50或100 Mbps)。 个人 文档,如果输入值为 20 Mbps,则无法将其导出为 20 Mbps以下的输出.
媒体输出
连接路由器输出到 MediaLive 输入( 输入必须是 MediaConnect 路由器类型) :
declare const stack: Stack;
declare const mediaLiveInput: medialive.IInput;
const output = new RouterOutput(stack, 'MediaLiveOutput', {
routerOutputName: 'medialive-output',
maximumBitrate: Bitrate.mbps(15),
routingScope: RoutingScope.GLOBAL,
tier: RouterOutputTier.OUTPUT_20,
configuration: RouterOutputConfiguration.mediaLiveInput({
input: mediaLiveInput,
pipeline: MediaLivePipeline.PIPELINE_0,
}),
});
或为 MediaLive 连接准备路由器输出,而不指定输入(需要明确可用区):
declare const stack: Stack;
const output = new RouterOutput(stack, 'MediaLiveOutputNoConnection', {
routerOutputName: 'medialive-output-no-connection',
maximumBitrate: Bitrate.mbps(15),
routingScope: RoutingScope.GLOBAL,
tier: RouterOutputTier.OUTPUT_20,
configuration: RouterOutputConfiguration.mediaLiveInputWithoutConnection({
availabilityZone: 'us-east-1a',
}),
});
MediaConnect 流量输出
连接路由器输出到已有的 MediaConnect 流 :
declare const stack: Stack;
declare const flow: Flow;
const output = new RouterOutput(stack, 'FlowOutput', {
routerOutputName: 'flow-output',
maximumBitrate: Bitrate.mbps(20),
routingScope: RoutingScope.REGIONAL,
tier: RouterOutputTier.OUTPUT_20,
configuration: RouterOutputConfiguration.mediaConnectFlow({
flow: flow,
}),
});
或者为流接准备路由器输出,而不指定流接(需要明确可用区):
declare const stack: Stack;
const output = new RouterOutput(stack, 'FlowOutputNoConnection', {
routerOutputName: 'flow-output-no-connection',
maximumBitrate: Bitrate.mbps(20),
routingScope: RoutingScope.REGIONAL,
tier: RouterOutputTier.OUTPUT_20,
configuration: RouterOutputConfiguration.mediaConnectFlowWithoutConnection({
availabilityZone: 'us-east-1a',
}),
});
用加密输出
declare const stack: Stack;
declare const networkInterface: RouterNetworkInterface;
declare const role: iam.IRole;
declare const secret: secretsmanager.ISecret;
const output = new RouterOutput(stack, 'EncryptedOutput', {
routerOutputName: 'encrypted-output',
maximumBitrate: Bitrate.mbps(10),
routingScope: RoutingScope.REGIONAL,
tier: RouterOutputTier.OUTPUT_20,
configuration: RouterOutputConfiguration.standard({
protocol: RouterOutputProtocol.srtCaller({
destinationAddress: '203.0.113.100',
destinationPort: 9001,
minimumLatency: Duration.millis(200),
encryptionConfiguration: { role, secret },
}),
networkInterface: networkInterface,
}),
});
流量
一个MediaConnect流量代表一个源和一个或多个输出之间的传输流连接. 流量是运输视频直播内容的主要来源.
创建流程
以下示例创建了带有 RTP 源的基本 MediaConnect 流量 :
declare const stack: Stack;
const flow = new Flow(stack, 'MyFlow', {
flowName: 'my-live-stream',
source: SourceConfiguration.rtp({
flowSourceName: 'my-source',
port: 5000,
network: NetworkConfiguration.publicNetwork('203.0.113.0/24'),
}),
});
流量来源
MediaConnect支持将内容摄入一流的多源类型. 以下实例 NetworkConfiguration.publicNetwork() 但基于协议的所有源也可以使用 NetworkConfiguration.vpc() 带有用于私人连接的VPC接口.
SRT 听取器来源
收听器模式中的SRT(Secure可靠运输)配置了MediaConnect,用于在某个特定端口上收听来取内容. 上游设备作为调用器连接了MediaConnect.
declare const stack: Stack;
const flow = new Flow(stack, 'MyFlow', {
source: SourceConfiguration.srtListener({
flowSourceName: 'live-encoder-source',
description: 'Live encoder feed',
port: 5000,
minLatency: Duration.millis(2000),
network: NetworkConfiguration.publicNetwork('203.0.113.0/24'),
}),
});
SRT 调用源
呼叫模式中的SRT配置MediaConnect可以连接到远程的SRT收听器. 当源设备正在监听输入的连接而不是按下内容时使用此功能 .
declare const stack: Stack;
const flow = new Flow(stack, 'MyFlow', {
source: SourceConfiguration.srtCaller({
flowSourceName: 'remote-source',
sourceListenerAddress: '203.0.113.50',
sourceListenerPort: 5000,
minLatency: Duration.millis(200),
}),
});
RTP 来源
RTP(Real-time Transport Protocol)是一种通过IP网络发送音频和视频的标准协议.
declare const stack: Stack;
const flow = new Flow(stack, 'MyFlow', {
source: SourceConfiguration.rtp({
flowSourceName: 'rtp-source',
port: 5000,
network: NetworkConfiguration.publicNetwork('203.0.113.0/24'),
}),
});
资源来源
带有前向错误校正的 RTP 添加冗余以回收丢失的包而无需再传输 。 在通过 RTP 投稿时使用此功能, 您需要回收包 .
declare const stack: Stack;
const flow = new Flow(stack, 'MyFlow', {
source: SourceConfiguration.rtpFec({
flowSourceName: 'rtp-fec-source',
port: 5000,
network: NetworkConfiguration.publicNetwork('203.0.113.0/24'),
}),
});
RIST 来源
RIST(可靠的互联网流运输)提供可靠的视频运输,并回收包.
declare const stack: Stack;
const flow = new Flow(stack, 'MyFlow', {
source: SourceConfiguration.rist({
flowSourceName: 'rist-source',
port: 5000,
maxLatency: Duration.millis(2000),
network: NetworkConfiguration.publicNetwork('203.0.113.0/24'),
}),
});
齐西推出源
Zixi Push使用Zixi协议进行可靠的视频运输. 内容被推向MediaConnect 从一个相兼容的上游组件.
declare const stack: Stack;
const flow = new Flow(stack, 'MyFlow', {
source: SourceConfiguration.zixiPush({
flowSourceName: 'zixi-source',
maxLatency: Duration.millis(2000),
network: NetworkConfiguration.publicNetwork('203.0.113.0/24'),
}),
});
Zixi Push ports由MediaConnect指定:2088用于公共来源,2090-2099用于VPC来源. 见 源端口任务。 。 。 .
路由器来源
当流源来自MediaConnect路由器而不是直接连接时使用路由器源.
declare const stack: Stack;
const flow = new Flow(stack, 'MyFlow', {
source: SourceConfiguration.router(),
});
VPC 来源
当您需要连接到流和您的亚马逊 VPC时使用基于 VPC 的源 。 这使得私人可以连接,通过AWS Direct Connect或VPN接收来自promes设备的内容,或者从您VPC中运行的其他AWS服务接收内容.
declare const stack: Stack;
declare const securityGroup: ec2.ISecurityGroup;
declare const subnet: ec2.ISubnet;
declare const role: iam.IRole;
const vpcInterface = VpcInterface.define({
vpcInterfaceName: 'my-vpc-interface',
role: role,
securityGroups: [securityGroup],
subnet: subnet,
});
const flow = new Flow(stack, 'MyFlow', {
source: SourceConfiguration.rist({
flowSourceName: 'vpc-source',
description: 'VPC-based source',
port: 5000,
maxLatency: Duration.millis(2000),
network: NetworkConfiguration.vpc(vpcInterface),
}),
vpcInterfaces: [vpcInterface],
});
标题源( 来自另一个 AWS 账户)
权利允许您订阅另一个 AWS 账户的内容 。 应享权利由内容发端人在其AWS账户中创建,您使用他们提供的应享权利ARN导入.
declare const stack: Stack;
// Import an entitlement from another AWS account
const entitlement = FlowEntitlement.fromFlowEntitlementArn(stack, 'ImportedEntitlement',
'arn:aws:mediaconnect:us-west-2:111122223333:entitlement:1-11111111111111111111111111111111:MyEntitlement',
);
const flow = new Flow(stack, 'MyFlow', {
source: SourceConfiguration.entitlement({
entitlement: entitlement,
}),
});
网关桥源
在通过MediaConnect网关和桥接设备时使用网关桥源。 网关定义了桥梁用来在地上和云层环境之间传输视频的网络基础设施.
declare const stack: Stack;
declare const bridge: Bridge;
declare const role: iam.IRole;
declare const securityGroup: ec2.ISecurityGroup;
declare const subnet: ec2.ISubnet;
const vpcInterface = VpcInterface.define({
vpcInterfaceName: 'bridge-interface',
role: role,
securityGroups: [securityGroup],
subnet: subnet,
});
const flow = new Flow(stack, 'MyFlow', {
source: SourceConfiguration.gatewayBridge({
bridge: bridge,
vpcInterface: vpcInterface,
}),
vpcInterfaces: [vpcInterface],
});
VPC 接口
VPC接口允许MediaConnect发送或接收您VPC内部的内容. 使用 VPC 接口创建 VpcInterface.define() 并把它们加入流中 vpcInterfaces 阵列。 同样的接口可以在源和输出中引用:
declare const stack: Stack;
declare const role: iam.IRole;
declare const securityGroup: ec2.ISecurityGroup;
declare const subnet: ec2.ISubnet;
// Create VPC interface
const vpcInterface = VpcInterface.define({
vpcInterfaceName: 'my-vpc-interface',
role: role,
securityGroups: [securityGroup],
subnet: subnet,
networkInterfaceType: NetworkInterface.ENA,
});
// Add to flow and reference in source
const flow = new Flow(stack, 'MyFlow', {
vpcInterfaces: [vpcInterface], // Declare at flow level
source: SourceConfiguration.rist({
flowSourceName: 'vpc-source',
port: 5000,
maxLatency: Duration.millis(2000),
network: NetworkConfiguration.vpc(vpcInterface), // Reference in source
}),
});
CDI 和带有全民教育接口的 JPEG XS
对于高性能的 CDI 或 JPEG XS 工作流程,使用 Emplo(弹性 Fabric Adapter)接口. 注意流动最多可有1个全民教育接口:
declare const stack: Stack;
declare const role: iam.IRole;
declare const securityGroup: ec2.ISecurityGroup;
declare const subnet: ec2.ISubnet;
const efaInterface = VpcInterface.define({
vpcInterfaceName: 'efa-interface',
role: role,
securityGroups: [securityGroup],
subnet: subnet,
networkInterfaceType: NetworkInterface.EFA, // Required for CDI
});
const videoStream = MediaStream.video({
mediaStreamId: 1,
mediaStreamName: 'video',
videoFormat: MediaVideoFormat.HD_1080P,
fmtp: {
exactFramerate: Framerate.FPS_29_97,
par: PixelAspectRatio.SQUARE,
},
});
const flow = new Flow(stack, 'MyCdiFlow', {
flowSize: FlowSize.LARGE_4X, // Required for CDI and JPEG XS
vpcInterfaces: [efaInterface],
mediaStreams: [videoStream],
source: SourceConfiguration.cdi({
flowSourceName: 'cdi-source',
vpcInterface: efaInterface,
port: 5000,
maxSyncBuffer: 100,
mediaStreamSourceConfigurations: [{
encoding: Encoding.RAW,
mediaStream: videoStream,
}],
}),
});
JPEG XS 有冗余接口
JPEG XS每条媒体流需要精确2个输入接口来进行冗余. 一般情况下,一个全民教育接口和一个ENA接口:
declare const stack: Stack;
declare const role: iam.IRole;
declare const sg1: ec2.ISecurityGroup;
declare const sg2: ec2.ISecurityGroup;
declare const subnet: ec2.ISubnet;
const efaInterface = VpcInterface.define({
vpcInterfaceName: 'efa-interface',
role: role,
securityGroups: [sg1],
subnet: subnet,
networkInterfaceType: NetworkInterface.EFA,
});
const enaInterface = VpcInterface.define({
vpcInterfaceName: 'ena-interface',
role: role,
securityGroups: [sg2],
subnet: subnet,
networkInterfaceType: NetworkInterface.ENA,
});
const videoStream = MediaStream.video({
mediaStreamId: 1,
mediaStreamName: 'video',
videoFormat: MediaVideoFormat.UHD_2160P,
fmtp: {
exactFramerate: Framerate.FPS_59_94,
par: PixelAspectRatio.SQUARE,
colorimetry: Colorimetry.BT2020,
videoRange: VideoRange.FULL,
scanMode: ScanMode.PROGRESSIVE,
tcs: Tcs.PQ,
},
});
const flow = new Flow(stack, 'MyJpegXsFlow', {
flowSize: FlowSize.LARGE_4X, // Required for JPEG XS
vpcInterfaces: [efaInterface, enaInterface],
mediaStreams: [videoStream],
source: SourceConfiguration.jpegXs({
flowSourceName: 'jpegxs-source',
maxSyncBuffer: 100,
mediaStreamSourceConfigurations: [{
encoding: Encoding.JXSV,
port: 5000,
inputInterface: [efaInterface, enaInterface], // 2 interfaces for redundancy
mediaStream: videoStream,
}],
}),
});
媒体流
媒体流代表您内容的单个组件(视频,音频,辅助数据),用于ST 2110 JPEG XS或CDI工作流程. 使用静态厂法创建媒体流并将其添加到流中 mediaStreams 数组 :
declare const stack: Stack;
// Create media streams
const videoStream = MediaStream.video({
mediaStreamId: 1,
mediaStreamName: 'video-stream',
videoFormat: MediaVideoFormat.HD_1080P,
fmtp: {
colorimetry: Colorimetry.BT709,
exactFramerate: Framerate.FPS_29_97,
par: PixelAspectRatio.SQUARE,
videoRange: VideoRange.NARROW,
scanMode: ScanMode.PROGRESSIVE,
tcs: Tcs.SDR,
},
});
const audioStream = MediaStream.audio({
mediaStreamId: 2,
mediaStreamName: 'audio-stream',
channelOrder: AudioStreamOrderOptions.STANDARD_STEREO,
});
// Add to flow
const flow = new Flow(stack, 'MyFlow', {
source: SourceConfiguration.router(),
mediaStreams: [videoStream, audioStream], // Declare at flow level
});
音频频道顺序
对于音频媒体流,请使用 AudioStreamOrderOptions 指定 SMPTE 2110-30 频道顺序的 enum :
// Available channel order options
AudioStreamOrderOptions.MONO // SMPTE2110.(M)
AudioStreamOrderOptions.DUAL_MONO // SMPTE2110.(DM)
AudioStreamOrderOptions.STANDARD_STEREO // SMPTE2110.(ST)
AudioStreamOrderOptions.LTRT_MATRIX_STEREO // SMPTE2110.(LtRt)
AudioStreamOrderOptions.SURROUND_5_1 // SMPTE2110.(51)
AudioStreamOrderOptions.SURROUND_7_1 // SMPTE2110.(71)
AudioStreamOrderOptions.SURROUND_22_2 // SMPTE2110.(222)
AudioStreamOrderOptions.ONE_SDI_AUDIO_GROUP // SMPTE2110.(SGRP)
// Example with 5.1 surround
const surroundAudio = MediaStream.audio({
mediaStreamId: 3,
mediaStreamName: 'surround-audio',
channelOrder: AudioStreamOrderOptions.SURROUND_5_1,
});
媒体流可以在源配置(用于CDI和JPEG XS)和输出配置中被引用.
流量大小
MediaConnect 提供了三种流量大小,决定特性支持:
| 流量大小 | 运输流 | 无线 | 土发委会/ JPEG XS |
|---|---|---|---|
MEDIUM (默认) | ✅ | ❌ | ❌ |
LARGE | ✅ | ✅ | ❌ |
LARGE_4X | ❌ | ❌ | ✅ |
每个表格 FlowSize 用于验证构造的能力。 关于产出计数、吞吐量限制和其他按大小计的详情,见 流量大小和能力。 。 。 .
该构造在合成时根据源协议和NDI配置验证流量大小限制:
MEDIUM支持传输流协议(RTP、SRT、RIST等),但不支持NDI或CDILARGE支持传输流和 NDI,并在启用 NDI 时需要LARGE_4X用于 CDI 和 JPEG XS 协议,不支持传输流或 NDI
这些是相互排斥的——CDI/JPEG XS和NDI不能在同一流量上共存,因为它们需要不同的流量大小.
declare const stack: Stack;
declare const ndiVpcInterface: VpcInterfaceConfig;
declare const efaInterface: VpcInterfaceConfig;
declare const videoStream: MediaStream;
// NDI requires LARGE, an encoding profile, and at least one discovery server
new Flow(stack, 'NdiFlow', {
flowSize: FlowSize.LARGE,
ndiConfig: {
ndiState: State.ENABLED,
ndiDiscoveryServers: [{
discoveryServerAddress: '10.0.0.10',
vpcInterface: ndiVpcInterface,
}],
},
encodingConfig: {
encodingProfile: EncodingProfile.CONTRIBUTION_H264_DEFAULT,
},
source: SourceConfiguration.ndi({
flowSourceName: 'ndi-source',
}),
});
// CDI and JPEG XS require LARGE_4X
new Flow(stack, 'CdiFlow', {
flowSize: FlowSize.LARGE_4X,
vpcInterfaces: [efaInterface],
mediaStreams: [videoStream],
source: SourceConfiguration.cdi({
flowSourceName: 'cdi-source',
vpcInterface: efaInterface,
port: 5000,
maxSyncBuffer: 100,
mediaStreamSourceConfigurations: [{
encoding: Encoding.RAW,
mediaStream: videoStream,
}],
}),
});
更多信息见 流量大小和能力。 。 。 .
网关
MediaConnect Gateways使得能够部署现场资源,将视频传送到AWS云中或从云中传送。 创建桥梁需要网关.
创建门户
declare const stack: Stack;
const productionNetwork = GatewayNetwork.define({
cidrBlock: '192.168.1.0/24',
name: 'production-network',
});
const gateway = new Gateway(stack, 'MyGateway', {
gatewayName: 'my-gateway',
egressCidrBlocks: ['10.0.0.0/16'],
networks: [productionNetwork],
});
导入现有网关
declare const stack: Stack;
const gateway = Gateway.fromGatewayArn(stack, 'ImportedGateway',
'arn:aws:mediaconnect:us-west-2:123456789012:gateway:1-XXXXXX',
);
桥梁
MediaConnect Bridge使您能够与以云为基础的工作流程在前提上连接设备. 桥梁既支持入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入出入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入入出出出出出出出入入入入入入入入入入出出出出出出出出出出出出出出入入入入入入入入入入入入入入入入入入入入入入出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出出.
创建桥梁
入通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通
入地桥接收从地上设备中取出内容,并用云:
declare const stack: Stack;
const productionNetwork = GatewayNetwork.define({
cidrBlock: '192.168.1.0/24',
name: 'production-network',
});
const gateway = new Gateway(stack, 'MyGateway', {
gatewayName: 'my-gateway',
egressCidrBlocks: ['10.0.0.0/16'],
networks: [productionNetwork],
});
const ingressBridge = new Bridge(stack, 'MyIngressBridge', {
bridgeName: 'my-ingress-bridge',
config: BridgeConfiguration.ingress({
maxBitrate: Bitrate.mbps(10),
maxOutputs: 2,
networkSources: [{
name: 'on-prem-source',
source: {
protocol: BridgeProtocol.RTP,
network: productionNetwork,
multicastIp: '239.1.1.1',
port: 5000,
},
}],
}),
gateway: gateway,
});
Egress Bridge (云到地平线上)
Egress桥将MediaConnect流量的内容发送到精品设备:
declare const stack: Stack;
declare const gateway: Gateway;
declare const flow: Flow;
declare const vpcInterface: VpcInterfaceConfig;
declare const productionNetwork: GatewayNetwork;
const egressBridge = new Bridge(stack, 'MyEgressBridge', {
bridgeName: 'my-egress-bridge',
config: BridgeConfiguration.egress({
maxBitrate: Bitrate.mbps(10),
flowSources: [{
name: 'cloud-source',
source: {
flow: flow,
vpcInterface: vpcInterface,
},
}],
networkOutputs: [{
name: 'on-prem-output',
output: BridgeOutputConfiguration.network({
ipAddress: '192.168.1.200',
port: 5001,
network: productionNetwork,
protocol: BridgeProtocol.RTP,
ttl: 50,
}),
}],
}),
gateway: gateway,
});
桥源
对于失败的情景,您可以使用 BridgeSource 构造 :
declare const stack: Stack;
declare const bridge: Bridge;
declare const flow: Flow;
// Add a flow source to an egress bridge (requires failover to be enabled)
const additionalSource = new BridgeSource(stack, 'AdditionalSource', {
bridgeSourceName: 'backup-source',
bridge: bridge,
source: BridgeSourceConfiguration.flow({
flow: flow,
}),
});
桥梁产出
桥梁输出被配置为Egress桥桥配置的一部分. 它们定义了内容从桥上出站到安装设备的地方.
declare const productionNetwork: GatewayNetwork;
const networkConfig = BridgeOutputConfiguration.network({
ipAddress: '192.168.1.200',
port: 5001,
network: productionNetwork,
protocol: BridgeProtocol.RTP,
ttl: 50,
});
const namedOutput = { name: 'on-prem-output', output: networkConfig };
加密
MediaConnect支持对来源,输出和应享权利进行加密. 这个软件包提供了符合不同协议加密要求的类型安全加密配置架构.
加密类型
MediaConnect支持两种加密方式:
- 静态密钥加密 - 用于Zixi Push/Pull协议和应享权利
- SRT 密码加密 - 用于SRT收听器和SRT调用器协议
注:CFN只披露 static-key 财务报告和审定财务报表 srt-password 用于当前流输出加密; SPEKE 目前不是表面的一部分.
自动创建的IAM角色. 每个加密结构接受一个可选 role. 放弃它和消耗性构筑物为您创造了一种范围化的作用: mediaconnect.amazonaws.com 与 aws:SourceAccount + 键 aws:SourceArn 条件(相互矛盾的 -- -- 信任的保护),以及仅允许阅读提供的秘密(包括 kms:Decrypt 当秘密使用客户管理的 KMS 密钥时).
提供你自己的角色. 如果你提供 role,它被使用作为一个—— 构造确实 没有 给它任何许可。 你必须亲自批准 当您需要更严格的控制或共同身份时, 提供您自己的角色 .
信托政策范围:流量与路由器. 当L2自动创建一个角色时,它也会被固定 aws:SourceArn 消费资源:
- 流量 ——信托政策将流出ARN(
arn:...:flow:*:<flow-name>) (中文(简体) ). 这个*通配符为服务指派的 id 段;流名在创建时被固定. - 路由器 ——信托政策只能给一个通配符ARN(
arn:...:routerInput:*编号 :arn:...:routerOutput:*) (中文(简体) ). 路由器 I/O ARNs 使用一个在合成时未知的服务生成的id段,使用活的ARN属性将产生出一个CloudFormation依赖周期(作用-路由器-角色). 如果你需要资源,请自给role信任条件将精确的 ARN 标出 —— 您可以从资源中计算routerInputId编号 :routerOutputId第一次部署后,在后续部署中应用.
静态密钥加密
使用静键加密结构用于齐克西协议和权限. 这需要加密算法(AES128,AES192,或AES256). 在建筑要求的地方通过它:
declare const stack: Stack;
declare const flow: Flow;
declare const role: iam.IRole;
declare const secret: secretsmanager.ISecret;
new FlowEntitlement(stack, 'MyEntitlement', {
flow,
subscribers: ['111122223333'],
description: 'Grant partner access to live feed',
encryption: {
role,
secret,
algorithm: EncryptionAlgorithm.AES256,
},
});
SRT 密码加密
SRT 协议使用加密结构 role 财务报告和审定财务报表 secret 没有算法 :
declare const stack: Stack;
declare const flow: Flow;
declare const role: iam.IRole;
declare const secret: secretsmanager.ISecret;
new FlowOutput(stack, 'SrtOutput', {
flow,
output: OutputConfiguration.srtCaller({
destination: '203.0.113.100',
port: 7000,
encryption: { role, secret },
}),
});
使用源码加密
配置流源时应用加密 :
declare const stack: Stack;
declare const role: iam.IRole;
declare const secret: secretsmanager.ISecret;
// SRT Listener source with encryption
const flow = new Flow(stack, 'MyFlow', {
source: SourceConfiguration.srtListener({
flowSourceName: 'encrypted-source',
port: 5000,
network: NetworkConfiguration.publicNetwork('203.0.113.0/24'),
decryption: { role, secret },
}),
});
// Zixi Push source with encryption
const flow2 = new Flow(stack, 'MyFlow2', {
source: SourceConfiguration.zixiPush({
flowSourceName: 'encrypted-zixi-source',
maxLatency: Duration.millis(2000),
network: NetworkConfiguration.publicNetwork('203.0.113.0/24'),
decryption: {
role,
secret,
algorithm: EncryptionAlgorithm.AES256,
},
}),
});
使用带有输出的加密
配置流量输出时应用加密 :
declare const stack: Stack;
declare const flow: Flow;
declare const role: iam.IRole;
declare const secret: secretsmanager.ISecret;
// SRT Caller output with encryption
const output = new FlowOutput(stack, 'EncryptedOutput', {
flow: flow,
description: 'Encrypted SRT output',
output: OutputConfiguration.srtCaller({
destination: '203.0.113.100',
port: 7000,
encryption: { role, secret },
}),
});
使用带有权限的加密
权限使用静态密钥加密 :
declare const stack: Stack;
declare const flow: Flow;
declare const role: iam.IRole;
declare const secret: secretsmanager.ISecret;
const entitlement = new FlowEntitlement(stack, 'MyEntitlement', {
flow: flow,
description: 'Grant partner access to live feed',
subscribers: ['111122223333'],
encryption: {
role,
secret,
algorithm: EncryptionAlgorithm.AES256,
},
});
路由器中转加密
在将流与路由器合并时,使用中转加密来保证流与路由器之间的连接:
declare const stack: Stack;
declare const flow: Flow;
declare const role: iam.IRole;
declare const secret: secretsmanager.ISecret;
declare const existingRouterOutput: RouterOutput;
// Flow output to router with transit encryption
const routerOutput = new FlowOutput(stack, 'RouterOutput', {
flow: flow,
output: OutputConfiguration.router({
encryption: { role, secret },
}),
});
// Flow source from router with transit encryption
const flowFromRouter = new Flow(stack, 'FlowFromRouter', {
source: SourceConfiguration.router({
routerOutput: existingRouterOutput,
decryption: { role, secret },
}),
});
路由器 SRT 加密
使用 SRT 协议的路由器输出 RouterSrtEncryption 用于加密 :
declare const stack: Stack;
declare const networkInterface: RouterNetworkInterface;
declare const role: iam.IRole;
declare const secret: secretsmanager.ISecret;
const output = new RouterOutput(stack, 'EncryptedSrtOutput', {
routerOutputName: 'encrypted-srt-output',
maximumBitrate: Bitrate.mbps(10),
routingScope: RoutingScope.REGIONAL,
tier: RouterOutputTier.OUTPUT_20,
configuration: RouterOutputConfiguration.standard({
protocol: RouterOutputProtocol.srtCaller({
destinationAddress: '203.0.113.100',
destinationPort: 9001,
minimumLatency: Duration.millis(200),
encryptionConfiguration: { role, secret },
}),
networkInterface: networkInterface,
}),
});
说明: RouterSrtEncryption 区别于 SrtPasswordEncryption (用于流源/输出)——路由器输出使用更简单的CFN外形而无 keyType 歧视者.
云表计量
流量和桥梁暴露出用于监测的 " 云表 " 计量工具。 您可以使用这些参数创建提醒和仪表板:
declare const flow: Flow;
declare const stack: Stack;
// Create a CloudWatch alarm on source bitrate
const alarm = flow.metricSourceBitrate().createAlarm(stack, 'LowBitrate', {
threshold: 1000000,
evaluationPeriods: 1,
});
// Monitor unrecovered packets
flow.metricSourceNotRecoveredPackets().createAlarm(stack, 'PacketLoss', {
threshold: 100,
evaluationPeriods: 2,
});
// Track total packets with custom options
const totalPackets = flow.metricSourceTotalPackets({
statistic: 'sum',
period: Duration.minutes(5),
});
流量计量
metricSourceBitrate()- 摄入流量的含量比特率(平均)metricSourceNotRecoveredPackets()- 中途丢失的未通过错误更正收回的包件(和)metricSourceTotalPackets()- 流动源收到的总包(和)metricSourceSelected()- 说明Failorover模式下使用的源(最大; 1 = 活动, 0 = 备用)metricSourceConnected()- Zixi、SRT和RIST的源连接状态(min;1=连接,0=断开)metricSourceDisconnections()- 从连接到断开的源数(和)metricSourceDroppedPackets()- 在任何错误更正发生前丢失的包 (和)metricSourcePacketLossPercent()- 在过境期间丢失的包件的百分比,即使回收(平均)metricSourceRoundTripTime()- 前往RIST、Zixi和SRT的往返时间(平均为毫秒)metricSourceJitter()- 源的当前网络焦急(平均,毫秒)metric(metricName)- 按名称创建自定义衡量标准
桥梁衡量标准
桥梁测量值的维度为: BridgeARN。基于桥是入地还是入地,自动选择基本的 Cloud Watch 度量衡名称.
metricSourceBitrate(bridgeSourceName)- 特定桥源的比特率(平均)metricSourcePacketLossPercent(bridgeSourceName)- 在特定桥梁来源上丢失的包的百分比(平均)metricFailoverSwitches()- 各种来源之间的桥接开关总数FAILOVER失败模式( 和)metric(metricName)- 按名称创建自定义衡量标准
输入指标
路由器输入度量度为 RouterInputARN。 。 。 .
metricBitrate()- 路由器输入有效载荷的比特率(平均)metricNotRecoveredPackets()- 中途丢失的未通过错误更正收回的包件(和)metricTotalPackets()- 路由器输入收到的包总数(和)metricConnected()- SRT源的连接状态(min; 1 =已连接, 0 =已断开)metricContinuityCounterErrors()- 运输流中的连续反差(和)metricLatency()- RIST、STT和RTP-FEC输入流的恢复延迟(平均,毫秒)metricFailoverSwitches()- 路由器输入在Failover模式下切换源的总次数(和)metric(metricName)- 按名称创建自定义衡量标准
产出指标
路由器输出度量度 RouterOutputARN。 。 。 .
metricBitrate()- 路由器输出的有效载荷的比特率(平均)metricTotalPackets()- 路由器输出发送的包总数(和)metricConnected()- SRT 输出的连接状态( min; 1 =已连接, 0 =已断开)metricArqRequests()- 通过年度报告调查表为RIST和STRT产出要求的再传送包(和)metric(metricName)- 按名称创建自定义衡量标准
网关衡量标准
网关衡量尺度由 GatewayARN。通过额外维度,例如 NetworkName, (中文(简体) ), InstanceId,或 BridgeSourceName 通过 props.dimensionsMap 缩小到特定的网络、电器或桥源.
metricEgressBridgeTotalPackets()- 从网关上的Egress Bridge发送的总包(和)metricEgressBridgeDroppedPackets()- 由网关上的Egress桥投放的包裹(和)metricIngressBridgeTotalPackets()- 网关上的入侵桥梁接收的总包(和)metricIngressBridgeDroppedPackets()- 由网关上的入室桥梁运送的包裹(和)metric(metricName)- 按名称创建自定义衡量标准(例如:.IngressBridgeBitRate, (中文(简体) ),EgressBridgeBitRate, (中文(简体) ),IngressBridgeSourcePacketLossPercent(中文(简体) )
对等全部 + 投放的帮助者来构建一个投放包百分比图—— 例如除法 metricEgressBridgeDroppedPackets() 以 metricEgressBridgeTotalPackets() 在数学表达式中.
所有衡量标准都支持用于自定义周期、统计和维度的标准 " 云表观察 " 计量选项.
公开的 CIDR 警告
几个构件接受CIDR范围,决定谁可以贡献内容或拉出产出. 通过开放范围( N)0.0.0.0/0 或任何 /0 前缀)使得资源从公共互联网的任何地方可以到达,这很少是你想要的. 模块在探测到开放范围时发出合成时间警告:
GatewayProps.egressCidrBlocksNetworkConfiguration.publicNetwork(cidr)用于流源cidrAllowList齐克西推/齐克西拉/SRT 听众流量产出RouterNetworkConfiguration.publicNetwork({ cidr })
将每个范围限制在实际需要访问的最窄的一组地址.