

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 投标构造和模板制作
<a name="yield-optimization-bid-construction"></a>

本页介绍如何根据您的模板 MediaTailor 构建 OpenRTB 出价请求、变量插值的工作原理以及自动设置的值。 MediaTailor 

## 配置字段
<a name="yield-optimization-bid-construction-config-fields"></a>

当您在播放配置上启用产量优化时，需要提供四个字段：


| 字段 | 说明 | 必填 | 
| --- | --- | --- | 
| PublisherId | 您的 APS 发布商 ID（从 APS 注册中获得）。app.publisher.id在每个出价请求中注入。 | 是 | 
| Region | APS 区域：AMERICASEUROPE、或ASIA\_PACIFIC。确定 APS 终端节点。 | 是 | 
| MinimumUnfilledDuration |  MediaTailor 触发出价请求之前所需的最短未填充秒数。也用作imp.video.minduration。 | 是 | 
| OpenRtbTemplate | 您的 ORTB JSON 模板（最大 100 KB）。定义出价请求正文。 | 是 | 

## 出价请求是如何构造的
<a name="yield-optimization-bid-construction-how"></a>

当广告插播时段剩余时间未填充时，按以下步骤 MediaTailor 构造出价请求：

1. **模板插值。** MediaTailor 使用标准的 [ Mustache 模板语法解析`{{session.*}}`模板中的`{{avail.*}}``{{request.*}}``{{asset.*}}`、、、、和`{{scte.*}}`占位符。`{{player_params.*}}`](https://mustache.github.io/mustache.5.html)Mustache 使用双大括号`{{ }}`，这与 ADS 网址变量替换中`[ ]`使用的方括号不同。

1. **JSON 解析。**插值后的模板被解析为 JSON。

1. **字段提取和验证。** MediaTailor提取必填字段，`BidRequestConfigurationError`如果有缺失或为空则抛出。

1. **硬编码场注入。** MediaTailor 使用控制台配置和当前可用上下文（例如，`app.publisher.id`来自您配置的发布商 ID，计算出的未填充持续时间）的值，覆盖或注入其自动管理的字段。`imp.video.maxduration`

1. **序列化和提交。**最终版本被序列化 BidRequest 为 JSON，并作为 HTTP POST 发送到 APS 端点。

**重要**  
如果插值后有任何必填字段缺失或为空，则出价请求将失败，`BidRequestConfigurationError`并且不会向 APS 发送任何请求。错误已记录在案，但播放正常（失效开放）。

## 控制台默认模板
<a name="yield-optimization-bid-construction-default-template"></a>

当您在 MediaTailor 控制台中启用收益优化时，将提供以下预先填写的模板作为起点。你应该为你的应用程序自定义值：

```
{
  "imp": [
    {
      "bidfloor": 5
    }
  ],
  "app": {
    "id": "{{player_params.app_id}}",
    "name": "{{player_params.app_name}}",
    "bundle": "{{player_params.bundle}}",
    "storeurl": "{{player_params.storeurl}}",
    "domain": "{{player_params.domain}}",
    "content": {
      "genre": "{{asset.genre}}",
      "contentrating": "{{asset.content_rating}}"
    }
  },
  "device": {
    "dnt": "{{player_params.dnt}}",
    "ua": "{{session.user_agent}}",
    "ip": "{{session.client_ip}}",
    "ifa": "{{player_params.device_ifa}}",
    "w": "{{player_params.device_width}}",
    "h": "{{player_params.device_height}}",
    "language": "{{player_params.language}}",
    "model": "{{player_params.model}}",
    "os": "{{player_params.os}}",
    "osv": "{{player_params.osv}}",
    "devicetype": "{{player_params.devicetype}}",
    "make": "{{player_params.make}}"
  },
  "user": {
    "consent": "{{player_params.consent}}"
  },
  "regs": {
    "gdpr": "{{player_params.gdpr}}",
    "us_privacy": "{{player_params.us_privacy}}",
    "gpp": "{{player_params.gpp_consent}}",
    "gpp_sid": "{{player_params.gpp_sid}}"
  }
}
```

**Field-by-field 解释：**


| 字段 | 类别 | 操作 | 
| --- | --- | --- | 
| imp[0].bidfloor | 可选（默认值：1.0） | 设置您的最低 CPM。主机默认值为 5 美元。在测试期间降低以获得更好的填充率。 | 
| app.id | APS 推荐 | 您的应用程序标识符。玩家必须发送playerParams.app\_id。 | 
| app.name | APS 推荐 | 您的应用程序名称。玩家必须发送playerParams.app\_name。 | 
| app.bundle | 强制性的  | 您的应用程序包 ID。玩家必须发送playerParams.bundle静态值或替换为静态值（推荐）。 | 
| app.storeurl | 强制性的  | 您的应用商店网址。玩家必须发送playerParams.storeurl静态值或替换为静态值（推荐）。 | 
| app.domain | APS 推荐 | 您的应用程序域。玩家必须发送playerParams.domain。 | 
| app.content.genre | APS 推荐 | 由内容源资产元数据填充。 | 
| app.content.contentrating | APS 推荐 | 由内容源资产元数据填充。 | 
| device.dnt | APS 推荐 | 请勿追踪标志。玩家必须发送playerParams.dnt。 | 
| device.ua | 强制性的  | 从查看者的 User-Agent 标题自动填充至{{session.user\_agent}}。无需玩家参数。 | 
| device.ip | 强制性的  | 通过查看者的 IP 自动填充{{session.client\_ip}}。无需玩家参数。 | 
| device.ifa | APS 推荐 | 广告编号。玩家必须发送playerParams.device\_ifa。 | 
| device.w / device.h | APS 推荐 | 屏幕尺寸。玩家必须发送playerParams.device\_width/device\_height。 | 
| device.language | APS 推荐 | 设备语言。玩家必须发送playerParams.language。 | 
| device.model | APS 推荐 | 设备型号。玩家必须发送playerParams.model。 | 
| device.os / device.osv | APS 推荐 | 操作系统和版本。玩家必须发送playerParams.os/osv。 | 
| device.devicetype | 可覆盖（默认值：3） | IAB 设备类型。玩家必须发送playerParams.devicetype。如果为空，则默认为 3 (CTV)。 | 
| device.make | APS 推荐 | 设备制造商。玩家必须发送playerParams.make。 | 
| user.consent | APS 推荐（欧盟） | GDPR 同意字符串 (TCF)。玩家必须发送playerParams.consent。 | 
| regs.gdpr | APS 推荐（欧盟） | GDPR 标志（0 或 1）。玩家必须发送playerParams.gdpr。 | 
| regs.us\_privacy | APS 推荐（美国） | CCPA 字符串（例如，1YNY）。玩家必须发送playerParams.us\_privacy。 | 
| regs.gpp | APS 推荐 | 全球隐私平台同意字符串。玩家必须发送playerParams.gpp\_consent。比us\_privacy起更高的填充率，首选。 | 
| regs.gpp\_sid | APS 推荐 | GPP 分区 ID（[7]例如，美国国民）。玩家必须发送playerParams.gpp\_sid。 | 

**重要**  
控制台默认使用诸如`app.bundle`和之类`{{player_params.*}}`的必填字段`app.storeurl`。如果您的玩家未发送这些参数，则出价请求将失败`BidRequestConfigurationError`。对于每个会话都相同的字段（通常是`app.bundle``app.storeurl``app.name`、和其他应用程序级标识符），可以考虑将占位符替换为静态值（例如，）。`"bundle": "com.yourcompany.app"`请勿对因查看者而异的字段进行硬编码，例如、`device.ua`、`device.ip``device.ifa`、GDPR 和 GPP 同意字符串，或任何监管或用户对象字段。这些必须来自`{{session.*}}`或`{{player_params.*}}`。

**注意**  
控制台默认不在模板`video.protocols`中包含`video.mimes`或。 MediaTailor 如果未提供硬编码的备用值（`["video/mp4"]`对于 mime，`[1,2,3,4,5,6,7,8]`用于协议），则使用这些值。如果您想限制支持的格式，可以将它们添加到您的模板中。

## 模板插值（胡子模板）
<a name="yield-optimization-bid-construction-interpolation"></a>

您的 ORTB 模板使用 [ Mustache 模板](https://mustache.github.io/mustache.5.html)语法进行动态值替换。占位符使用双大括号。`{{ }}`

### 可用的模板变量
<a name="yield-optimization-bid-construction-variables"></a>

您的 ORTB 模板可以使用与 ADS 网址模板中相同的动态变量。其中包括会话变量（例如，，`{{session.client_ip}}`）`{{session.user_agent}}`、玩家参数（`{{player_params.*}}`）、资产元数据（`{{asset.*}}`）、可用上下文（`{{avail.*}}`）和 SCTE 信号数据（`{{scte.*}}`）。

有关可用变量的完整列表及其描述，请参见[MediaTailor ADS 请求的动态广告变量](variables.md)。有关在将 MediaTailor URL-decodes玩家参数替换到模板之前的值，请参阅本页[编码和解码行为](#yield-optimization-bid-construction-encoding)后面的内容。

ORTB 模板中最常用的变量是：
+ `{{session.user_agent}}`：查看者的 User-Agent 标题（用于`device.ua`）。
+ `{{session.client_ip}}`：查看者的 IP 地址（用于`device.ip`）。
+ `{{player_params.*}}`：玩家在会话初始化期间传递的自定义值。
+ `{{asset.*}}`：来自源的内容元数据（例如，`asset.genre`，`asset.content_rating`）。

**警告**  
务必将占位符用引号括起来，即使对于像`dnt`或`devicetype`这样的数值字段也是如此。如果占位符解析为空字符串且未加引号（例如，`"dnt": {{player_params.dnt}}`），则结果为 JSON 无效，整个出价请求将失败，并显示为。`BidRequestConfigurationError`请改用 `"dnt": "{{player_params.dnt}}"`。APS 接受以字符串形式传递的数值字段。这种行为是设计使然，因为自动引用空字符串替换会与插值器中其他地方使用的 Raw-JSON 模式发生冲突。该限制是记录在案的，而不是强制执行的。另[编码和解码行为](#yield-optimization-bid-construction-encoding)请参阅，了解如何在插值之前 MediaTailor处理玩家参数值。

### 如何传递玩家参数
<a name="yield-optimization-bid-construction-pass-params"></a>

在会话初始化期间，有两种方法可以传递玩家参数。

**方法 1：带有 JSON 正文的 POST 请求（推荐）**

```
POST https://<mediatailor-endpoint>/v1/session/<config-hash>/<origin-id>/master.m3u8
Content-Type: application/json

{
  "playerParams": {
    "app_id": "558775_example",
    "slot_id": "608109df-2378-4bc5-8da5-24bc355f01a4",
    "os": "Tizen",
    "make": "Samsung",
    "model": "Tizen TV",
    "language": "en",
    "us_privacy": "1YNY"
  }
}
```

这种方法是首选，因为它避免了用户代理字符串等复杂值 URL-encoding 的问题。

**方法 2：网址查询参数 **

```
GET https://<mediatailor-endpoint>/v1/session/<config-hash>/<origin-id>/master.m3u8
  ?playerParams.app_id=558775_example
```

使用此方法，值必须为 URL-encoded。 MediaTailor URL-decodes 它们在插值之前。

### 编码和解码行为
<a name="yield-optimization-bid-construction-encoding"></a>

MediaTailor 在将玩家参数值插入模板之前，**对它们执行**一级 URL 解码。无论如何传递参数（POST 正文或 URL 查询参数），这都适用。

**解码值的示例：**


| 值已发送 | 解码后的值（在模板中使用） | 
| --- | --- | 
| Test%20Os | Test Os | 
| https%3A%2F%2Flocalhost | https://localhost | 
| foo%20bar | foo bar | 
| Mozilla%2F5.0%20(SMART-TV) | Mozilla/5.0 (SMART-TV) | 

**要点：**
+ MediaTailor 只能**解码到**一个级别。 Double-encoded 值（例如`%2520`）将被解码为空格`%20`，而不是空格。
+ **POST 正文值也会**被解码。如果您的 POST 正文包含 URL-encoded 值，则将在插值之前对其进行解码。
+ **纯文本值**（无编码）按原样传递。
+ 解码和插值后，整个模板被解析为 JSON。插值中的特殊字符（例如未转义的引号或反斜杠）可能会中断 JSON 解析。

**提示**  
如果你的玩家发送的值已经是纯文本（不是 URL-encoded），则它们会按原样运行。在发送之前，您只需要注意解码玩家的 URL-encodes值。

### 变量丢失时会发生什么
<a name="yield-optimization-bid-construction-missing-variable"></a>

如果玩家未发送模板中引用的参数（例如，`{{player_params.app_name}}`但玩家参数`app_name`中没有发送参数），则占位符将解析为**空字符串。** `""`

**影响：**如果空字符串位于必填字段（例如`app.bundle`）中，则出价请求将失败`BidRequestConfigurationError`。如果它位于可选字段中，APS 会收到一个空值，这可能会导致无出价 (HTTP 204) 响应。

## 什么会自动 MediaTailor 设置
<a name="yield-optimization-bid-construction-auto-set"></a>

以下字段始终 MediaTailor 使用您的控制台配置和当前 Avail上下文中的值来设置。如果您在模板中包含这些值，则您的值将被覆盖：


| 字段 | 来源 | 
| --- | --- | 
| id | Auto-generated: {sessionId}\_{availId} 格式（例如，abc123-def456\_78901）。可用于将出价请求与会话日志关联起来。 | 
| app.publisher.id | 您的控制PublisherId台配置。 | 
| imp[0].video.minduration | 您的控制MinimumUnfilledDuration台配置。 | 
| imp[0].video.maxduration | 已计算：此用途的实际未填充秒数。 | 
| imp[0].video.maxseq | 已计算：floor(unfilled\_duration / 6)。 | 
| imp[0].video.poddur | 已计算：此用途的实际未填充秒数。 | 
| ext.integrationType | 始终设置为"EMT"。 | 

## 后续步骤
<a name="yield-optimization-bid-construction-next-steps"></a>
+ 有关完整的逐字段参考，请参阅。[ORTB 字段参考](yield-optimization-ortb-reference.md)
+ 有关复制粘贴模板，请参阅。[示例 模板](yield-optimization-examples.md)