# Send an adaptive bitrate stream to Akamai Wowza Streaming Engine (WSE) stream targets allow you to send adaptive bitrate (ABR) live streams to Akamai for HLS and MPEG-DASH delivery. This article includes instructions on [enabling push publishing](#enable-push-publishing) on an existing WSE streaming app, how to [create an Akamai stream target](#create-an-akamai-stream-target), and how to [test the connection](#test-the-connection). With the `group-manager` profile, you can bundle multiple bitrate streams into a single stream target group. (Each group uses a unique ABR playback URL.) ## Prerequisites - A [WSE application](https://developer.wowza.com/docs/wowza-engine/guides/live-app), configured to stream HLS or MPEG-DASH - (The requests below use `myPushPublishApp`, as an example.) - [Akamai](https://www.wowza.com/docs/how-to-stream-to-akamai#configure-akamai-to-receive-and-distribute-the-stream) configured to ingest HLS and MPEG-DASH streams Note You can [enable push publishing using the REST API](#enable-push-publishing) or by editing the [`PushPublishMap.txt` file directly](https://www.wowza.com/docs/sample-map-file-entries-for-stream-target-destinations-push-publishing). (Configuring stream targets using the `group-manager` profile is not supported in WSE Manager at this time.) ## Enable push publishing In order to send a stream target with the WSE REST API, push publishing must be enabled on your app. To enable push publishing, follow the steps below: 1. Retrieve the app's current advanced settings and modules. 2. Configure the app's push publish property and module. 3. Restart the app. ### Step 1: Retrieve the app's current settings and modules To get your app's current advanced settings and modules, send a GET request to the [`/v2/servers/{serverName}/vhosts/{vhostName}/applications/{appName}/adv` endpoint](/docs/wowza-engine/rest-api/openapi/applications/getapplicationconfigadv). Set the following path parameters: - Server name: `_defaultServer_` - Vhost name: `_defaultVHost_` - App name: The name of the streaming app. (For example, `myPushPublishApp`) ```bash Example request curl -X GET \ -H 'Accept:application/json' \ -u username:password \ "http://localhost:8087/v2/servers/_defaultServer_/vhosts/_defaultVHost_/applications/myPushPublishApp/adv" ``` A successful response will include an `advancedSettings` array and a `modules` array. ```json Example 200 response { "version": "1543353224014", "serverName": "serverName", "advancedSettings": [ { "enabled": false, "canRemove": true, "name": "debugAACTimecodes", "value": "false", "defaultValue": "false", "type": "Boolean", "sectionName": "cupertinostreamingpacketizer", "section": "/Root/Application/LiveStreamPacketizer", "documented": true }, { "enabled": false, "canRemove": true, "name": "debugMP3Timecodes", "value": "false", "defaultValue": "false", "type": "Boolean", "sectionName": "cupertinostreamingpacketizer", "section": "/Root/Application/LiveStreamPacketizer", "documented": true } ], "modules": [ { "order": 0, "name": "base", "description": "Base", "class": "com.wowza.wms.module.ModuleCore" }, { "order": 1, "name": "logging", "description": "Client Logging", "class": "com.wowza.wms.module.ModuleClientLogging" }, { "order": 2, "name": "flvplayback", "description": "FLVPlayback", "class": "com.wowza.wms.module.ModuleFLVPlayback" }, { "order": 3, "name": "ModuleCoreSecurity", "description": "Core Security Module for Applications", "class": "com.wowza.wms.security.ModuleCoreSecurity" } ] } ``` Copy the JSON from the 200 response; it will be used as the foundation for the body of the request in the next step. ### Step 2: Prepare the request body Using the response from the previous step, add the updated settings the `advancedSettings` array and the `modules` array. The modules array will **overwrite the existing array**. To preserve existing modules, you must include previously existing modules in your PUT request. Append the settling called `pushPublishMapPath` to the existing `advancedSettings` array, as shown in the example below. ```json Updated advanced settings array [ { "enabled": false, "canRemove": true, "name": "debugAACTimecodes", "value": "false", "defaultValue": "false", "type": "Boolean", "sectionName": "cupertinostreamingpacketizer", "section": "/Root/Application/LiveStreamPacketizer", "documented": true }, { "enabled": false, "canRemove": true, "name": "debugMP3Timecodes", "value": "false", "defaultValue": "false", "type": "Boolean", "sectionName": "cupertinostreamingpacketizer", "section": "/Root/Application/LiveStreamPacketizer", "documented": true }, { "enabled": true, "canRemove": false, "name": "pushPublishMapPath", "value": "${com.wowza.wms.context.VHostConfigHome}/conf/${com.wowza.wms.context.Application}/PushPublishMap.txt", "defaultValue": null, "type": "String", "sectionName": "Application", "section": "/Root/Application", "documented": false } ] ``` Append the module called `ModulePushPublish` to the existing `modules` array, as shown in the example below. ```json Updated modules array [ { "order": 0, "name": "base", "description": "Base", "class": "com.wowza.wms.module.ModuleCore" }, { "order": 1, "name": "logging", "description": "Client Logging", "class": "com.wowza.wms.module.ModuleClientLogging" }, { "order": 2, "name": "flvplayback", "description": "FLVPlayback", "class": "com.wowza.wms.module.ModuleFLVPlayback" }, { "order": 3, "name": "ModuleCoreSecurity", "description": "Core Security Module for Applications", "class": "com.wowza.wms.security.ModuleCoreSecurity" }, { "order": 4, "name": "ModulePushPublish", "description": "ModulePushPublish", "class": "com.wowza.wms.pushpublish.module.ModulePushPublish" } ] ``` ### Step 3: Configure the app's push publish property and module Send a PUT request to the [`/v2/servers/{serverName}/vhosts/(vhostName}/applications/{appName}/adv` endpoint](/docs/wowza-engine/rest-api/openapi/applications/putapplicationconfigadv). Set the following path parameters: - Server name: `_defaultServer_` *(default)* - Vhost name: `_defaultVHost_` *(default)* - App name: The name of the streaming app. Include the updated `advancedSettings` and `modules` arrays in the request body, as shown in the example below. ```bash Example request curl -X PUT \ -H 'Accept:application/json' \ -H 'Content-Type:application/json' \ -u username:password \ "http://localhost:8087/v2/servers/_defaultServer_/vhosts/_defaultVHost_/applications/myPushPublishApp/adv" \ -d '{ "advancedSettings": [ { "enabled": false, "canRemove": true, "name": "debugAACTimecodes", "value": "false", "defaultValue": "false", "type": "Boolean", "sectionName": "cupertinostreamingpacketizer", "section": "/Root/Application/LiveStreamPacketizer", "documented": true }, { "enabled": false, "canRemove": true, "name": "debugMP3Timecodes", "value": "false", "defaultValue": "false", "type": "Boolean", "sectionName": "cupertinostreamingpacketizer", "section": "/Root/Application/LiveStreamPacketizer", "documented": true }, { "enabled": true, "canRemove": false, "name": "pushPublishMapPath", "value": "${com.wowza.wms.context.VHostConfigHome}/conf/${com.wowza.wms.context.Application}/PushPublishMap.txt", "defaultValue": null, "type": "String", "sectionName": "Application", "section": "/Root/Application", "documented": false } ], "modules": [ { "order": 0, "name": "base", "description": "Base", "class": "com.wowza.wms.module.ModuleCore" }, { "order": 1, "name": "logging", "description": "Client Logging", "class": "com.wowza.wms.module.ModuleClientLogging" }, { "order": 2, "name": "flvplayback", "description": "FLVPlayback", "class": "com.wowza.wms.module.ModuleFLVPlayback" }, { "order": 3, "name": "ModuleCoreSecurity", "description": "Core Security Module for Applications", "class": "com.wowza.wms.security.ModuleCoreSecurity" }, { "order": 4, "name": "ModulePushPublish", "description": "ModulePushPublish", "class": "com.wowza.wms.pushpublish.module.ModulePushPublish" } ] }' ``` ### Step 4: Restart the app Restart the application by sending a PUT request to the [`/v2/servers/{serverName}/vhosts/{vhostName}/applications/{appName}/actions/{action}` endpoint](/docs/wowza-engine/rest-api/openapi/applications/putapplicationaction). Set the following path parameters: - Server name: `_defaultServer_` (default) - Vhost name: `_defaultVHost_` (default) - App name: The name of the streaming app. - Action: `restart` ```bash Example request curl -X PUT \ -H 'Accept:application/json' \ -u username:password \ "http://localhost:8087/v2/servers/_defaultServer_/vhosts/_defaultVHost_/applications/myPushPublishApp/actions/restart" ``` Once the app restarts, it can be used to create and edit stream targets. ## Create an Akamai stream target Create a push publish map entry by sending a POST request to the [`/v2/servers/{serverName}/vhosts/{vhostName}/applications/{appName}/pushpublish/mapentries/{entryName}` endpoint](https://developer.wowza.com/docs/wowza-engine/rest-api/openapi/applications/postpushpublishstreamappconfig). Include the following path parameters: - Server name: `_defaultServer_` (default) - Vhost name: `_defaultVHost_` (default) - App name: The name of the streaming app. - Entry name: The name of your Akamai stream. (For example, `myAkamaiStreamTarget`) You can find your Akamai stream information from the Media Services Live (MLS) page of the Akamai Control Center. In the body of the request, set the `profile` to `group-manager`. Set additional body parameters shown in the table below. (For a complete list of available parameters, see the [REST API reference](/docs/wowza-engine/rest-api/openapi/applications/postpushpublishstreamappconfig#applications/postpushpublishstreamappconfig/request/body).) #### Body parameters | Parameter | Data Type | Description | | --- | --- | --- | | `profile` (required) | String | Set to `group-manager`. This profile allows you to group adaptive bitrate streams. | | `childProfile` (required) | String | Determines how each stream in the group is sent to the destination. (This setting determines which additional parameters are available.) Supported values: `cupertino-akamai`: Send streams to an HLS Akamai stream`mpegdash-akamai`: Send streams to an MPEG-DASH Akamai stream. | | `group.streamMatcher` (required) | String | Determines how source streams are presented in the `sourceStreamName` value. Supported values: `nameList`: Streams are listed by name separated by the pipe character |. For example, `sourceStreamName: myStream_160p|myStream_720p`.`nameRegex`: Streams are identified using a regular expression. For example, `sourceStreamName: my[sSdDqQ]tream.+`.`namePrefix`: Streams are identified by a shared prefix in stream names. For example, `sourceStreamName: myStream` will group any streams with names that begin with `myStream`.`ngrp`: Stream are identified by a stream name group. For example, `sourceStreamName: myStream_all`.`smil`: Streams are identified in a SMIL file in `[install-dir]/content`. For example, `sourceStreamName: myStream.smil`.`amlst`: Streams are identified in an AMLST file provided by the `IMediaListProvider` module. For example, `sourceStreamName: myStream.amlst`. | | `sourceStreamName` (required) | String | The streams to be included in the stream group. | | `group.name` (required) | String | A descriptive name for the stream group. Used to identify the group in playback URLs. | | `entryName` (required) | String | A descriptive name for the map entry. For example, `myAkamaiStreamTarget`. | | `akamai.streamId` (required) | String | The destination Akamai `streamId`. | | `playbackHost` | String | **For Akamai MSL 4 networks**. The playback server's hostname or IP address. This value appears in the playback URLs of the WSE logs.(Required if `http.relativePlaylists` is `false`) | | `akamai.destinationServer` | String | The destination Akamai server(s) for redundant stream failover. WSE sends the redundant stream to the backup entry point at Akamai. Supported values:`primary`: The map entry is pushed to the primary server.`backup`: The map entry is pushed to the backup server.`redundant`: The map entry is pushed to both primary and backup servers. (A separate redundancy manifest with playback URLs will be created for both the primary and backup streams.) | | `http.playlistCount` | Integer | The number of chunks to maintain in the playlist. If this value is set to `0` (default) WSE will select this value based on the app's streaming protocol:HLS: `3` MPEG-DASH: `5` | | `http.relativePlaylists` | Boolean | Set to `true` to send relative URL references in the playlists and manifests. (The default of `false` will send absolute URL references.) | | `mpegdash.audioRepresentationId` | String | A unique ID for the stream's audio. Sets the representation ID in MPEG-DASH MPD manifests. Accepts any alphanumeric string. If omitted, WSE constructs the ID from the bitrate in Kbps. For example, `audio_752kbps`. | | `mpegdash.videoRepresentationId` | String | A unique ID for the stream's video. Sets the representation ID in MPEG-DASH MPD manifests. Accepts any alphanumeric string. If omitted, WSE constructs the ID from the bitrate in Kbps. For example, `video_752kbps`. | | `debugLog` | Boolean | Set to `true` to enable debug connection logging.(Default: `false`) | | `debugLogChildren` | Boolean | Set to `true` to enable debug logging of child push publishing sessions.(Default: `false`) | ```bash Example request curl -X POST \ -H 'Accept:application/json' \ -H 'Content-Type:application/json' \ -u username:password \ http://localhost:8087/v2/servers/_defaultServer_/vhosts/_defaultVHost_/applications/myPushPublishApp/pushpublish/mapentries/myAkamaiStreamTarget \ -d '{ "profile": "group-manager", "childProfile": "mpegdash-akamai", "group.streamMatcher": "ngrp", "sourceStreamName": "myStream_all", "group.name": "NameGroupDASH", "entryName": "myAkamaiStreamTarget", "akamai.streamId": "123456", "playbackHost": "example-i", "akamai.destinationServer": "primary", "http.playlistCount": "15", "debugLog": "true", "debugLogChildren": "true" }' ``` ```json Example 200 response { "success": true, "message": "Entry (myAkamaiStreamTarget) saved successfully", "data": null } ``` A successful request will add a map entry to the push publish map in the [push publish configuration file](https://www.wowza.com/docs/how-to-push-streams-to-cdns-and-other-services-push-publishing) located at `[install-dir]/conf/PushPublishMap.txt`. ```text Stream target entry added to PushPublishMap.txt myStream_all={"entryName":"myAkamaiStreamTarget","profile":"group-manager", "group.name":"NameGroupDASH", "playbackHost":"example-i","debugLog":"true","debugLogChildren":"true","akamai.streamId":"123456", "http.playlistCount":"15","childProfile":"mpegdash-akamai","group.streamMatcher":"ngrp"} ``` Note Stream targets created using the `group-manager` profile do not appear in WSE Manager. ### Enable a single stream target Enable a single stream target (push publishing map entry) by sending a PUT request to the [`/v2/servers/{serverName}/vhosts/{vhostName}/applications/{appName}/pushpublish/mapentries/{entryName}/actions/{action}` endpoint](https://developer.wowza.com/docs/wowza-engine/rest-api/openapi/applications/putapplicationaction). Include the following path parameters: - Server name: `_defaultServer_` (default) - Vhost name: `_defaultVHost_` (default) - App name: The name of the streaming app. - Entry name: The name of the push publishing map entry. (For example, `myAkamaiStreamTarget`) - Action: `enable` ```bash Example request curl -X PUT \ -H "Accept:application/json" \ -u username:password \ "http://localhost:8087/v2/servers/_defaultServer_/vhosts/_defaultVHost_/applications/myPushPublishApp/pushpublish/mapentries/myAkamaiStreamTarget/actions/enable" ``` ## Test the connection 1. Start the stream in its camera or encoder. The WSE app will ingest the live stream and send it to Akamai. 2. In the Akamai Control Center, verify that Akamai is receiving and distributing the stream: - Click the **Monitor** menu. - Select **Monitor Streams**. - Select the product. - Check whether your stream has an **Ingest Bit Rate** and an **Egress Bit Rate**. 3. Enter the playback URL(s) in a test player. You can use your own player or a [Wowza Test Player](https://www.wowza.com/testplayers). In the following example playback URLs, `[akamai-playback-host]` is the playback hostname for the stream as it appears in the Akamai Control Center. `http://[akamai-playback-host].akamaihd.net/hls/live/[akamai.streamId]/[group.name]/playlist.m3u8` `http://[akamai-playback-host].akamaihd.net/dash/live/[akamai.streamId]/[group.name]/manifest.mpd` 4. Stop the stream to end your test connection.