diff --git a/404.html b/404.html index 1bfe5ff6..0b93178e 100644 --- a/404.html +++ b/404.html @@ -4,13 +4,13 @@ Page Not Found | Streams Docs - +
Skip to main content

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

- + \ No newline at end of file diff --git a/assets/js/e6a5ebb5.50958d13.js b/assets/js/e6a5ebb5.50958d13.js deleted file mode 100644 index ce74912d..00000000 --- a/assets/js/e6a5ebb5.50958d13.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkstreams_docs=self.webpackChunkstreams_docs||[]).push([[8],{3905:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>m});var r=t(7294);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function s(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function a(e){for(var n=1;n=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var c=r.createContext({}),l=function(e){var n=r.useContext(c),t=n;return e&&(t="function"==typeof e?e(n):a(a({},n),e)),t},p=function(e){var n=l(e.components);return r.createElement(c.Provider,{value:n},e.children)},d={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},u=r.forwardRef((function(e,n){var t=e.components,o=e.mdxType,s=e.originalType,c=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),u=l(t),m=o,y=u["".concat(c,".").concat(m)]||u[m]||d[m]||s;return t?r.createElement(y,a(a({ref:n},p),{},{components:t})):r.createElement(y,a({ref:n},p))}));function m(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var s=t.length,a=new Array(s);a[0]=u;var i={};for(var c in n)hasOwnProperty.call(n,c)&&(i[c]=n[c]);i.originalType=e,i.mdxType="string"==typeof e?e:o,a[1]=i;for(var l=2;l{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>s,metadata:()=>i,toc:()=>l});var r=t(7462),o=(t(7294),t(3905));const s={sidebar_position:5},a="DRM License",i={unversionedId:"server-api/drm",id:"server-api/drm",title:"DRM License",description:"To play DRM protected videos, your player should request DRM licence from our URL.",source:"@site/docs/server-api/drm.md",sourceDirName:"server-api",slug:"/server-api/drm",permalink:"/docs/server-api/drm",draft:!1,tags:[],version:"current",sidebarPosition:5,frontMatter:{sidebar_position:5},sidebar:"serverAPISidebar",previous:{title:"Live Streams",permalink:"/docs/server-api/live-stream"},next:{title:"Web Hooks",permalink:"/docs/server-api/webhooks"}},c={},l=[],p={toc:l};function d(e){let{components:n,...t}=e;return(0,o.kt)("wrapper",(0,r.Z)({},p,t,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"drm-license"},"DRM License"),(0,o.kt)("p",null,"To play DRM protected videos, your player should request DRM licence from our URL."),(0,o.kt)("p",null,"This API requires ",(0,o.kt)("a",{parentName:"p",href:"/docs/video-embedding/authentication"},"access_token")," in query param for authentication."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-bash"},"POST: https://app.tpstreams.com/api/v1//assets//drm_license/?access_token={{access_token}}/\n")),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"This endpoint should not be directly called from client-side. Your server should called this API and return its response to player.")),(0,o.kt)("p",null,(0,o.kt)("strong",{parentName:"p"},"Sample code")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-html"},'\n\n \n \n \n \n \n - + \ No newline at end of file diff --git a/docs/category/flutter-sdk/index.html b/docs/category/flutter-sdk/index.html index ba112a6c..20ad3e8d 100644 --- a/docs/category/flutter-sdk/index.html +++ b/docs/category/flutter-sdk/index.html @@ -4,13 +4,13 @@ Flutter SDK | Streams Docs - + - + \ No newline at end of file diff --git a/docs/category/ios-native-sdk/index.html b/docs/category/ios-native-sdk/index.html index b0ebd639..dc93792e 100644 --- a/docs/category/ios-native-sdk/index.html +++ b/docs/category/ios-native-sdk/index.html @@ -4,13 +4,13 @@ iOS Native SDK | Streams Docs - + - + \ No newline at end of file diff --git a/docs/category/javascript-sdk/index.html b/docs/category/javascript-sdk/index.html index 36f5cc7f..a4432686 100644 --- a/docs/category/javascript-sdk/index.html +++ b/docs/category/javascript-sdk/index.html @@ -4,13 +4,13 @@ Javascript SDK | Streams Docs - + - + \ No newline at end of file diff --git a/docs/category/plugins/index.html b/docs/category/plugins/index.html index 6d8c498f..bd4de23b 100644 --- a/docs/category/plugins/index.html +++ b/docs/category/plugins/index.html @@ -4,13 +4,13 @@ Plugins | Streams Docs - + - + \ No newline at end of file diff --git a/docs/drm-service/encrypting/index.html b/docs/drm-service/encrypting/index.html index 050b861b..7cdd5956 100644 --- a/docs/drm-service/encrypting/index.html +++ b/docs/drm-service/encrypting/index.html @@ -4,14 +4,14 @@ Encrypting the content | Streams Docs - +

Encrypting the content

The encryption process varies depending on the technology used. For Widevine and FairPlay, there are different entry paths and parameters involved in encrypting content. Each DRM provider has its own distinct approach to ensure secure protection for media content.

Widevine Encryption

Shaka Packager is used for encrypting content and offers seamless integration with Widevine, making it a popular choice for ensuring secure delivery through the Widevine DRM technology. Shaka Packager

To encrypt your content, you can utilize Shaka Packager by running the following command with authentication Header. :


packager \
in=https://static.testpress.in/BigBuckBunny.mp4,stream=audio,output=audio.mp4 \
in=https://static.testpress.in/BigBuckBunny.mp4,stream=video,output=h264_360p.mp4 \
--enable_widevine_encryption \
--key_server_url https://app.tpstreams.com/api/v1/<org_code>/widevine_key/ \
--content_id <content_id> \
--signer testpress \
--aes_signing_key <WIDEWINE_AES_KEY> \
--aes_signing_iv <WIDEWINE_IV> \
--mpd_output video.mpd

Fields

NameTypeDescriptionRequired
org_codestringThe organization code for API endpointYes
content_idstringThe unique identifier for the content (Should be a random UUID generated you. This UUID will be used for getting licenses for that video.)Yes
WIDEVINE_AES_KEYstringThe AES key used for Widevine encryptionYes
WIDEVINE_IVstringThe initialization vector (IV) for Widevine encryptionYes
info

WIDEWINE_AES_KEY , WIDEWINE_IV and org_code will be provided by us.

Fairplay Encryption

This API allows users to obtain a FairPlay encryption key. It provides the necessary functionality to acquire the encryption key for ensuring secure content delivery on Apple's platforms.

This API requires authentication Header

POST: https://app.tpstreams.com/api/v1/{{org_code}}/fairplay_key/

with request body:

{
"request": "eyJjb250ZW50X2lkIjoiY2Y2YzMwZGQ1MGMxNDkyZTgyMzQ0ZWEzZTEzOWRhMWQifQ==",
"signature": "NsBcxxchrA7tFw/O86SCM5hwiM6Np/+JnZgjlV0vRyo="
}

Generating Request Body:

You can obtain the request field by performing the following steps in Python:

import json
import base64

data = {"content_id": "cf6c30dd50c1492e82344ea3e139da1d"}
data = json.dumps(data, separators=(',', ':'))
result = base64.urlsafe_b64encode(data.encode())
# The result will be eyJjb250ZW50X2lkIjoiY2Y2YzMwZGQ1MGMxNDkyZTgyMzQ0ZWEzZTEzOWRhMWQifQ==

Generating Signature:

You can obtain the signature field by performing the following steps in Python:

import base64
import binascii
import hashlib
import json


from Cryptodome.Cipher import AES
from Cryptodome.Util.Padding import pad

def generate_signature(data, key, iv):
hash = hashlib.sha1(base64.b64encode(data.encode())).digest()
cipher = AES.new(
binascii.unhexlify(key),
AES.MODE_CBC,
binascii.unhexlify(iv),
)
padded_hash = pad(hash, AES.block_size, style="pkcs7")
signature = cipher.encrypt(padded_hash)
return base64.b64encode(signature).decode()

key = "xxxx" # AES Signing key
iv = "yyy" # AES Signing iv
data = {
"content_id": "cf6c30dd50c1492e82344ea3e139da1d"
}
data = json.dumps(data, separators=(',', ':'))
signature = generate_signature(data, key, iv)
result = base64.urlsafe_b64encode(data.encode())

post_data = {
"request": result,
"signature": signature
}

Response

{
"iv": "f70bce4094fd4612abac60d9809c5b0c",
"key": "3ab60de900d64edf9cb25a76f81794e6",
"uri": "skd://e5573f8bb8ac47ea839a65beae73263d",
}
- + \ No newline at end of file diff --git a/docs/drm-service/get-license/index.html b/docs/drm-service/get-license/index.html index 3c6e3fd9..4b035fc4 100644 --- a/docs/drm-service/get-license/index.html +++ b/docs/drm-service/get-license/index.html @@ -4,13 +4,13 @@ Getting license to playback the content | Streams Docs - +

Getting license to playback the content

Obtaining a license is essential for enabling playback of DRM-protected content. The process involves acquiring a valid license through the DRM system, granting authorized users access to view the protected media on their devices.

This API requires authentication Header

POST: https://app.tpstreams.com/api/v1/<org_code>/drm_license/?data=<encoded_data>/

Fields

NameTypeDescriptionRequired
org_codestringThe organization code for API endpointYes
content_idstringThe unique identifier for the content (Should be a random UUID generated you. This UUID will be used for getting licenses for that video.)Yes
WIDEVINE_AES_KEYstringThe AES key used for Widevine encryptionYes
WIDEVINE_IVstringThe initialization vector (IV) for Widevine encryptionYes
info

WIDEWINE_AES_KEY , WIDEWINE_IV and org_code will be provided by us.

Generating Encoded Data:

To generate encoded data you need to fetch content data and signature

{
"content_data": "eyJkb3dubG9hZCI6ZmFsc2UsImRybV90eXBlIjoid2lkZXZpbmUiLCJjb250ZW50X2lkIjoiYTM1NmFhZWYzMGFhNGNkODlmNzY2ZjVmNjUzN2FjMzMifQ==",
"signature": "NsBcxxchrA7tFw/O86SCM5hwiM6Np/+JnZgjlV0vRyo="
}

Generating Content Data:

You can obtain the request field by performing the following steps in Python:

import json
import base64

data = {
"content_id": <content_id>,
"download": true/false,
"drm_type": "widevine/fairplay"
}
data = json.dumps(data, separators=(',', ':'))
encoded_content_data = base64.urlsafe_b64encode(data.encode())
# The result will be eyJjb250ZW50X2lkIjoiY2Y2YzMwZGQ1MGMxNDkyZTgyMzQ0ZWEzZTEzOWRhMWQifQ==

Generating Signature:

You can obtain the signature field by performing the following steps in Python:

import base64
import binascii
import hashlib
import json


from Cryptodome.Cipher import AES
from Cryptodome.Util.Padding import pad

def generate_signature(data, key, iv):
hash = hashlib.sha1(base64.b64encode(data.encode())).digest()
cipher = AES.new(
binascii.unhexlify(key),
AES.MODE_CBC,
binascii.unhexlify(iv),
)
padded_hash = pad(hash, AES.block_size, style="pkcs7")
signature = cipher.encrypt(padded_hash)
return base64.b64encode(signature).decode()

key = "xxxx" # AES Signing key
iv = "yyy" # AES Signing iv
data = {
"content_id": "cf6c30dd50c1492e82344ea3e139da1d"
}
data = json.dumps(data, separators=(',', ':'))
signature = generate_signature(data, key, iv)

You can obtain the Encoded data by performing the following steps in Python:

import base64
import binascii
import hashlib
import json


from Cryptodome.Cipher import AES
from Cryptodome.Util.Padding import pad

key = "xxxx" # AES Signing key
iv = "yyy" # AES Signing iv
org_code = "xxxx"

content_data = {"content_id": "cf6c30dd50c1492e82344ea3e139da1d", "download": "true", "drm_type": "widevine"}
content_data = json.dumps(content_data, separators=(',', ':'))
encoded_content_data = base64.urlsafe_b64encode(content_data.encode())
signature = generate_signature(encoded_content_data)
data = {"content_data": encoded_content_data, "signature": signature}
data = json.dumps(data, separators=(',', ':'))
encoded_data = base64.urlsafe_b64encode(data)


LICENSE_URL = f"https://app.tpstreams.com/api/v1/{org_code}/drm_license/?data={encoded_data}"
- + \ No newline at end of file diff --git a/docs/drm-service/getting-started/index.html b/docs/drm-service/getting-started/index.html index de7478a3..d1c47168 100644 --- a/docs/drm-service/getting-started/index.html +++ b/docs/drm-service/getting-started/index.html @@ -4,13 +4,13 @@ DRM Service | Streams Docs - +

DRM Service

DRM (Digital Rights Management) is a technology that enables content creators and distributors to safeguard their media content on the TP Streams system, ensuring that only authorized users have access during processing and delivery. It prevents unauthorized copying and distribution, maintaining content security and protecting ownership rights.

Currently, there are two major DRM providers:

  • Widevine by Google: This DRM solution is used for Windows, Linux, and Android devices, ensuring content protection and security on these platforms.

  • FairPlay by Apple: FairPlay is Apple's DRM technology specifically designed for Mac and iOS devices, safeguarding media content and maintaining copyright protection for users of these devices.

DRM Service consists of two parts

  • Encrypting the content
  • Getting license to playback the content
- + \ No newline at end of file diff --git a/docs/mobile-sdk/android-native-sdk/getting-started/index.html b/docs/mobile-sdk/android-native-sdk/getting-started/index.html index 3c3d3c1c..00f36e13 100644 --- a/docs/mobile-sdk/android-native-sdk/getting-started/index.html +++ b/docs/mobile-sdk/android-native-sdk/getting-started/index.html @@ -4,13 +4,13 @@ Getting Started | Streams Docs - +

Getting Started

This SDK enables you to securely stream DRM-protected videos through your Android app.

Sample Android App

Adding dependency

  • If you have a settings.gradle file in your project root, then you need to add the repositories in the settings.gradle inside dependencyResolutionManagement with the given path below. Else, this will go in build.gradle file in project root.
repositories {
// other repo, e.g. google() or mavenCentral()
maven {
url "https://github.com/testpress/maven/raw/main/repo"
}
}

Then reference the library in the dependency section:

dependencies {
implementation "com.tpstreams.player:player:1.0.14b"
}

Using ProGuard

If you use ProGuard in your app, you might need to add the following rule to your ProGuard file.

-keep class com.tpstream.player.** { *; }

Integrating player fragment

Drop a TpStreamPlayerFragment into your activity layout with an id. This is the fastest and easiest way to integrate the player into your application. TpStreamPlayerFragment includes a prebuilt UI for the player with ample features and functionality.

<androidx.fragment.app.FragmentContainerView
android:id="@+id/tpstream_player_fragment"
android:name="com.tpstream.player.TpStreamPlayerFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:keepScreenOn="true"
tools:layout="@layout/fragment_tp_stream_player" />

and receive its instance in your activity using findFragmentbyId()

playerFragment = supportFragmentManager.findFragmentById(R.id.tpstream_player_fragment) as TpStreamPlayerFragment

Initializing Player And Starting Playback

You can set listener class with onInitializationSuccess method and receive the player in the onInitializationSuccess callback.

playerFragment.setOnInitializationListener(object: InitializationListener {
override fun onInitializationSuccess(player: TpStreamPlayer) {
Log.i(TAG, "onInitializationSuccess");
this.player = player
}
})

Once you have a player, you can start loading media onto it for playback. You'll need a TpInitParams object to specify which media to load along with your playback preferences.

A TpInitParams object needs videoId, accessToken and orgCode.

val parameters = TpInitParams.Builder()
.setVideoId(videoId)
.setAccessToken(accessToken)
.setOrgCode("organization_id") // app.tpstreams.com/api/v1/organizations_id/
.build()
player.load(parameters)

Final code will look like this

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_player)
playerFragment =
supportFragmentManager.findFragmentById(R.id.tpstream_player_fragment) asTpStreamPlayerFragment
playerFragment.setOnInitializationListener(object: InitializationListener {
override fun onInitializationSuccess(player: TpStreamPlayer) {
val parameters = TpInitParams.Builder()
.setVideoId(videoId)
.setAccessToken(accessToken)
.setOrgCode("organization_id")
.build()
player.load(parameters)
}
});
}

Call this below method to enable auto fullscreen on rotate

  playerFragment.enableAutoFullScreenOnRotate()
- + \ No newline at end of file diff --git a/docs/mobile-sdk/android-native-sdk/offline-downloads/index.html b/docs/mobile-sdk/android-native-sdk/offline-downloads/index.html index dd955a93..3f578eff 100644 --- a/docs/mobile-sdk/android-native-sdk/offline-downloads/index.html +++ b/docs/mobile-sdk/android-native-sdk/offline-downloads/index.html @@ -4,13 +4,13 @@ Offline Downloads | Streams Docs - +

Offline Downloads

We'll explore the workflow in this document.The Sample Android App on Github provides code examples for a typical use case.

Enable Download support

Create TpInitParams with .enableDownloadSupport(true) to enable download support.

var parameters = TpInitParams.Builder()
.setVideoId(videoId)
.setAccessToken(accessToken)
.setOrgCode("organization_id") // app.tpstreams.com/api/v1/organizations_id/
.enableDownloadSupport(true)
.build()

Creating a TpStreamsDownloadManager

The following code snippet demonstrates how to instantiate a TpStreamsDownloadManager

val tpStreamDownloadManager : TpStreamDownloadManager = TpStreamDownloadManager(activityContext)

Using this TpStreamDownloadManager we can get a list of downloaded media and the following media operations to delete, pause, resume, and cancel.

Get list of downloaded media

val downloads : LiveData<List<Video>?> = tpStreamDownloadManager.getAllDownloads()

It will return a list of OfflineVideoInfo in LiveData to monitor the download progress use ViewModel and observe.

Delete

tpStreamDownloadManager.deleteDownload(video)

Pause

tpStreamDownloadManager.pauseDownload(video)

Resume

tpStreamDownloadManager.resumeDownload(video)

Cancel

tpStreamDownloadManager.cancelDownload(video)

Delete All

tpStreamDownloadManager.deleteAllDownload()

Playing downloaded media

Create offline params and pass them to player activity via intent to play an offline video.

val intent = Intent(activityContext,PlayerActivity::class.java)
intent.putExtra(TP_OFFLINE_PARAMS,TpInitParams.createOfflineParams(video.videoId))
startActivity(intent)
- + \ No newline at end of file diff --git a/docs/mobile-sdk/flutter-sdk/getting-started/index.html b/docs/mobile-sdk/flutter-sdk/getting-started/index.html index 778aaf0a..be166e00 100644 --- a/docs/mobile-sdk/flutter-sdk/getting-started/index.html +++ b/docs/mobile-sdk/flutter-sdk/getting-started/index.html @@ -4,14 +4,14 @@ Getting Started | Streams Docs - +

Getting Started

To use our Flutter player SDK, add tpstreams_player_sdk as a dependency in your pubspec.yaml file.

Initializing TPStreamsSDK

First, imported our package:

import 'package:tpstreams_player_sdk/tpstreams_player_sdk.dart';

Next, you can initialize the TPStreamsSDK with your organization code.

TPStreamsSDK.initialize(orgCode: "YOUR_ORG_CODE");

Make sure to replace "YOUR_ORG_CODE" with your actual organization code. This code snippet should be placed at the entry point of your application (usually in the main function) to ensure proper initialization of the TPStreamsSDK.

Play a Video

To play a video using the TPStreams Player SDK, use the TPStreamPlayer widget:

TPStreamPlayer(assetId: 'ASSET_ID', accessToken: 'ACCESS_TOKEN')

Replace ASSET_ID and ACCESS_TOKEN with the actual assetId and accessToken of the video you wish to play. After executing your Flutter application, the TPStreams player will display the video specified by the provided assetId and accessToken.

For a practical implementation and usage of tpstreams_player_sdk, refer to our Sample Flutter App.

- + \ No newline at end of file diff --git a/docs/mobile-sdk/ios-native-sdk/getting-started/index.html b/docs/mobile-sdk/ios-native-sdk/getting-started/index.html index e11c4738..ea9b3c23 100644 --- a/docs/mobile-sdk/ios-native-sdk/getting-started/index.html +++ b/docs/mobile-sdk/ios-native-sdk/getting-started/index.html @@ -4,13 +4,13 @@ Getting Started | Streams Docs - +

Getting Started

TPStreamsSDK is a versatile iOS native SDK with support for both DRM (FairPlay) and non-DRM content.

Requirements

Before integrating TPStreamsSDK into your iOS application, ensure that your project meets the following requirement:

  • Minimum Deployment Version: iOS 11.4 or later
  • Swift: Version 5.5 or later

Integration using Swift Package Manager (SPM)

To add TPStreamsSDK to your Xcode project using Swift Package Manager, follow these steps:

  • Select File > Add Packages in Xcode.
  • In the search bar, enter the following URL: https://github.com/testpress/iOSPlayerSDK.
  • Select 'iOSPlayerSDK' from the search results. Click Add package button.

Once the package is added, you can start using TPStreamsSDK in your iOS application.

Initializing TPStreamsSDK

In the application(_:didFinishLaunchingWithOptions:) method in your AppDelegate, call TPStreamsSDK.initialize(withOrgCode:) to initialize the SDK with your organization code.

class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
TPStreamsSDK.initialize(withOrgCode: "YOUR_ORGANIZATION_CODE")
return true
}
}

Please note that the above code assumes you are using SwiftUI for your application. If you are using a different app architecture, you may need to adapt the integration steps accordingly.

Playing a Video with TPStreamsSDK

SwiftUI Integration

  1. Instantiate a TPAVPlayer by providing the appropriate assetID and accessToken.
  2. Embed the TPStreamPlayerView in your SwiftUI view.
struct ContentView: View {
let player = TPAVPlayer(assetID: "YOUR_ASSET_ID", accessToken: "YOUR_ACCESS_TOKEN")

var body: some View {
VStack {
TPStreamPlayerView(player: player)
.frame(height: 240)
Spacer()
}
}
}

UIKit Integration

  1. Instantiate a TPAVPlayer with the relevant assetID and accessToken.
  2. Create an TPStreamPlayerViewController and assign the previously created TPAVPlayer to the player attribute.
  3. Add the TPStreamPlayerViewController.view to the view hierarchy. This will display the video player within the specified playerContainer view.
class ViewController: UIViewController {
@IBOutlet weak var playerContainer: UIView!

var playerViewController: TPStreamPlayerViewController?
var player: TPAVPlayer?

override func viewDidLoad() {
super.viewDidLoad()
self.setupPlayerView()
player?.play()
}

func setupPlayerView(){
player = TPAVPlayer(assetID: "YOUR_ASSET_ID", accessToken: "YOUR_ACCESS_TOKEN")
playerViewController = TPStreamPlayerViewController()
playerViewController?.player = player

addChild(playerViewController!)
playerContainer.addSubview(playerViewController!.view)
playerViewController!.view.frame = playerContainer.bounds
}
}
info

TPAVPlayer is a wrapper class of AVPlayer that provides built-in support for playing our videos without requiring additional effort. It also supports FairPlay streaming for DRM-protected content.

Since TPAVPlayer is a wrapper class of AVPlayer, you can also use the TPAVPlayer with native iOS player to play Streams Videos.

For a practical implementation and usage of TPStreamsSDK, refer to our Sample iOS App.

- + \ No newline at end of file diff --git a/docs/server-api/access-token/index.html b/docs/server-api/access-token/index.html index ee095726..9a2cd6fc 100644 --- a/docs/server-api/access-token/index.html +++ b/docs/server-api/access-token/index.html @@ -4,13 +4,13 @@ Access token | Streams Docs - +

Access token

For Creation API, Please check here

List Access tokens

Make get request to the below API with your video id to list access tokens

https://app.tpstreams.com/api/v1/{{org_code}}/assets/{{asset_id}}/access_tokens/

Query parameters

ParameterData type
is_activeboolean

Response

{
"count": 3,
"next": null,
"previous": null,
"results": [
{
"playback_url": "https://app.tpstreams.com/embed/d2ff26b2-f88e-4d6d-a9ce-bb0e3ce858cc/?access_token=e91e2bf4-a3ab-493f-8685-7b88ea943c5a",
"expires_after_first_usage": false,
"code": "e91e2bf4-a3ab-493f-8685-7b88ea943c5a",
"status": "Active",
"valid_until": null,
"annotations": [
{
"text": "moving text",
"type": "dynamic",
"color": "#FF0000",
"opacity": "0.80",
"size": 15,
"interval": 1000,
"skip": 0,
"x": 16,
"y": 16
},
{
"text": "moving text 2",
"type": "dynamic",
"color": "#FF0000",
"opacity": "0.80",
"size": 15,
"interval": 1000,
"skip": 0,
"x": 16,
"y": 16
}
]
},
{
"playback_url": "https://app.tpstreams.com/embed/d2ff26b2-f88e-4d6d-a9ce-bb0e3ce858cc/?access_token=a33ab940-2fc5-44e8-bb7a-222ee06f023b",
"expires_after_first_usage": false,
"code": "a33ab940-2fc5-44e8-bb7a-222ee06f023b",
"status": "Active",
"valid_until": null,
"annotations": [
{
"text": "moving text",
"type": "dynamic",
"color": "#FF0000",
"opacity": "0.80",
"size": 15,
"interval": 1000,
"skip": 0,
"x": 16,
"y": 16
},
{
"text": "moving text 2",
"type": "dynamic",
"color": "#FF0000",
"opacity": "0.80",
"size": 15,
"interval": 1000,
"skip": 0,
"x": 16,
"y": 16
}
]
},
{
"playback_url": "https://app.tpstreams.com/embed/d2ff26b2-f88e-4d6d-a9ce-bb0e3ce858cc/?access_token=609fb114-d45d-4b64-9c95-3a2334bec0ad",
"expires_after_first_usage": false,
"code": "609fb114-d45d-4b64-9c95-3a2334bec0ad",
"status": "Active",
"valid_until": null,
"annotations": [
{
"text": "moving text",
"type": "dynamic",
"color": "#FF0000",
"opacity": "0.80",
"size": 15,
"interval": 1000,
"skip": 0,
"x": 16,
"y": 16
},
{
"text": "moving text 2",
"type": "dynamic",
"color": "#FF0000",
"opacity": "0.80",
"size": 15,
"interval": 1000,
"skip": 0,
"x": 16,
"y": 16
}
]
}
]
}

View Access token

Make get request to the below API with your video id and access token code to get the access token details

https://app.tpstreams.com/api/v1/{{org_code}}/assets/{{asset_id}}/access_tokens/{access_token_code}/

Response

    {
"playback_url": "https://app.tpstreams.com/embed/d2ff26b2-f88e-4d6d-a9ce-bb0e3ce858cc/?access_token=e91e2bf4-a3ab-493f-8685-7b88ea943c5a",
"expires_after_first_usage": false,
"code": "e91e2bf4-a3ab-493f-8685-7b88ea943c5a",
"status": "Active",
"valid_until": null,
"annotations": [
{
"text": "moving text",
"type": "dynamic",
"color": "#FF0000",
"opacity": "0.80",
"size": 15,
"interval": 1000,
"skip": 0,
"x": 16,
"y": 16
}
]
}

Update Access token

https://app.tpstreams.com/api/v1/{{org_code}}/assets/{{asset_id}}/access_tokens/{access_token_code}/

This code below updates the access_token time_to_live.

{
time_to_live: 300
}

Response

{
"playback_url": "https://app.tpstreams.com/embed/d2ff26b2-f88e-4d6d-a9ce-bb0e3ce858cc/?access_token=e91e2bf4-a3ab-493f-8685-7b88ea943c5a",
"expires_after_first_usage": false,
"code": "e91e2bf4-a3ab-493f-8685-7b88ea943c5a",
"status": "Active",
"valid_until": "2022-08-30T14:24:23.835382Z",
"annotations": []
}
- + \ No newline at end of file diff --git a/docs/server-api/assets/index.html b/docs/server-api/assets/index.html index 80cb7b0c..1afb449b 100644 --- a/docs/server-api/assets/index.html +++ b/docs/server-api/assets/index.html @@ -4,13 +4,13 @@ Assets | Streams Docs - +

Assets

  • An asset refers to a media content/video that is processed, stored, and delivered through Streams. This endpoint creates an asset allowing users to ingest media content into the TP Streams system for processing and delivery.

Upload an video

To Upload a asset you need to send an HTTP POST request to the API Endpoint, with the authentication Header.

https://app.tpstreams.com/api/v1/<organization_id>/assets/videos/

Fields

NameTypeDescriptionRequired
content_protection_typestringTo ensure the security of your video content, you can choose from available protection types: 'drm', 'aes' encryption, or indicate 'disable' for no specific protection. Each option offers varying levels of security for your content.No
titlestringSpecify a text string or identifier which can be used for filtering or searching the asset.No
resolutionsarrayRequired resolutions of the transformed asset in case of HLS or MPEG-DASH delivery format. Can be a comma separated string out of the following values: 240p, 360p, 480p, 540p, 720p, and 1080p. Re-sized rendition will retain the input aspect ratio.Yes
inputsjsonURL or web address of a file that TP streams should download to create a new asset.Yes
folderstringThe UUID of the folder, if you want to upload the video into that specific folderNo

Sample request body

{
"title": "Big Buck Bunny Video",
"inputs": [
{
"url": "https://static.testpress.in/BigBuckBunny.mp4"
}
],
"resolutions": ["240p", "360p", "480p", "720p"],
"content_protection_type": "drm",
"folder": "32seYYHeNxE"
}

For valid requests the API server returns a JSON:

{
"id": "9328558d-e0a5-4093-b3b9-8f15ad1550d8", // asset id
"title": "Big Buck Bunny Video",
"bytes": null,
"type": "video",
"video": {
"progress": 0,
"thumbnails": [],
"status": "Completed",
"playback_url": "https://d7pdowhru2wq4.cloudfront.net/transcoded/9328558d-e0a5-4093-b3b9-8f15ad1550d8/video.m3u8",
"dash_url": "https://d7pdowhru2wq4.cloudfront.net/transcoded/9328558d-e0a5-4093-b3b9-8f15ad1550d8/video.mpd",
"preview_thumbnail_url": null,
"format": "abr",
"resolutions": ["240p", "360p", "480p", "720p"],
"video_codec": "h264",
"audio_codec": "aac",
"content_protection_type": "drm",
"tracks": [],
"inputs": [
{
"url": "https://static.testpress.in/BigBuckBunny.mp4"
}
],
},
"parent_id": "32seYYHeNxE",
}

Above response can also be obtained by asset detail API /api/v1/<organization_id>/assets/<asset_id>/

Get all the assets that belong to the organization

To get all assets in the organization, you need to send an HTTP GET request to the API Endpoint, with the authentication Header.

Endpoint

https://app.tpstreams.com/api/v1/<organization_id>/assets/

Response

{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"id": "9328558d-e0a5-4093-b3b9-8f15ad1550d8",
"title": "Big Buck Bunny Video",
"bytes": null,
"type": "video",
"video": {
"progress": 0,
"thumbnails": [],
"status": "Completed",
"playback_url": "https://d7pdowhru2wq4.cloudfront.net/transcoded/9328558d-e0a5-4093-b3b9-8f15ad1550d8/video.m3u8",
"dash_url": "https://d7pdowhru2wq4.cloudfront.net/transcoded/9328558d-e0a5-4093-b3b9-8f15ad1550d8/video.mpd",
"preview_thumbnail_url": null,
"format": "abr",
"resolutions": [
"240p"
],
"video_codec": "h264",
"audio_codec": "aac",
"content_protection_type": "drm",
"tracks": [],
"inputs": [
{
"url": "https://static.testpress.in/BigBuckBunny.mp4"
}
],
},
"parent_id": "32seYYHeNxE",
}
]
}

Get Individual Asset Details

To get a individual asset in the organization, you need to send an HTTP GET request to the API Endpoint, with the authentication Header.

Endpoint

https://app.tpstreams.com/api/v1/<organization_id>/assets/<asset_id>/

Response

{
"title": "sample.mp4",
"bytes": null,
"type": "video",
"video": {
"progress": 0,
"thumbnails": [],
"status": "Completed",
"playback_url": "https://d28qihy7z761lk.cloudfront.net/transcoded/56761978-503c-4ad9-9eca-dff4c4cc12db/video.m3u8",
"dash_url": "https://d28qihy7z761lk.cloudfront.net/transcoded/56761978-503c-4ad9-9eca-dff4c4cc12db/video.mpd",
"preview_thumbnail_url": null,
"format": "abr",
"resolutions": [
"240p"
],
"video_codec": "h264",
"audio_codec": "aac",
"content_protection_type": "drm",
"tracks": [],
"inputs": [
{
"url": "private/e3e153564cb641b08edb3ae9c85c7211.mp4"
}
]
},
"id": "56761978-503c-4ad9-9eca-dff4c4cc12db",
"live_stream": null,
"parent_id": "32seYYHeNxE",
}

Delete Individual Asset

To delete a individual asset in the organization, you need to send an HTTP DELETE request to the API Endpoint, with the authentication Header.

Endpoint

https://app.tpstreams.com/api/v1/<organization_id>/assets/<asset_id>/

If the specified asset is a folder, it will remove all its child assets.

This will delete the specified asset from your organization

- + \ No newline at end of file diff --git a/docs/server-api/authentication/index.html b/docs/server-api/authentication/index.html index bfd35ce7..ff5309e1 100644 --- a/docs/server-api/authentication/index.html +++ b/docs/server-api/authentication/index.html @@ -4,13 +4,13 @@ Authentication | Streams Docs - +

Authentication

You need authentication token to access Streams data and resources through the API

Generate authentication token

Make Post request to the below link with the credentials to generate an authentication token.

POST https://app.tpstreams.com/api/auth/login/

NameTypeDescription
usernamestringEmail address of the user
passwordstringPassword of the user
organization_idstringOrganization id

Sample code

import requests

url = "https://app.tpstreams.com/api/auth/login/"

payload = "{\n \"username\": \"hari@example.com\",\n \"password\": \"welcome\",\n \"organization_id\": \"auhf2k\"}"
headers = {
'content-type': "application/json",
'cache-control': "no-cache",
}

response = requests.request("POST", url, data=payload, headers=headers)

print(response.text)

Response

The response will return an token which should be prefixed with Token and included in all API requests to the server in a header that looks like the following:

Authorization: Token auth-token-string
- + \ No newline at end of file diff --git a/docs/server-api/drm/index.html b/docs/server-api/drm/index.html index 78235aeb..7a239d87 100644 --- a/docs/server-api/drm/index.html +++ b/docs/server-api/drm/index.html @@ -4,13 +4,13 @@ DRM License | Streams Docs - +
-

DRM License

To play DRM protected videos, your player should request DRM licence from our URL.

This API requires access_token in query param for authentication.

POST: https://app.tpstreams.com/api/v1/<organization_id>/assets/<asset_id>/drm_license/?access_token={{access_token}}/
note

This endpoint should not be directly called from client-side. Your server should called this API and return its response to player.

Sample code

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link
href="https://cdnjs.cloudflare.com/ajax/libs/video.js/7.11.7/video-js.min.css"
rel="stylesheet"
/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/video.js/7.11.7/video.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/videojs-contrib-eme@3.8.0/dist/videojs-contrib-eme.js"></script>
<title>Test VideJS DRM</title>
</head>
<body>
<div style="margin: 50px auto; max-width: 400px">
<video id="my-video" class="video-js"></video>
</div>
<script>
const license_url = "" // replace with your endpoint which returns DRM license response
var player = videojs(
"my-video",
{
controls: true,
fluid: true,
html5: {
vhs: {
overrideNative: true,
},
},
},
function () {
var player = this;
player.eme();
player.src({
src: "https://d7pdowhru2wq4.cloudfront.net/transcoded/8b9b948e-192d-4474-b909-5ac5c27918eb/video.mpd",
type: "application/dash+xml",
keySystems: {
"com.widevine.alpha": {
getLicense: (emeOptions, keyMessage, callback) => {
let headers = {};
let body = undefined;

headers["Content-type"] = "application/octet-stream";
body = keyMessage;

videojs.xhr(
{
url: license_url,
method: "POST",
body: body,
responseType: "arraybuffer",
headers: headers,
},
(err, response, responseBody) => {
if (err) {
callback(err);
return;
}

if (
response.statusCode >= 400 &&
response.statusCode <= 599
) {
// Pass an empty object as the error to use the default code 5 error message
callback({});
return;
}

callback(null, responseBody);
}
);
},
},
},
});
}
);
</script>
</body>
</html>

- +

DRM License

To play DRM protected videos, your player should request DRM licence from our URL.

This API requires access_token in query param for authentication.

POST: https://app.tpstreams.com/api/v1/<organization_id>/assets/<asset_id>/drm_license/?access_token={{access_token}}

Sample code

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link
href="https://cdnjs.cloudflare.com/ajax/libs/video.js/7.11.7/video-js.min.css"
rel="stylesheet"
/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/video.js/7.11.7/video.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/videojs-contrib-eme@3.8.0/dist/videojs-contrib-eme.js"></script>
<title>Test VideJS DRM</title>
</head>
<body>
<div style="margin: 50px auto; max-width: 400px">
<video id="my-video" class="video-js"></video>
</div>
<script>
const license_url = "" // replace with your endpoint which returns DRM license response
var player = videojs(
"my-video",
{
controls: true,
fluid: true,
html5: {
vhs: {
overrideNative: true,
},
},
},
function () {
var player = this;
player.eme();
player.src({
src: "https://d7pdowhru2wq4.cloudfront.net/transcoded/8b9b948e-192d-4474-b909-5ac5c27918eb/video.mpd",
type: "application/dash+xml",
keySystems: {
"com.widevine.alpha": {
getLicense: (emeOptions, keyMessage, callback) => {
let headers = {};
let body = undefined;

headers["Content-type"] = "application/octet-stream";
body = keyMessage;

videojs.xhr(
{
url: license_url,
method: "POST",
body: body,
responseType: "arraybuffer",
headers: headers,
},
(err, response, responseBody) => {
if (err) {
callback(err);
return;
}

if (
response.statusCode >= 400 &&
response.statusCode <= 599
) {
// Pass an empty object as the error to use the default code 5 error message
callback({});
return;
}

callback(null, responseBody);
}
);
},
},
},
});
}
);
</script>
</body>
</html>

+ \ No newline at end of file diff --git a/docs/server-api/folders/index.html b/docs/server-api/folders/index.html index ed584eff..55d8c407 100644 --- a/docs/server-api/folders/index.html +++ b/docs/server-api/folders/index.html @@ -4,13 +4,13 @@ Folders | Streams Docs - +

Folders

Create a folder

To create a folder, you need to send an HTTP POST request to the API Endpoint, along with the authentication Header.

https://app.tpstreams.com/api/v1/<organization_id>/assets/folders/

Fields

NameTypeDescriptionRequired
titlestringThe name of the folderYes
parentstringThe UUID of the parent folder, if you want to create the folder as a childNo

Sample request body

{
"title": "CAT videos",
"parent": "32seYYHeNxE"
}

For valid requests the API server returns a JSON:

{
"title": "CAT videos",
"uuid": "46seZZHAnWE", // folder id
}

- + \ No newline at end of file diff --git a/docs/server-api/live-stream/index.html b/docs/server-api/live-stream/index.html index 78f78cdf..95e6af10 100644 --- a/docs/server-api/live-stream/index.html +++ b/docs/server-api/live-stream/index.html @@ -4,7 +4,7 @@ Live Streams | Streams Docs - + @@ -13,7 +13,7 @@ /api/v1/<organization_id>/assets/<asset_id>/

info
  • Scheduled live streams will not automatically start at the specified time; they must be manually initiated.
  • RTMP URL and stream key will be available once you start the stream

Start the server for the scheduled live stream

To Start a server for the scheduled live stream you need to send an HTTP POST request to the API Endpoint, with the authentication Header.

https://app.tpstreams.com/api/v1/<organization_id>/assets/<str:asset_id>/start_server/

For valid requests the API server returns a JSON:

{
"title": "Data science Live class",
"bytes": null,
"type": "livestream",
"video": null,
"id": "8XGEEj6ptnB",
"live_stream": {
"rtmp_url": "",
"stream_key": null,
"status": "Not Started",
"hls_url": "https://d3cydmgt9q030i.cloudfront.net/live/edee9b/8XGEEj6ptnB/video.m3u8",
"start": "2024-10-05 15:30:00",
"transcode_recorded_video": true,
"enable_drm": false,
"chat_embed_url": "https://app.tpstreams.com/live-chat/edee9b/8XGEEj6ptnB/",
"resolutions": [
"240p",
"480p",
"720p"
]
},
"parent": null,
"parent_id": null
}

This will start the server for specified live stream

Above response has the details of the live stream started which can also be obtained by API /api/v1/<organization_id>/assets/<asset_id>/

info
  • The live stream server typically takes around 20-30 seconds to start.
  • Once it's up and running, both the "rtmp_url" and "stream_key" will become accessible.

To automatically receive rtmp_url and stream key as soon as the server is established,Create a Web Hook.

After successfully registering the webhook, you will receive an updated webhook response.

Stop a live stream

To Stop a live stream you need to send an HTTP POST request to the API Endpoint, with the authentication Header.

https://app.tpstreams.com/api/v1/<organization_id>/assets/<str:asset_id>/stop_live_stream/

This will stop the specified live stream

info

If the value of the parameter "transcode_recorded_video" is set to true, you will receive the video object in the webhook response.

Sample webhook response is as follows

{
"title": "Data science Live class",
"bytes": null,
"type": "livestream",
"video": {
"progress": 0,
"thumbnails": [],
"status": "Completed",
"playback_url": "https://d7pdowhru2wq4.cloudfront.net/transcoded/9328558d-e0a5-4093-b3b9-8f15ad1550d8/video.m3u8",
"dash_url": "https://d7pdowhru2wq4.cloudfront.net/transcoded/9328558d-e0a5-4093-b3b9-8f15ad1550d8/video.mpd",
"preview_thumbnail_url": null,
"format": "abr",
"resolutions": ["240p", "360p", "480p", "720p"],
"video_codec": "h264",
"audio_codec": "aac",
"enable_drm": true,
"tracks": [],
"inputs": [
{
"url": "https://static.testpress.in/Data_science_Live_class.mp4"
}
],
},
"id": "4PtERT9d9uK",
"live_stream": {
"rtmp_url": "rtmp://23.427.127.24/live",
"stream_key": "org-4xu8ay-live-4PtERT9d9uK-jKP4",
"status": "Completed",
"hls_url": "https://d28qihy7z761lk.cloudfront.net/live/4xu8ay/4PtERT9d9uK/video.m3u8",
"start": null,
"transcode_recorded_video": true,
"chat_embed_url":"https://app.tpstreams.com/live-chat/4PtERT9d9uK/"
},
"parent_id": null
}

WebHook Response

Upon a successful creation of live stream, to notify your application about things that happen asynchronously , Create a Web Hook.

After successfully registering the webhook, whenever the status of live stream changes, response will be sent to the webhook.

Sample webhook response for livestream is as follows

{
"title": "Data science Live class",
"bytes": null,
"type": "livestream",
"video": null,
"id": "4PtERT9d9uK",
"live_stream": {
"rtmp_url": "rtmp://23.427.127.24/live",
"stream_key": "org-4xu8ay-live-4PtERT9d9uK-jKP4",
"status": "Available",
"hls_url": "https://d28qihy7z761lk.cloudfront.net/live/4xu8ay/4PtERT9d9uK/video.m3u8",
"start": null,
"transcode_recorded_video": true,
"chat_embed_url":"https://app.tpstreams.com/live-chat/4PtERT9d9uK/"
},
"parent_id": null
}

After getting the rtmp_url and stream_key paste it in the obs stream settings Settings > Stream

OBS settings

- + \ No newline at end of file diff --git a/docs/server-api/organizations/index.html b/docs/server-api/organizations/index.html index 7c61650e..d0ec4a6e 100644 --- a/docs/server-api/organizations/index.html +++ b/docs/server-api/organizations/index.html @@ -4,13 +4,13 @@ Organization | Streams Docs - +

Organization

Get all the organizations that belong to the user

you need to send an HTTP GET request to the API Endpoint, with the authentication Header, to list all the organizations belonging to the user.

https://app.tpstreams.com/api/v1/organizations/
curl --request GET \
--url https://app.tpstreams.com/api/v1/organizations/ \
--header 'authorization: token 378ad87dc80534b75dcb674da1e7a0145b27461c936c4091c17546fdca6baac1' \
--header 'cache-control: no-cache'

Response


{
"count": 2,
"next": null,
"previous": null,
"results": [
{
"name": "Testpress",
"uuid": "6dnpyx"
},
{
"name": "Streams",
"uuid": "7coqzy"
}
]
}
- + \ No newline at end of file diff --git a/docs/server-api/webhooks/index.html b/docs/server-api/webhooks/index.html index da91963d..f024b35c 100644 --- a/docs/server-api/webhooks/index.html +++ b/docs/server-api/webhooks/index.html @@ -4,14 +4,14 @@ Web Hooks | Streams Docs - +

Web Hooks

Streams uses webhooks to notify your application about things that happen asynchronously, apart from the API request-response cycle. For example, you may want to update something on your end when a video asset status changes from queued to ready or errored. When these events happen, Streams will make a POST request to the address you give us and you can do whatever you need with it on your end.

Configure Webhook

Webhooks can be configured using a webhook endpoint URL and a secret token to ensure authenticity. Once the webhook is configured for a video source or different video sources, a notification will be sent for each event for the sources. Here, the parameter Secret Token is used to ensure in your code that the Webhook is coming from Streams.

Create a Webhook

To Create a webhook you need to send an HTTP POST request to the API Endpoint, with the Authentication Header.

https://app.tpstreams.com/api/v1/<organization_id>/webhooks/

Fields

NameTypeDescriptionRequired
urlstringURL to which asset data to be sent.True
secret_tokenstringsecret_token will be sent in x-streams-token.True

Sample request body

{
"url": "https://sample.beeceptor.com",
"secret_token": "abcdef",
}

For valid requests the API server returns a JSON:

{
"url": "https://sample.beeceptor.com",
"secret_token": "abcdef",
"id": "c4cf9c5f-0b60-4e5c-9db9-81321ffe31d5"
}

List all webhooks

To get all the webhooks, you need to send an HTTP GET request to the API Endpoint, with the Authentication Header.

Endpoint

https://app.tpstreams.com/api/v1/<organization_id>/webhooks/

Response

{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"url": "https://sample.beeceptor.com",
"secret_token": "abcdef",
"id": "c4cf9c5f-0b60-4e5c-9db9-81321ffe31d5"
}
]
}

Update a webhook

To update a webhook, you need to send an HTTP PUT request to the API Endpoint, with the Authentication Header.

Endpoint

https://app.tpstreams.com/api/v1/<organization_id>/webhooks/<webhook_id>/

Response

{
"url": "https://sample1.beeceptor.com",
"secret_token": "abcdef",
"id": "c4cf9c5f-0b60-4e5c-9db9-81321ffe31d5"
}

Delete a webhook

To delete a webhook, you need to send an HTTP PUT request to the API Endpoint, with the Authentication Header.

Endpoint

https://app.tpstreams.com/api/v1/<organization_id>/webhooks/<webhook_id>/

WebHook Response

Whenever the status of asset changes, response will be sent to the webhook. Sample webhook response is as follows

{
"id": "9328558d-e0a5-4093-b3b9-8f15ad1550d8", // asset id
"title": "Big Buck Bunny Video",
"bytes": null,
"type": "video",
"video": {
"progress": 0,
"thumbnails": [],
"status": "Completed",
"playback_url": "https://d7pdowhru2wq4.cloudfront.net/transcoded/9328558d-e0a5-4093-b3b9-8f15ad1550d8/video.m3u8",
"dash_url": "https://d7pdowhru2wq4.cloudfront.net/transcoded/9328558d-e0a5-4093-b3b9-8f15ad1550d8/video.mpd",
"preview_thumbnail_url": null,
"format": "abr",
"resolutions": ["240p", "360p", "480p", "720p"],
"video_codec": "h264",
"audio_codec": "aac",
"enable_drm": true,
"tracks": [],
"inputs": [
{
"url": "https://static.testpress.in/BigBuckBunny.mp4"
}
],
},
}
- + \ No newline at end of file diff --git a/docs/transcoding-service/transcode-a-video/index.html b/docs/transcoding-service/transcode-a-video/index.html index c2473c57..2321b922 100644 --- a/docs/transcoding-service/transcode-a-video/index.html +++ b/docs/transcoding-service/transcode-a-video/index.html @@ -4,13 +4,13 @@ Introduction | Streams Docs - +

Introduction

Welcome to the Transcoding as a Service documentation! This guide will help you understand how to use our transcoding service to convert videos into different resolutions. Transcoding is the process of converting video files from one format to another or to different resolutions to make them compatible with various devices and streaming platforms.

Trancode a video

To transcode a video, you need to make a POST request to the following API endpoint:

https://app.tpstreams.com/api/v1/<organization_id>/transcoding_jobs/

Replace <organization_id> with your organization's unique identifier.

Sample payload:

{
"input_url": "https://example.com/input-video.mp4",
"output_path": "s3://example-bucket/output-path/",
"resolutions": ["240p", "480p"]
}

Here's a breakdown of the fields in the payload:

NameDescription
input_urlThe URL of the input video file you want to transcode
output_pathThe S3 bucket path where the transcoded video files will be stored. Make sure to specify a unique path for each transcoding job
resolutionsAn array of resolutions you want to transcode the video into. You can specify multiple resolutions as needed. Available resoltions are 240p, 360p, 480p, 720p and 1080p

Response

Upon a successful request, you will receive a response like below with information about the transcoding job, including a unique job ID. You can use this job ID to monitor the progress and check the status of your transcoding job.

{
"id": "5KQfnXCg8Qh",
"resolutions": [
"240p",
"480p"
],
"video_duration": null,
"status": "Queued",
"input_url": "https://example.com/input-video.mp4",
"output_path": "s3://example-bucket/output-path/",
"start_time": null,
"end_time": null
}

Get notified on status change

We offer webhook integration to keep you informed about the status and progress of your transcoding jobs in real-time. With webhook integration, you can receive notifications as soon as your job status changes, making it easier to track and manage your video transcoding tasks.

To register a webhook for your organization, Please check webhook documentation.

Get Transcoding Job detail

To retrieve the details of a transcoding job, make a GET request to the following API endpoint:

https://app.tpstreams.com/api/v1/<organization_id>/transcoding_jobs/<job_id>/

Replace <organization_id> with your organization's unique identifier and <job_id> with the specific job ID you want to retrieve details for.

Sample Response

{
"id": "5KQfnXCg8Qh",
"resolutions": [
"240p",
"480p"
],
"video_duration": 120,
"status": "Completed",
"input_url": "https://example.com/input-video.mp4",
"output_path": "s3://example-bucket/output-path/",
"start_time": "2023-04-20T23:20:06.034924+12:00",
"end_time": "2023-04-20T23:40:06.034924+12:00"
}
- + \ No newline at end of file diff --git a/docs/video-embedding/aes-encryption/index.html b/docs/video-embedding/aes-encryption/index.html index d8abba0e..63439eba 100644 --- a/docs/video-embedding/aes-encryption/index.html +++ b/docs/video-embedding/aes-encryption/index.html @@ -4,7 +4,7 @@ AES Encryption | Streams Docs - + @@ -12,7 +12,7 @@

AES Encryption

Advanced Encryption Standard (AES) is a widely used symmetric encryption algorithm designed to secure data.

It employs a block cipher method, transforming data in fixed-size blocks, typically 128 bits. AES operates through a series of rounds involving substitution, permutation, and mixing of data elements, making it highly resistant to attacks.

It offers key lengths of 128, 192, or 256 bits for varying levels of security. AES encryption is widely adopted for its efficiency and robust protection, used in securing sensitive data during transmission and storage

Upload AES Encrypted video

To Upload a asset with AES Encryption you need to send an HTTP POST request to the API Endpoint, with the "content_protection_type" as "aes".

Sample request body

{
"title": "Big Buck Bunny Video",
"inputs": [
{
"url": "https://static.testpress.in/BigBuckBunny.mp4"
}
],
"resolutions": ["240p", "360p", "480p", "720p"],
"content_protection_type": "aes",
"folder": "32seYYHeNxE"
}

How to play AES Encrypted video

Generate a Signed Playback URL

To successfully access and play AES encrypted videos, it's essential to generate a signed playback URL specifically designed for each video.

To obtain it send an HTTP GET request to the API Endpoint, with the the query parameter 'expiry,' indicating the duration in seconds until the URL expires.

Endpoint

https://app.tpstreams.com/api/v1/<organization_id>/assets/<asset_id>/?expiry=100

The playback_url provided in the API response is the signed URL that you can use for secure video playback.

Response

{
"title": "sample.mp4",
"bytes": null,
"type": "video",
"video": {
....
....
"playback_url": "https://d384padtbeqfgy.cloudfront.net/transcoded_private/B66mmRm2TPF/video.m3u8?Expires=1692398327&Signature=OXqiVfCVAFrNoMq0hrpJ05YYY0XeyzA1H8kD6lv~~71v5PCdpf-9h1Qe~A0RFYoJuOq22j70juEFVJNjEr-WvVPvCvSRoYbRG6xEx5sr-541G~UkBXrcNXRHpb1988hQdG8NAh2pCV6o7bFOKsk3BBk8t6FRo-ZYs6xl46vFN8qH3FCNMhQLFmWqNpNo1vSPjmSSZlNrAplBkNq7MWxoNPxEFrzBgKusqrFZWLqOoXdzR8f9kb9VKkEQAPZL2tk71D6aN8toxwPV70esr8df78hkmAl3d4lChKZlrbWKd0tzew3RDPYZxicxfD1ZBx0th5PQfCltukkitQ0zPbE3TQ__&Key-Pair-Id=K2XWKDWM065EGO",
},

}

Handle AES-encrypted key request

The player sends a request to our endpoint, as indicated within the m3u8 file, to obtain the AES decryption key needed for video playback. However, the API endpoint mandates an access token for authorization.

To handle this, it's important to ensure that the access token is included in the request as a query parameter initiated by the player.

To generate access tokens send an HTTP GET request to the API Endpoint

Sample video.js code

<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Video.js HLS Example</title>
<link href="https://unpkg.com/video.js@7.21.4/dist/video-js.min.css" rel="stylesheet">
<script src="https://unpkg.com/video.js@7.21.4/dist/video.min.js"></script>
</head>
<body>
<video id="player" class="video-js vjs-big-play-centered vjs-default-skin" controls preload="auto" width="640"
height="360">
<source src="PLAYBACK_SIGNED_URL.m3u8" type="application/x-mpegURL">
</video>

<script>
var player = videojs('player', { html5: { hls: { cacheEncryptionKeys: true } } });

player.ready(function () {
player.hls.xhr.beforeRequest = (options) => {
if (options.uri.includes("aes_key")) {
options.uri += `?access_token=YOUR_ACCESS_TOKEN_HERE`;
return options;
}

return options;
};
});
</script>
</body>

</html>

Replace "PLAYBACK_SIGNED_URL.m3u8" with the actual playback_url of your encrypted video and "YOUR_ACCESS_TOKEN_HERE" with the provided access token.

- + \ No newline at end of file diff --git a/docs/video-embedding/authentication/index.html b/docs/video-embedding/authentication/index.html index 3d0683f4..4c185e38 100644 --- a/docs/video-embedding/authentication/index.html +++ b/docs/video-embedding/authentication/index.html @@ -4,13 +4,13 @@ Playback Authentication | Streams Docs - +

Playback Authentication

Access token generated using Streams API which is required to authorize video playback.

If the user has your video embed code he can embed your video onto any page on the internet if you don't have domain restrictions. even if you have, users can view the video by embedding your video on your home page or any other page that doesn't restrict users.

You can prevent the above scenario by generating an access token using API with time-to-live or set to expire after one usage on the back-end server and then sent to the website front-end and use generate access_token as part of the video embed code.

Obtaining an Access token

To generate the Access token you need to send an HTTP POST request to the API Endpoint, with the authentication Header and the optional Access token request Body.

https://app.tpstreams.com/api/v1/{{org_code}}/assets/{{asset_id}}/access_tokens/

Optional Fields

NameTypedescription
time_to_liveintegerBy default, the Access token validity is set to infinity. You can create shorter-lived URLs by passing the time_to_live parameter. This value is to be set in seconds
expires_after_first_usagebooleanPassing true will make the access token expire immediately after the first usage
annotationsjsonJSON contain all the information about the watermark. Please refer to this doc for details on watermarking.

For valid requests the API server returns a JSON:


{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"playback_url": "https://app.tpstreams.com/embed/dcek2m/3XqS4b4UKUm/?access_token=b1aa3af8-9c75-40e9-a051-4c129e84da82",
"expires_after_first_usage": false,
"code": "b1aa3af8-9c75-40e9-a051-4c129e84da82",
"status": "Active",
"valid_until": null,
"annotations": []
}
]
}

Other CRED operation APIs are documented here

- + \ No newline at end of file diff --git a/docs/video-embedding/getting-started/index.html b/docs/video-embedding/getting-started/index.html index 667795fc..f2032f90 100644 --- a/docs/video-embedding/getting-started/index.html +++ b/docs/video-embedding/getting-started/index.html @@ -4,7 +4,7 @@ Getting started | Streams Docs - + @@ -46,7 +46,7 @@ } }
Result
Loading...
- + \ No newline at end of file diff --git a/docs/video-embedding/javascript-sdk/introduction/index.html b/docs/video-embedding/javascript-sdk/introduction/index.html index 92b9a7b7..a225906f 100644 --- a/docs/video-embedding/javascript-sdk/introduction/index.html +++ b/docs/video-embedding/javascript-sdk/introduction/index.html @@ -4,13 +4,13 @@ About player SDK | Streams Docs - +

About player SDK

Our player SDK enables you to interact with embedded Streams players through the code on your web page. You can modify the default behavior of the player for features like looping, execute custom functions on particular playback events, and even set basic properties like the volume, and playback rate of the player.

The SDK, as a JavaScript library, is completely separate from the API. You connect to it differently, and it gives you a different range of options.

- + \ No newline at end of file diff --git a/docs/video-embedding/javascript-sdk/player-events/index.html b/docs/video-embedding/javascript-sdk/player-events/index.html index 5ee3871d..decd0838 100644 --- a/docs/video-embedding/javascript-sdk/player-events/index.html +++ b/docs/video-embedding/javascript-sdk/player-events/index.html @@ -4,13 +4,13 @@ Player Events | Streams Docs - +

Player Events

About Player events

You can listen for events in the player by attaching a callback using .on()

player.on('ended', function() {
// Executes when the video is ended
});

The events are equivalent to the HTML5 video events.

To remove a listener, call .off() with the callback function. If you pass an event name only, you remove all listeners for that event.

var onPlay = function() {

};

player.on('ended', onPlay);

// If later you decide that you don't need to listen for `ended`
player.off('ended', onPlay);

// Alternatively, call `off` with just the event name to remove all listeners
player.off('ended');

Events for playback controls

  • ended
  • error
  • loaded
  • pause
  • play
  • progress
  • seeked
  • timeupdate
  • volumechange
  • ratechange

ended

This event fires when playback reaches the end of a video.

info

When the player's loop behavior is enabled, the ended event doesn't fire.

loaded

This event fires when a new video is loaded in the player.

volume

This event fires when the volume in the player changes.

timeupdate

This event fires when the playback position of the video changes, generally every 250 ms during playback, but the interval can vary depending on the browser.

seeked

This event fires when the player seeks a specific time. A simultaneous timeupdate event also fires.

progress

This event fires while the video is loading. The event data indicates the amount of the video that has been buffered.

play

This event fires when the video plays.

pause

This event fires when the video is paused.

error

This event fires when the player experiences some sort of error. If a method call generated the error, the name of the method appears in the event data, along with the name of the error.

ratechange

This event fires when the playback rate of the video in the player changes.

- + \ No newline at end of file diff --git a/docs/video-embedding/javascript-sdk/player-methods/index.html b/docs/video-embedding/javascript-sdk/player-methods/index.html index 473bdd7c..027638ac 100644 --- a/docs/video-embedding/javascript-sdk/player-methods/index.html +++ b/docs/video-embedding/javascript-sdk/player-methods/index.html @@ -4,7 +4,7 @@ Player Methods | Streams Docs - + @@ -12,7 +12,7 @@

Player Methods

About player methods

You can call player methods by calling the corresponding function on the Player object. All player method executes only after the iframe is loaded, so no need to wait for the player to loaded to call the methods.

player.play();

All methods, except for on() and off(), return a Promise — a special JavaScript object that stands for the result of the operation, whether success or failure.

Promises for methods that return information resolve with the value of the property in question.

player.getLoop().then(function(loop) {
// Whether the player is set to loop
});

Get the playback position of a video

This method gets the current playback position of a video, measured in seconds.

Function

getCurrentTime()

Returns

Promise <number>

Example

player.getCurrentTime().then(function(seconds) {
// `seconds` indicates the current playback position of the video
});

Get the loop state of a player

This method gets the loop state of a player, where true indicates that the video restarts once it reaches the end of playback.

Function

getLoop()

Returns

Promise <boolean>

Example

player.getLoop().then(function(loop) {
// `loop` indicates whether the loop behavior is active
});

Get the pause state of a player

This method gets the pause state of the current player, where true indicates that playback is paused.

Function

getPaused()

Returns

Promise <boolean>

Example

player.getPaused().then(function(paused) {
// `paused` indicates whether the player is paused
});

Get the ended state of a video

This method gets the ended state of the video, where true indicates that the video has ended. The video has ended if its current playback position is exactly equal to its duration.

Function

getEnded()

Returns

Promise <boolean>

Example

player.getEnded().then(function(ended) {
// `ended` indicates whether the video has ended
});

Get the playback rate of a player

This method gets the playback rate of a player on a scale from 0.5 to 2, where 0.5 is half speed and 2 is double speed.

Function

getPlaybackRate()

Returns

Promise <number>

Example

player.getPlaybackRate().then(function(playbackRate) {
// `playbackRate` indicates the numeric value of the current playback rate
});

Get the volume level of a player

This method gets the volume level of a player on a scale of 0 to 1.

info

Most mobile devices don't support a volume level independent of the system volume. In these cases, this method always returns 1.

Function

getVolume()

Returns

Promise <number>

Example

player.getVolume().then(function(volume) {
// `volume` indicates the volume level of the player
});

Get the video duration

This method gets the current video duration in seconds.

Function

getDuration()

Returns

Promise <number>

Example

player.getDuration().then(function(duration) {
// duration 596.4630000000002
});

Get user watched time ranges

This methods returns the list of time ranges that user watched in a video.

Function

played()

Returns

Promise <Array>

Example

player.played().then(function(ranges) {
// ranges => [[0, 120.084666], [155.292928, 161.054032], ...]
});

Pause a video

This method pauses the playback of a video.

Function

pause()

Returns

Promise <void>

Example

player.pause().then(function() {
// The video is paused
}).catch(function(error) {
// Some other error occurred
});

Play a video

This method plays the playback of a video.

Function

play()

Returns

Promise <void>

Example

player.play().then(function() {
// The video is paused
}).catch(function(error) {
// Some other error occurred
});

Set the playback position of a video

This method sets the current playback position in seconds. The player attempts to seek to as close to the specified time as possible. The exact time comes back as the fulfilled value of the promise.

If playback hasn't started yet, using this method starts playback.
If playback has already started, using this method doesn't affect the play state.

info

If the player is paused, it remains paused. If the player is playing, it buffers the video from the new position and then resumes playing.

Function

setCurrentTime(seconds)

Parameters

ParameterData typeRequired?Description
secondsNumberYesThe playback position in seconds.

Returns

Promise <number, (RangeError | Error)>

Errors

ErrorDescription
RangeErrorThe time is less than 0 or greater than the video's duration.
ErrorSome other error occurred.

Example

player.setCurrentTime(30.456).then(function(seconds) {
// `seconds` indicates the actual time that the player seeks to
}).catch(function(error) {
switch (error.name) {
case 'RangeError':
// The time is less than 0 or greater than the video's duration
break;
default:
// Some other error occurred
break;
}
});

Set the autoplay state of a player or browser

This method enables or disables autoplay in a player or browser, where true indicates that autoplay is enabled. Under autopause, whenever a new video loads in the browser window, the video begins in a played state. By default autoplay was disabled.

info

The autopause feature has no effect if you've disabled cookies in your browser, either through browser settings or with an extension or plugin.

Function

setAutoPlay({autoplay})

Parameters

ParameterData typeRequired?Description
autopauseBooleanYesThe autopause state to set.

Returns

Promise <boolean, (UnsupportedError | Error)>

Errors

ErrorDescription
UnsupportedErrorAutopause isn't supported by the current player or browser.
ErrorSome other error occurred.

Example

player.setAutoPlay(false).then(function(autopause) {
// Autoplay is disabled
}).catch(function(error) {
// Handle errors
});

Set the loop state of a player

This method sets the loop state of the player. When the loop state is true, playback resumes at the beginning of the video immediately after the video ends.

Function

setLoop(loop)

Parameters

ParameterData typeRequired?Description
loopBooleanYesWhether the player loops video playback.

Returns

Promise <boolean>

Example

player.setLoop(true).then(function(loop) {
// The loop behavior is enabled
});

Set the playback rate of a player

This method sets the playback rate of the player on a scale from 0.5 to 2, where 0.5 is half speed and 2 is double speed. When you set the playback rate through the API, the specified value isn't synchronized to other players or stored as the viewer's preference.

Function

setPlaybackRate(playbackRate)

Parameters

ParameterData typeRequired?Description
playbackRateNumberYesThe playback rate of the player from 0.5 to 2.

Returns

Promise <number, (RangeError | Error)>**

Errors

ErrorDescription
RangeErrorThe playback rate is less than 0.5 or greater than 2.
ErrorSome other error occurred.

Example

player.setPlaybackRate(0.5).then(function(playbackRate) {
// The playback rate is set
}).catch(function(error) {
switch (error.name) {
case 'RangeError':
// The playback rate is less than 0.5 or greater than 2
break;
default:
// Some other error occurred
break;
}
});

Set the volume level of a player

This method sets the volume level of the player on a scale from 0 to 1. When you set the volume through the API, the specified value isn't synchronized to other players or stored as the viewer's preference.

Function

setVolume(volume)

Parameters

ParameterData typeRequired?Description
volumeNumberYesThe volume level of the player from 0 to 1.

Returns

Promise <number, (RangeError | Error)>

Errors

ErrorDescription
RangeErrorThe volume is less than 0 or greater than 1.
ErrorSome other error occurred.

Example

player.setVolume(0.5).then(function(volume) {
// The volume is set
}).catch(function(error) {
switch (error.name) {
case 'RangeError':
// The volume is less than 0 or greater than 1
break;
default:
// Some other errors occurred
break;
}
});

Apply watermark to the video

This method applies watermark to the video. Please refer to this doc for more details on watermarking.

Function

applyWatermark()

Parameters

ParameterData typeRequired?
annotationsjsonYes

Returns

Promise <void>

Example

const annotations = [
{
"type":"dynamic",
"text":"Dinesh",
"opacity":"0.8",
"color":"#FF0000",
"size":"5",
"interval":5000,
"skip": 2000
}
]
player.applyWatermark(annotations).then(function() {
// The watermark is applied
})
- + \ No newline at end of file diff --git a/docs/video-embedding/javascript-sdk/plugins/markers/index.html b/docs/video-embedding/javascript-sdk/plugins/markers/index.html index 01875098..28279602 100644 --- a/docs/video-embedding/javascript-sdk/plugins/markers/index.html +++ b/docs/video-embedding/javascript-sdk/plugins/markers/index.html @@ -4,13 +4,13 @@ Markers | Streams Docs - +

Markers

Enable plugin

You can enable a plugin by passing query param plugins with value "markers to src URL"

Initialize markers

You can intialize markers through Player SDK method call setMarkers

Arguments

NameTypedescription
markerDisplayObjectThe general css styling that would be applied to all the markers created by the plugin. The default is only concerned with width, border-radius, and background-color, but any other css rules would be applied too (think of it as jQuery's css function).
breakOverlayObjectOptions for the break overlays at each marker. Available fields => display, displayTime, style

You can read more about available arguments here

Events

Namedescription
onMarkerReachedThis callback function is triggered whenever playback reaches the time interval from a marker. The interval is specified in the breakOverlay.displayTime . This can be used to trigger certain actions at each marker, depending on your use case. Again, this function is given a marker instance. In 0.6.0, the function also takes in a second parameter index.
onMarkerClickThis callback function is triggered when clicking on the markers. The default behavior for clicking on the marker is seeking to that point in the video. However, if onMarkerClick returns false, the default behavior will be prevented.

Methods

Remove markers

You can remove the particular markers by passing its indices to removeMarkers function.

player.removeMarkers([1,2,4]);

Remove All markers

player.removeAllMarkers([1,2,4]);

Sample code

<!DOCTYPE html>
<html>
<body>

<div style="padding-top:56.25%;position:relative;"><iframe id="video_player" src="https://app.tpstreams.com/embed/edee9b/5b0c2695-65ab-4695-b1a5-e124c6782942/?access_token=070ca6bf-b9bf-4c3e-b039-808d7edaebda&plugins=markers" style="border:0;max-width:100%;position:absolute;top:0;left:0;height:100%;width:100%;" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope picture-in-picture" allowfullscreen="" frameborder="0"></iframe></div>
<script src="https://static.testpress.in/static/js/player.js"></script>
<script>
var player = new Testpress.Player(document.getElementById("video_player"));
player.loaded().then(()=>{
player.setMarkers({
markerStyle: {
'width': '7px',
'border-radius': '30%',
'background-color': 'yellow'
},
markers: [{
time: 60,
text: "marker",
},
{
time: 120,
text: "marker2",
},
{
time: 180,
text: "marker3",
}
]
});

})

player.on("onMarkerReached", (marker, index)=>{
console.log("onMarkerReached", marker, index)
player.removeMarkers([index])
})

player.on("onMarkerClick", (marker)=>{
console.log("onMarkerClick", marker)
})

</script>
</body>
</html>

Output

Domain restriction form

- + \ No newline at end of file diff --git a/docs/video-embedding/javascript-sdk/using-player-sdk/index.html b/docs/video-embedding/javascript-sdk/using-player-sdk/index.html index d5a5c741..4938f131 100644 --- a/docs/video-embedding/javascript-sdk/using-player-sdk/index.html +++ b/docs/video-embedding/javascript-sdk/using-player-sdk/index.html @@ -4,13 +4,13 @@ Using Player SDK | Streams Docs - +

Using Player SDK

The iframe embed lets you embed your Streams videos and control the player using Javascript. You have access to the essential methods and properties of the players. There are events that you can listen for and execute custom actions in your web application.

Adding the script

Add the following script to the html of your web page. This loads the interface that are used to establish communication with the video player. If this script is loaded on-demand later, make sure to wait for the load to complete before calling subsequent methods on the object.

<script src="https://static.testpress.in/static/js/player.js"></script>

Get a reference to the iframe

Note: Assuming the API script (above) is already loaded,

To begin communicating with the player, get a reference to the iframe element. This can be using DOM APIs such as querySelector().

const iframe = document.querySelector("iframe");

Establish communication with the iframe

<html>
<head>
<title>page_title</title>
</head>
<body>
<iframe width='560' height='315' src='https://lms.testpress.in/embed/cnwKtQwNmbG' title='DDE video 12' frameborder='0' allow='accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture' allowfullscreen></iframe>
<script src="https://static.testpress.in/static/js/player.js"></script>
<script>
var iframe = document.querySelector('iframe');
var player = new Testpress.Player(iframe);

player.loaded().then(()=>{
console.log('Player is ready now')
});


player.on('play', function() {
console.log('Played the video')
});


player.setCurrentTime(30).then(()=>{
console.log('Current watch time updated')
});
</script>

</body>
</html>


What's next

It's time to start controlling some videos. We've compiled a comprehensive reference of methods and events to make your dreams of absolute power a reality.

If we've confused you going forward, contact us. We tend to get it right the second time.

- + \ No newline at end of file diff --git a/docs/video-embedding/watermarking/index.html b/docs/video-embedding/watermarking/index.html index 593ba84a..79d64837 100644 --- a/docs/video-embedding/watermarking/index.html +++ b/docs/video-embedding/watermarking/index.html @@ -4,13 +4,13 @@ Watermark Videos | Streams Docs - +

Watermark Videos

Videos hosted through Streams cannot be downloaded. There does however remain the risk of piracy from screen capture. Add text to videos with our dynamic watermark feature that effectively prevents users from pirating video content using screen capture, and goes a long way towards helping users protect their premium content.

The dynamic watermark can be customized for movement, color, size and transparency.

Create Watermark Code

Here is a sample JSON string that adds a moving (dynamic) watermark and a static watermark.

{
"annotations":[
{
"type":"static",
"text":"Testpress",
"x":10,
"y":10,
"opacity":"0.5",
"color":"#FFF",
"size":6
},
{
"type":"dynamic",
"text":"hari",
"opacity":"0.5",
"color":"#FF0000",
"size":6,
"interval":5000,
"skip":2000
}
]
}

Technically, this is an array of JSON objects, where each object describe a single annotation item.

Each of these items will be described by its parameters. Every item requires a type parameter which defines the type of watermark by default its value was static. The type of watermark can be either a moving text or a static text. The rest of the parameters depends on the type.

Following is a short description of how each parameter affects the display of text.

Static text

The following code will display a static watermark code, placed at 10px distance from the left border of the video and 50px from top border, displaying text Testpress . The text color will be white (#fff), opacity is 0.5, and font-size is 6.

[{
"type": "static",
"text": "Testpress",
"x": 10",
"y": 10,
"opacity": "0.5",
"color": "#FFF",
"size": "6"
}]

Moving text

The following code will display a dynamic watermark code, displaying text hari. The text color will be red (#ff0000), opacity is 0.8, and font-size is 6. The watermark is configured to update position every 5 seconds (5000ms).

[{
'type': 'dynamic',
'text': 'hari',
'opacity': '0.8',
'color': '#FF0000',
'size': '6',
'interval': 5000,
'skip': 2000,
}]

Type of text

Set type parameter as dynamic for Dynamic watermark and static for Static watermark

'type':'dynamic',

Set the text to be shown

'text" : 'testpress',

Specify text opacity

This is the opacity of the text. For full opacity keep value 1.

'opacity':'0.8',

Specify text color

This is the hex value of the watermark text color.

'color':'#FF0000',

Specify the font size

This is the font size

'size':6,

Specify the interval over which watermark changes position

The value is the interval in milliseconds when the text changes position

'interval':5000,

Skip feature for watermark

It is possible to have watermark skip for some time between two overlays. Here is a sample code for it –

'skip':2000

Apply Watermark

Now you just need pass the watermark code that you've created to the player to apply on the video. There are two ways to do that

- + \ No newline at end of file diff --git a/index.html b/index.html index ef961f2e..25237f4d 100644 --- a/index.html +++ b/index.html @@ -4,13 +4,13 @@ Hello from Streams Docs | Streams Docs - +

Streams Docs

Video DRM Encryption

No downloader, plugin or hack can download the videos streamed through Streams.

Dynamic Watermarking

Total Screen Capture Block in Mobile Apps. Discourage screen capture in websites with user based watermark like IP address, user id, email id, phone no. etc.

Upload & Embed on Your Site Or App

Embed player with subtitles, multiple qualities & speed change options. Option for the viewer to download securely in mobile app and play offline.

- + \ No newline at end of file diff --git a/markdown-page/index.html b/markdown-page/index.html index c8cc5871..61620d1f 100644 --- a/markdown-page/index.html +++ b/markdown-page/index.html @@ -4,13 +4,13 @@ Markdown page example | Streams Docs - +

Markdown page example

You don't need React to write simple standalone pages.

- + \ No newline at end of file