{"_id":"59796d1140a3a2001f068cbb","category":{"_id":"59796d1140a3a2001f068cb6","version":"59796d1140a3a2001f068cb4","project":"5669937dfc5abf2300afe7de","__v":0,"sync":{"url":"","isSync":false},"reference":true,"createdAt":"2015-12-23T15:52:27.836Z","from_sync":false,"order":1,"slug":"foo","title":"Core"},"user":"543532513513400800a144f4","project":"5669937dfc5abf2300afe7de","parentDoc":null,"version":{"_id":"59796d1140a3a2001f068cb4","project":"5669937dfc5abf2300afe7de","__v":2,"createdAt":"2017-07-27T04:33:21.278Z","releaseDate":"2017-07-27T04:33:21.278Z","categories":["59796d1140a3a2001f068cb5","59796d1140a3a2001f068cb6","59796d1140a3a2001f068cb7","59796d1140a3a2001f068cb8","5acb7bc606a2ce0003f28da4"],"is_deprecated":false,"is_hidden":false,"is_beta":false,"is_stable":true,"codename":"","version_clean":"2.0.0","version":"2.0"},"githubsync":"","__v":26,"updates":[],"next":{"pages":[],"description":""},"createdAt":"2016-01-04T13:58:57.849Z","link_external":false,"link_url":"","sync_unique":"","hidden":false,"api":{"examples":{"codes":[{"code":"curl -X \"POST\" \"https://s2-api.safestream.com/2.0/watermark\" \\\n     -H \"Content-Type: application/json\" \\\n     -H \"x-api-key: [[app:apiKey]]\" \\\n     -H \"x-api-client-id: [[app:apiClientId]]\" \\\n     -d $'{\n  \"videoId\": \"831623c0-72ff-4a91-aa6b-323d7ef2ab9a\",\n  \"settings\": [\n    {\n      \"y\": 0.5,\n      \"x\": 0.5,\n      \"align\": \"RIGHT\",\n      \"content\": \"Any String You Want\",\n      \"verticalAlign\": \"middle\",\n      \"animation\": {\n        \"startTime\": 1,\n        \"endTime\": 3,\n        \"toX\": 1,\n        \"toY\": 1\n      }\n    }\n  ],\n  \"viewLimit\" : 5,\n  \"expiration\" : 1523640477\n}'\n","language":"curl"}]},"method":"post","results":{"codes":[{"name":"","code":"{\n  \"status\": \"READY\",\n  \"containers\": {\n    \"href\": \"https://api.safestream.com/player/1.0/?href=https%3A%2F%2Fsafestream-api.shiftplatform.io%2F1.0%2Fwatermark%2F1741b0ce-71d7-439e-a52b-f1dc61ee7f0c%2F42d9f235443bdea89139a3243594389abe5f9b46%3Fcontainers%3Dmp4%26containers%3Dm3u8%26expiration%3D1478877353611%26signature%3DaRO9RIF1uuhXiss3lKMxIrUqCjI%253D\",\n    \"m3u8\": \"https://api.safestream.com/1.0/watermark/1741b0ce-71d7-439e-a52b-f1dc61ee7f0c/42d9f235443bdea89139a3243594389abe5f9b46/video.m3u8?x=y&expiration=1478877353611&signature=Wgbr4AKZFCzo877Nz78Jf84TCFo%3D\"\n  },\n  \"href\": \"https://api.safestream.com/1.0/watermark/1741b0ce-71d7-439e-a52b-f1dc61ee7f0c/42d9f235443bdea89139a3243594389abe5f9b46?containers=mp4&containers=m3u8&expiration=1478877353611&signature=aRO9RIF1uuhXiss3lKMxIrUqCjI%3D\"\n}","language":"json","status":200},{"name":"","code":"{ message: [Array of error messages] }","language":"json","status":400},{"code":"{\n  \"message\": \"Access Denied\"\n}","language":"json","status":401},{"language":"json","status":403,"code":"{\n  \"message\": \"Access Denied\"\n}"}]},"settings":"","auth":"required","params":[{"_id":"568a7b50bf86800d00fe310c","ref":"","in":"body","required":false,"desc":"Optional: The key of the video that you'd like to watermark.","default":"","type":"string","name":"key"},{"_id":"568a7bd18360c00d00a0e72b","ref":"","in":"body","required":false,"desc":"Optional: Use the ID SafeStream assigned to this asset during ingest","default":"","type":"string","name":"videoId"},{"_id":"568a7c40d4e2360d0098002b","ref":"","in":"body","required":false,"desc":"An array of watermark settings to be applied to the video that should be watermarked. See below for details on the watermark setting properties.","default":"{\"content\": \"Joe Smith\",                 \"align\":\"center\",                 \"verticalAlign\":\"middle\"             }","type":"array_object","name":"settings"},{"_id":"58248f95d90fa027009b2597","ref":"","in":"body","required":false,"desc":"Defaults to m3u8 for HLS playback but also supports MP4 to specifically request a watermarked mp4 video for download.","default":"[\"m3u8\",\"mp4\"]","type":"array_string","name":"containers"},{"_id":"582494658d0ac71b00780e89","ref":"","in":"body","required":false,"desc":"A mapping object that references an existing watermark template and maps values to placeholders.","default":"\"settingsTemplateMapping\": {         \"id\": \"74fc00c8-847d-4631-94a4-f4ac7d1e4748\",         \"mappings\": {             \"name\": \"User Name\"         }     }","type":"object","name":"settingsTemplateMapping"},{"_id":"5acb8da83990fe0003bc52d5","ref":"","in":"body","required":false,"desc":"determines the number of times the watermarked file can be requested. After the limit is reached, the watermarked file will no longer be available.","default":"null","type":"int","name":"viewLimit"},{"_id":"5acb8da83990fe0003bc52d4","ref":"","in":"body","required":false,"desc":"determines the exact epoch time in SECONDS that the watermark file will no longer be accessible.","default":"null","type":"long","name":"expiration"}],"url":"/watermark"},"isReference":true,"order":2,"body":"[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Watermarking Overview\"\n}\n[/block]\nOnce a video has been [ingested](doc:video), you can request a watermark for the video using this endpoint. At it's simplest you just need the ID or KEY of the video and the text that you'd like you have as your watermark. SafeStream will locate the video that you've already ingested and it will apply the watermark to the file.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"{\\n    \\\"key\\\": \\\"my-internal-id\\\",\\n    \\\"settings\\\": [\\n           {\\n        \\\"content\\\": \\\"Kai Pradel\\\",\\n        \\\"fontColor\\\": \\\"FFFFFF\\\",\\n        \\\"y\\\": 0.02,\\n        \\\"x\\\": 0.02,\\n        \\\"fontOpacity\\\": 0.5,\\n        \\\"fontSize\\\": 0.04,\\n        \\\"align\\\": \\\"LEFT\\\",\\n        \\\"verticalAlign\\\": \\\"TOP\\\",\\n        \\\"shadowColor\\\": \\\"000000\\\",\\n        \\\"shadowOffsetX\\\": 0.08,\\n        \\\"shadowOffsetY\\\": 0.08,\\n        \\\"shadowOpacity\\\": 0.33\\n      },\\n      {\\n        \\\"content\\\": \\\"ACME Studios\\\",\\n        \\\"fontColor\\\": \\\"FFFFFF\\\",\\n        \\\"y\\\": 0.02,\\n        \\\"x\\\": 0.98,\\n        \\\"fontOpacity\\\": 0.5,\\n        \\\"fontSize\\\": 0.04,\\n        \\\"align\\\": \\\"RIGHT\\\",\\n        \\\"verticalAlign\\\": \\\"TOP\\\",\\n        \\\"shadowColor\\\": \\\"000000\\\",\\n        \\\"shadowOffsetX\\\": 0.08,\\n        \\\"shadowOffsetY\\\": 0.08,\\n        \\\"shadowOpacity\\\": 0.33,\\n        \\\"animation\\\": {\\n\\t\\t\\t\\t\\t\\\"toX\\\": -0.3,\\n\\t\\t\\t\\t\\t\\\"startTime\\\": 8,\\n\\t\\t\\t\\t\\t\\\"endTime\\\": 16\\n\\t  \\t\\t}\\n      }\\n    ]\\n}\",\n      \"language\": \"json\"\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Watermark Using A Template\"\n}\n[/block]\nUsing [predefined template watermark templates](doc:creating-templates) simplifies the watermark request by referencing an existing template and providing the the placeholder data.\n\nA template can contain a placeholder variable such as [%name%] or [%email%] which is then passed into the watermark request along with the template id.\n\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"curl -X \\\"POST\\\" \\\"https://s2-api.safestream.com/2.0/watermark\\\" \\\\\\n     -H \\\"Content-Type: application/json\\\" \\\\\\n     -H \\\"x-api-key: [[app:apiKey]]\\\" \\\\\\n     -H \\\"x-api-client-id: [[app:apiClientId]]\\\" \\\\\\n     -d '{\\n    \\\"key\\\":\\\"my-internal-id\\\",\\n    \\\"settingsTemplateMapping\\\": {\\n        \\\"id\\\": \\\"my-template-id\\\",\\n        \\\"mappings\\\": {\\n            \\\"name\\\": \\\"My User\\\",\\n            \\\"email\\\" : \\\"user:::at:::user.com\\\",\\n            \\\"time\\\" : \\\"12:13:11 am\\\"\\n        }\\n    }\\n}'\",\n      \"language\": \"curl\"\n    }\n  ]\n}\n[/block]\nTo learn more about creating templates, see [Creating a Template](doc:creating-templates)\n[block:api-header]\n{\n  \"title\": \"Embedding a Forensic Watermark\"\n}\n[/block]\nIn addition to adding a visual watermark, you can also embed an invisible watermark. Doing this requires that the video was initially [ingested](doc:video) with \"enableForensic\" set to true. \n\nThe request payload for embedding a forensic watermark is much simpler than for visual watermarking. Rather than specifying display properties, the settings for a forensic watermark only need the bits that should be embedded into the video. Here's an example request body for a forensic watermark:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"{\\n    \\\"key\\\": \\\"my-internal-id\\\",\\n    \\\"settings\\\": [\\n      {\\n        \\\"type\\\":\\\"FORENSIC\\\",\\n        \\\"content\\\": \\\"DIg=\\\"\\n      }\\n    ]\\n}\",\n      \"language\": \"json\"\n    }\n  ]\n}\n[/block]\nFirst, notice that we've added the \"type\" property to the request. This is an optional field that allows us to override the default type, TEXT, and set it to FORENSIC. Without this change this video would be visually watermarked with the string \"DIg=\" rather than embedding a forensic watermark.\n\nSecond, notice the content, it's a 16 bit base64 encoded payload that we'll ebbed invisibly in the video.\n\nThe forensic payload for each watermark should be unique to the user who is watching the video.\n[block:callout]\n{\n  \"type\": \"warning\",\n  \"title\": \"Minimum Video Duration\",\n  \"body\": \"Embedding forensic watermarks is not supported on videos with a duration less than 5 minutes.\"\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Understanding the Watermarking Response\"\n}\n[/block]\n SafeStream supports several integration scenarios: \n  * 1. Use SafeStream's default video player\n  * 2. Use your own video player\n  * 3. Implement SafeStream with your own DRM client. \n\nThe watermark post call returns all the data needed to support all three scenarios. Let's take a look at what the response object means:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"{\\n  \\\"status\\\": \\\"READY\\\",\\n  \\\"containers\\\": {\\n    \\\"href\\\": \\\"http://linktotheplayerpage\\\",\\n    \\\"m3u8\\\": \\\"http://api.safestream.com/...\\\"\\n  },\\n  \\\"href\\\": \\\"https://s2-api.safestream.com/2.0/watermark/...\\\"\\n}\",\n      \"language\": \"json\"\n    }\n  ]\n}\n[/block]\n\n[block:parameters]\n{\n  \"data\": {\n    \"0-0\": \"status\",\n    \"h-0\": \"Field\",\n    \"h-1\": \"Description\",\n    \"0-1\": \"READY. or FAILED\",\n    \"1-0\": \"containers.m3u8\",\n    \"1-1\": \"The m3u8 playlist. Use this if you'd like to use your own video player.\\n\\nhttps://en.wikipedia.org/wiki/M3U\",\n    \"2-0\": \"href\",\n    \"2-1\": \"This is a link to this watermark resource. Use this if you'd like to get the same watermark with renewed HMAC signatures.\",\n    \"3-0\": \"containers.href\",\n    \"3-1\": \"The href inside the container is a direct link to the player page. This is useful when constructing your own iframe to add to the page.\"\n  },\n  \"cols\": 2,\n  \"rows\": 4\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"1. Using SafeStream's Default Player\"\n}\n[/block]\nThe most straight forward integration with SafeStream is to use the default video player which is returned in the containers.href property of the watermarking response. Using this approach, the developer just has to submit the watermark request and place the href in a iframe on the page.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"<iframe width='1280' height='720' frameBorder='0' src='<containers.href from watermarking response>'></iframe>\",\n      \"language\": \"html\"\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"2. Integrate With Your Video Player\"\n}\n[/block]\nIf you'd like to integrate with your own player or another third party player, you can use the containers.m3u8 URL in the watermarking response. \n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"3. Integrate with DRM\"\n}\n[/block]\nContact us for integration scenarios with your preferred DRM vendor.\n[block:callout]\n{\n  \"type\": \"danger\",\n  \"title\": \"Creating watermarks should be done server side\",\n  \"body\": \"We strongly recommend that you do not create watermarks directly from the browser. Instead you should request watermarks server side. This endpoint requires your credentials and sending those via JavaScript could weaken the security of your viewing system.\\nHowever, ALL URL's returned in the watermarking response are intended to be used directly in the browser.\"\n}\n[/block]","excerpt":"Add a visual or forensic watermark to you video","slug":"watermark-a-video","type":"endpoint","title":"Watermark a Video"}

postWatermark a Video

Add a visual or forensic watermark to you video

Definition

{{ api_url }}{{ page_api_url }}

Parameters

Body Params

key:
string
Optional: The key of the video that you'd like to watermark.
videoId:
string
Optional: Use the ID SafeStream assigned to this asset during ingest
settings:
array of objects{"content": "Joe Smith", "align":"center", "verticalAlign":"middle" }
An array of watermark settings to be applied to the video that should be watermarked. See below for details on the watermark setting properties.
containers:
array of strings["m3u8","mp4"]
Defaults to m3u8 for HLS playback but also supports MP4 to specifically request a watermarked mp4 video for download.
settingsTemplateMapping:
object"settingsTemplateMapping": { "id": "74fc00c8-847d-4631-94a4-f4ac7d1e4748", "mappings": { "name": "User Name" } }
A mapping object that references an existing watermark template and maps values to placeholders.
viewLimit:
integernull
determines the number of times the watermarked file can be requested. After the limit is reached, the watermarked file will no longer be available.
expiration:
longnull
determines the exact epoch time in SECONDS that the watermark file will no longer be accessible.

Examples


Result Format


Documentation

[block:api-header] { "type": "basic", "title": "Watermarking Overview" } [/block] Once a video has been [ingested](doc:video), you can request a watermark for the video using this endpoint. At it's simplest you just need the ID or KEY of the video and the text that you'd like you have as your watermark. SafeStream will locate the video that you've already ingested and it will apply the watermark to the file. [block:code] { "codes": [ { "code": "{\n \"key\": \"my-internal-id\",\n \"settings\": [\n {\n \"content\": \"Kai Pradel\",\n \"fontColor\": \"FFFFFF\",\n \"y\": 0.02,\n \"x\": 0.02,\n \"fontOpacity\": 0.5,\n \"fontSize\": 0.04,\n \"align\": \"LEFT\",\n \"verticalAlign\": \"TOP\",\n \"shadowColor\": \"000000\",\n \"shadowOffsetX\": 0.08,\n \"shadowOffsetY\": 0.08,\n \"shadowOpacity\": 0.33\n },\n {\n \"content\": \"ACME Studios\",\n \"fontColor\": \"FFFFFF\",\n \"y\": 0.02,\n \"x\": 0.98,\n \"fontOpacity\": 0.5,\n \"fontSize\": 0.04,\n \"align\": \"RIGHT\",\n \"verticalAlign\": \"TOP\",\n \"shadowColor\": \"000000\",\n \"shadowOffsetX\": 0.08,\n \"shadowOffsetY\": 0.08,\n \"shadowOpacity\": 0.33,\n \"animation\": {\n\t\t\t\t\t\"toX\": -0.3,\n\t\t\t\t\t\"startTime\": 8,\n\t\t\t\t\t\"endTime\": 16\n\t \t\t}\n }\n ]\n}", "language": "json" } ] } [/block] [block:api-header] { "type": "basic", "title": "Watermark Using A Template" } [/block] Using [predefined template watermark templates](doc:creating-templates) simplifies the watermark request by referencing an existing template and providing the the placeholder data. A template can contain a placeholder variable such as [%name%] or [%email%] which is then passed into the watermark request along with the template id. [block:code] { "codes": [ { "code": "curl -X \"POST\" \"https://s2-api.safestream.com/2.0/watermark\" \\\n -H \"Content-Type: application/json\" \\\n -H \"x-api-key: [[app:apiKey]]\" \\\n -H \"x-api-client-id: [[app:apiClientId]]\" \\\n -d '{\n \"key\":\"my-internal-id\",\n \"settingsTemplateMapping\": {\n \"id\": \"my-template-id\",\n \"mappings\": {\n \"name\": \"My User\",\n \"email\" : \"user@user.com\",\n \"time\" : \"12:13:11 am\"\n }\n }\n}'", "language": "curl" } ] } [/block] To learn more about creating templates, see [Creating a Template](doc:creating-templates) [block:api-header] { "title": "Embedding a Forensic Watermark" } [/block] In addition to adding a visual watermark, you can also embed an invisible watermark. Doing this requires that the video was initially [ingested](doc:video) with "enableForensic" set to true. The request payload for embedding a forensic watermark is much simpler than for visual watermarking. Rather than specifying display properties, the settings for a forensic watermark only need the bits that should be embedded into the video. Here's an example request body for a forensic watermark: [block:code] { "codes": [ { "code": "{\n \"key\": \"my-internal-id\",\n \"settings\": [\n {\n \"type\":\"FORENSIC\",\n \"content\": \"DIg=\"\n }\n ]\n}", "language": "json" } ] } [/block] First, notice that we've added the "type" property to the request. This is an optional field that allows us to override the default type, TEXT, and set it to FORENSIC. Without this change this video would be visually watermarked with the string "DIg=" rather than embedding a forensic watermark. Second, notice the content, it's a 16 bit base64 encoded payload that we'll ebbed invisibly in the video. The forensic payload for each watermark should be unique to the user who is watching the video. [block:callout] { "type": "warning", "title": "Minimum Video Duration", "body": "Embedding forensic watermarks is not supported on videos with a duration less than 5 minutes." } [/block] [block:api-header] { "type": "basic", "title": "Understanding the Watermarking Response" } [/block] SafeStream supports several integration scenarios: * 1. Use SafeStream's default video player * 2. Use your own video player * 3. Implement SafeStream with your own DRM client. The watermark post call returns all the data needed to support all three scenarios. Let's take a look at what the response object means: [block:code] { "codes": [ { "code": "{\n \"status\": \"READY\",\n \"containers\": {\n \"href\": \"http://linktotheplayerpage\",\n \"m3u8\": \"http://api.safestream.com/...\"\n },\n \"href\": \"https://s2-api.safestream.com/2.0/watermark/...\"\n}", "language": "json" } ] } [/block] [block:parameters] { "data": { "0-0": "status", "h-0": "Field", "h-1": "Description", "0-1": "READY. or FAILED", "1-0": "containers.m3u8", "1-1": "The m3u8 playlist. Use this if you'd like to use your own video player.\n\nhttps://en.wikipedia.org/wiki/M3U", "2-0": "href", "2-1": "This is a link to this watermark resource. Use this if you'd like to get the same watermark with renewed HMAC signatures.", "3-0": "containers.href", "3-1": "The href inside the container is a direct link to the player page. This is useful when constructing your own iframe to add to the page." }, "cols": 2, "rows": 4 } [/block] [block:api-header] { "type": "basic", "title": "1. Using SafeStream's Default Player" } [/block] The most straight forward integration with SafeStream is to use the default video player which is returned in the containers.href property of the watermarking response. Using this approach, the developer just has to submit the watermark request and place the href in a iframe on the page. [block:code] { "codes": [ { "code": "<iframe width='1280' height='720' frameBorder='0' src='<containers.href from watermarking response>'></iframe>", "language": "html" } ] } [/block] [block:api-header] { "type": "basic", "title": "2. Integrate With Your Video Player" } [/block] If you'd like to integrate with your own player or another third party player, you can use the containers.m3u8 URL in the watermarking response. [block:api-header] { "type": "basic", "title": "3. Integrate with DRM" } [/block] Contact us for integration scenarios with your preferred DRM vendor. [block:callout] { "type": "danger", "title": "Creating watermarks should be done server side", "body": "We strongly recommend that you do not create watermarks directly from the browser. Instead you should request watermarks server side. This endpoint requires your credentials and sending those via JavaScript could weaken the security of your viewing system.\nHowever, ALL URL's returned in the watermarking response are intended to be used directly in the browser." } [/block]

User Information

Try It Out

post
{{ tryResults.results }}
Method{{ tryResults.method }}
Request Headers
{{ tryResults.requestHeaders }}
URL{{ tryResults.url }}
Request Data
{{ tryResults.data }}
Status
Response Headers
{{ tryResults.responseHeaders }}