@tivio/sdk-react 9.3.1 → 9.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +327 -105
- package/README.md.bak +327 -105
- package/dist/index.d.ts +92 -3
- package/dist/index.js +1 -1
- package/dist/sdk-react.d.ts +103 -3
- package/package.json +2 -2
package/README.md
CHANGED
@@ -52,6 +52,17 @@ await setUser('userId', { token: 'xxx'})
|
|
52
52
|
await setUser(null)
|
53
53
|
```
|
54
54
|
|
55
|
+
## Single Sign-On (SSO) across subdomains
|
56
|
+
If you want to enable Single Sign-On (SSO) for all subdomains under the same parent domain, you can specify the customTokenCookiesDomain in the configuration object.
|
57
|
+
``` javascript
|
58
|
+
import type { Config } from '@tivio/sdk-react'
|
59
|
+
|
60
|
+
const config: Config = {
|
61
|
+
// ... other required tivio config properties
|
62
|
+
customTokenCookiesDomain: 'example.com' // allows SSO across example.com, app.example.com, admin.example.com, etc.
|
63
|
+
};
|
64
|
+
```
|
65
|
+
|
55
66
|
### Create user with email and password
|
56
67
|
|
57
68
|
Returns user's firebase uid or null if error occurs
|
@@ -302,7 +313,7 @@ watchHistory.forEach(watchPosition => {
|
|
302
313
|
|
303
314
|
Simply call addToFavorites or removeFromFavorites on the Video or Tag.
|
304
315
|
```typescript
|
305
|
-
const video = await tivio.getVideoById('videoId')
|
316
|
+
const video = await tivio.getVideoById('videoId')
|
306
317
|
await video.addToFavorites()
|
307
318
|
await video.removeFromFavorites()
|
308
319
|
|
@@ -315,7 +326,7 @@ const favorites = await tivio.getUser()?.favorites
|
|
315
326
|
favorites[0]?.removeFromFavorites()
|
316
327
|
```
|
317
328
|
|
318
|
-
>
|
329
|
+
> ℹ️ **_Note:_** When user saves favorite without profileId, it will only be shown if the app doesn't have any active user profile.
|
319
330
|
|
320
331
|
### Get screen by ID
|
321
332
|
|
@@ -582,10 +593,64 @@ The VideoController returned by `renderWebPlayer` provides the following methods
|
|
582
593
|
|
583
594
|
The Tivio player supports different types of sources:
|
584
595
|
|
596
|
+
**PathSourceParams** - Path-based sources with ad configuration
|
597
|
+
- Used for playing Tivio-hosted videos and TV channels with custom VAST ad configurations
|
598
|
+
- Supports both `videos/ID` and `tvChannels/ID` paths
|
599
|
+
- Includes `staticAdsConfig` for custom VAST ad insertion
|
600
|
+
- Example usage:
|
601
|
+
```typescript
|
602
|
+
const sourceWithAds = {
|
603
|
+
path: 'videos/123', // or 'tvChannels/456'
|
604
|
+
staticAdsConfig: [
|
605
|
+
{
|
606
|
+
type: 'preroll',
|
607
|
+
url: 'https://example.com/vast-preroll-ad.xml',
|
608
|
+
},
|
609
|
+
{
|
610
|
+
type: 'midroll',
|
611
|
+
from: 30000, // 30 seconds
|
612
|
+
url: 'https://example.com/vast-midroll-ad.xml',
|
613
|
+
},
|
614
|
+
{
|
615
|
+
type: 'postroll',
|
616
|
+
url: 'https://example.com/vast-postroll-ad.xml',
|
617
|
+
},
|
618
|
+
],
|
619
|
+
}
|
620
|
+
```
|
621
|
+
|
622
|
+
**VOD_TIVIO** - Tivio-hosted video-on-demand content
|
623
|
+
- Used for playing videos that are hosted within Tivio's infrastructure
|
624
|
+
- Example usage:
|
625
|
+
```typescript
|
626
|
+
const vodSource = {
|
627
|
+
type: SourceType.VOD_TIVIO,
|
628
|
+
videoPath: 'videos/123', // Video path
|
629
|
+
sourcePlayMode: SourcePlayMode.ON_DEMAND,
|
630
|
+
name: 'Tivio Video',
|
631
|
+
autoplay: false,
|
632
|
+
continuePositionMs: 10000, // Start at 10 seconds (optional)
|
633
|
+
}
|
634
|
+
```
|
635
|
+
|
636
|
+
**CHANNEL** - TV channel content (both classic and virtual channels)
|
637
|
+
- Used for playing live TV channels
|
638
|
+
- Example usage:
|
639
|
+
```typescript
|
640
|
+
const channelSource = {
|
641
|
+
type: SourceType.CHANNEL,
|
642
|
+
path: 'tvChannels/456', // TV channel path
|
643
|
+
sourcePlayMode: SourcePlayMode.LIVE,
|
644
|
+
name: 'TV Channel',
|
645
|
+
autoplay: true,
|
646
|
+
}
|
647
|
+
```
|
648
|
+
|
585
649
|
**VOD_EXTERNAL** - External video-on-demand content from third-party URLs
|
586
650
|
- Used for playing videos that are hosted outside of Tivio's infrastructure
|
587
651
|
- Supports various streaming protocols (HLS, DASH, MP4)
|
588
|
-
-
|
652
|
+
- Optionally, you can include `staticAdsConfig` for custom ad insertion
|
653
|
+
- Example usage (single url):
|
589
654
|
```typescript
|
590
655
|
const externalSource = {
|
591
656
|
type: SourceType.VOD_EXTERNAL,
|
@@ -595,9 +660,137 @@ const externalSource = {
|
|
595
660
|
name: 'External Video',
|
596
661
|
autoplay: false,
|
597
662
|
continuePositionMs: 10000, // Start at 10 seconds (optional)
|
663
|
+
staticAdsConfig: [
|
664
|
+
{
|
665
|
+
type: 'preroll',
|
666
|
+
url: 'https://example.com/preroll-ad.xml',
|
667
|
+
},
|
668
|
+
{
|
669
|
+
type: 'midroll',
|
670
|
+
from: 20000, // 20 seconds
|
671
|
+
url: 'https://example.com/midroll-ad.xml',
|
672
|
+
},
|
673
|
+
],
|
598
674
|
}
|
599
675
|
```
|
600
676
|
|
677
|
+
**Path-Based Sources**
|
678
|
+
You can also use simple path strings for both video and TV channel sources:
|
679
|
+
```typescript
|
680
|
+
// Video path
|
681
|
+
videoController.setSource('videos/123')
|
682
|
+
|
683
|
+
// TV channel path
|
684
|
+
videoController.setSource('tvChannels/456')
|
685
|
+
```
|
686
|
+
|
687
|
+
#### Static Ads Configuration
|
688
|
+
|
689
|
+
> ℹ️ **_Note:_** To enable ad functionality, you must configure the IMA ad service in your Tivio configuration:
|
690
|
+
> ```typescript
|
691
|
+
> import { AD_SERVICE_PROXY_NAME } from '@tivio/sdk-react'
|
692
|
+
>
|
693
|
+
> const config = {
|
694
|
+
> // ... other config properties
|
695
|
+
> player: {
|
696
|
+
> adService: {
|
697
|
+
> name: AD_SERVICE_PROXY_NAME.IMA,
|
698
|
+
> },
|
699
|
+
> },
|
700
|
+
> }
|
701
|
+
> ```
|
702
|
+
|
703
|
+
The `staticAdsConfig` property lets you specify custom ad insertion points within your content.
|
704
|
+
If multiple ads are set for the same entry point, they will be played one after another in sequence. For example, if you have two preroll ads, the first will play, followed by the second. Similarly, midroll ads that share the same `from` time will be grouped and played sequentially.
|
705
|
+
|
706
|
+
It supports the following ad types:
|
707
|
+
|
708
|
+
**Preroll Ads** - Play before the main content starts
|
709
|
+
```typescript
|
710
|
+
{
|
711
|
+
type: 'preroll',
|
712
|
+
url: 'https://example.com/preroll-ad.xml',
|
713
|
+
}
|
714
|
+
```
|
715
|
+
|
716
|
+
**Midroll Ads** - Play during the main content at specified time
|
717
|
+
```typescript
|
718
|
+
{
|
719
|
+
type: 'midroll',
|
720
|
+
from: 30000, // Time in milliseconds (30 seconds)
|
721
|
+
url: 'https://example.com/midroll-ad.xml',
|
722
|
+
}
|
723
|
+
```
|
724
|
+
|
725
|
+
**Postroll Ads** - Play after the main content ends
|
726
|
+
```typescript
|
727
|
+
{
|
728
|
+
type: 'postroll',
|
729
|
+
url: 'https://example.com/postroll-ad.xml',
|
730
|
+
}
|
731
|
+
```
|
732
|
+
|
733
|
+
**Complete Example:**
|
734
|
+
```typescript
|
735
|
+
const sourceWithAds = {
|
736
|
+
path: 'videos/123',
|
737
|
+
name: 'Video with Multiple Ad Types',
|
738
|
+
staticAdsConfig: [
|
739
|
+
// multiple preroll ads
|
740
|
+
{
|
741
|
+
type: 'preroll',
|
742
|
+
url: 'https://vasterix.joj.sk/api/v1/creative?id=0c5d96fd-2ab9-4207-a325-4607437965e3&vast=4.0',
|
743
|
+
},
|
744
|
+
{
|
745
|
+
type: 'preroll',
|
746
|
+
url: 'https://example.com/preroll-ad.xml',
|
747
|
+
},
|
748
|
+
// multiple midroll ads (with same from time)
|
749
|
+
{
|
750
|
+
type: 'midroll',
|
751
|
+
from: 30000, // 30 seconds
|
752
|
+
url: 'https://example.com/midroll-ad-1.xml',
|
753
|
+
},
|
754
|
+
{
|
755
|
+
type: 'midroll',
|
756
|
+
from: 30000, // 30 seconds
|
757
|
+
url: 'https://example.com/midroll-ad-2.xml',
|
758
|
+
},
|
759
|
+
// one midroll ad with different from time
|
760
|
+
{
|
761
|
+
type: 'midroll',
|
762
|
+
from: 60000, // 1 minute
|
763
|
+
url: 'https://example.com/midroll-ad-2.xml',
|
764
|
+
},
|
765
|
+
// postroll ad
|
766
|
+
{
|
767
|
+
type: 'postroll',
|
768
|
+
url: 'https://example.com/postroll-ad.xml',
|
769
|
+
},
|
770
|
+
],
|
771
|
+
}
|
772
|
+
```
|
773
|
+
- It is also possible to set multiple urls for external source type, e.g. when you want to use both DASH and HLS formats. Player then automatically will pick most suitable format to play depending on device capabilities.
|
774
|
+
- Example usage (multiple urls):
|
775
|
+
```typescript
|
776
|
+
const externalSource = {
|
777
|
+
type: SourceType.VOD_EXTERNAL,
|
778
|
+
urls: ['https://example.com/video.m3u8', 'https://example.com/video.mpd'],
|
779
|
+
sourcePlayMode: SourcePlayMode.ON_DEMAND,
|
780
|
+
}
|
781
|
+
```
|
782
|
+
|
783
|
+
**VOD_TIVIO** - Internal source type for playing content managed by Tivio
|
784
|
+
- Used for playing videos and tv channels managed by Tivio infrastructure, e.g. everything that is uploaded through Tivio Admin application
|
785
|
+
- For convenience, it is recommended to use shortcut format and pass the source as string in `${'videos' | 'tvChannels'}/{id}` format
|
786
|
+
- Ids of corresponding videos and tv channel could be found in Tivio admin application
|
787
|
+
- Example usage:
|
788
|
+
```typescript
|
789
|
+
const tivioVideoSource = 'videos/2BzH4xsTXW8vqYKJegXj'
|
790
|
+
const tivioTvChannelSource = 'tvChannels/Ct4UcK6ozX3VfxaL5yP5'
|
791
|
+
```
|
792
|
+
- Otherwise, it is also possible to pass internal tivio source as an object with `type: SourceType.VOD_TIVIO` and additional parameters, similarly to external source type.
|
793
|
+
|
601
794
|
#### Source Play Modes
|
602
795
|
|
603
796
|
The `sourcePlayMode` property determines how the content is played:
|
@@ -614,6 +807,23 @@ The `setSource` method allows you to dynamically change what's playing:
|
|
614
807
|
// Change to a different video
|
615
808
|
videoController.setSource('videos/newVideoId')
|
616
809
|
|
810
|
+
// Change to a video with custom ads
|
811
|
+
videoController.setSource({
|
812
|
+
path: 'videos/newVideoId',
|
813
|
+
name: 'Video with Ads',
|
814
|
+
staticAdsConfig: [
|
815
|
+
{
|
816
|
+
type: 'preroll',
|
817
|
+
url: 'https://example.com/preroll-ad.xml',
|
818
|
+
},
|
819
|
+
{
|
820
|
+
type: 'midroll',
|
821
|
+
from: 30000,
|
822
|
+
url: 'https://example.com/midroll-ad.xml',
|
823
|
+
},
|
824
|
+
],
|
825
|
+
})
|
826
|
+
|
617
827
|
// Change to an external video
|
618
828
|
videoController.setSource({
|
619
829
|
type: SourceType.VOD_EXTERNAL,
|
@@ -625,6 +835,18 @@ videoController.setSource({
|
|
625
835
|
// Change to a TV channel
|
626
836
|
videoController.setSource('tvChannels/channelId')
|
627
837
|
|
838
|
+
// Change to a TV channel with custom ads
|
839
|
+
videoController.setSource({
|
840
|
+
path: 'tvChannels/channelId',
|
841
|
+
name: 'TV Channel with Ads',
|
842
|
+
staticAdsConfig: [
|
843
|
+
{
|
844
|
+
type: 'preroll',
|
845
|
+
url: 'https://example.com/tv-preroll-ad.xml',
|
846
|
+
},
|
847
|
+
],
|
848
|
+
})
|
849
|
+
|
628
850
|
// Stop playback
|
629
851
|
videoController.setSource(null)
|
630
852
|
```
|
@@ -645,6 +867,107 @@ The `setSource` method is particularly useful for:
|
|
645
867
|
|
646
868
|
The VideoController emits various events that you can listen to:
|
647
869
|
|
870
|
+
#### Ad events
|
871
|
+
|
872
|
+
```typescript
|
873
|
+
videoController.addEventListener('ad_started', (adMetadata: AdMetadata | null) => {
|
874
|
+
if (!adMetadata) {
|
875
|
+
console.log('Ad started playing (no metadata available)')
|
876
|
+
return
|
877
|
+
}
|
878
|
+
|
879
|
+
console.log('Ad started playing', adMetadata)
|
880
|
+
|
881
|
+
if ('customAdMetadata' in adMetadata && adMetadata.customAdMetadata) {
|
882
|
+
console.log('Ad custom metadata:', adMetadata.customAdMetadata)
|
883
|
+
// customAdMetadata contains VAST trafficking parameters (from VAST AdParameters tag)
|
884
|
+
}
|
885
|
+
|
886
|
+
// Access CTA element for rendering custom call-to-action buttons
|
887
|
+
const { ctaElement } = adMetadata
|
888
|
+
if (ctaElement) {
|
889
|
+
console.log('CTA element available for rendering custom buttons', ctaElement)
|
890
|
+
|
891
|
+
const { customAdMetadata } = adMetadata
|
892
|
+
if (!customAdMetadata) {
|
893
|
+
console.log('No custom ad metadata available')
|
894
|
+
return
|
895
|
+
}
|
896
|
+
|
897
|
+
const { extensions } = customAdMetadata
|
898
|
+
if (!extensions) {
|
899
|
+
console.log('No extensions available')
|
900
|
+
return
|
901
|
+
}
|
902
|
+
|
903
|
+
const { parameters } = extensions[0]
|
904
|
+
if (!parameters) {
|
905
|
+
console.log('No parameters available')
|
906
|
+
return
|
907
|
+
}
|
908
|
+
|
909
|
+
const metadataParameters = parameters as {
|
910
|
+
main_title?: string
|
911
|
+
subtitle?: string
|
912
|
+
image?: string
|
913
|
+
button_text: string
|
914
|
+
url: string
|
915
|
+
}
|
916
|
+
|
917
|
+
const buttonText = metadataParameters.button_text as string | undefined
|
918
|
+
|
919
|
+
if (!buttonText) {
|
920
|
+
console.log('No button text available')
|
921
|
+
return
|
922
|
+
}
|
923
|
+
|
924
|
+
// Example: Create a custom CTA button using React portal
|
925
|
+
const CTAButton = () => (
|
926
|
+
<div style={{
|
927
|
+
position: 'absolute',
|
928
|
+
bottom: '20px',
|
929
|
+
right: '20px',
|
930
|
+
backgroundColor: 'rgba(0, 0, 0, 0.8)',
|
931
|
+
color: 'white',
|
932
|
+
padding: '12px 24px',
|
933
|
+
borderRadius: '6px',
|
934
|
+
cursor: 'pointer',
|
935
|
+
fontSize: '16px',
|
936
|
+
fontWeight: 'bold',
|
937
|
+
pointerEvents: 'auto',
|
938
|
+
}}>
|
939
|
+
Learn More
|
940
|
+
</div>
|
941
|
+
)
|
942
|
+
|
943
|
+
// Render the CTA button using React portal
|
944
|
+
const root = ReactDOM.createRoot(ctaElement)
|
945
|
+
root.render(<CTAButton />)
|
946
|
+
}
|
947
|
+
|
948
|
+
// adMetadata contains information like:
|
949
|
+
// - ctaElement?: HTMLElement (for rendering custom CTA buttons)
|
950
|
+
// - customAdMetadata?: Record<string, unknown> (for IMA ads with rich metadata)
|
951
|
+
// - type: 'ad'
|
952
|
+
// - subType: 'inserted' | 'original'
|
953
|
+
// - secondsToEnd: number
|
954
|
+
// - secondsToSkippable: number | null
|
955
|
+
// - canTriggerSkip: boolean
|
956
|
+
// - isSkippable: boolean
|
957
|
+
// - order: number | null
|
958
|
+
// - totalCount: number | null
|
959
|
+
// - skip: () => void
|
960
|
+
// Update UI, show ad overlay, etc.
|
961
|
+
})
|
962
|
+
|
963
|
+
videoController.addEventListener('ad_ended', () => {
|
964
|
+
console.log('Ad finished playing')
|
965
|
+
})
|
966
|
+
```
|
967
|
+
|
968
|
+
> ℹ️ **_Note:_** The CTA overlay element is visible in the WebPlayer only while an ad is playing and is automatically cleaned up on source changes.
|
969
|
+
|
970
|
+
#### Video state changes
|
648
971
|
```typescript
|
649
972
|
// Video state changes
|
650
973
|
videoController.addEventListener('statechange', (state) => {
|
@@ -717,105 +1040,4 @@ The `WebPlayerProps` interface defines the properties that can be passed to the
|
|
717
1040
|
|
718
1041
|
### Visual Properties
|
719
1042
|
|
720
|
-
- **`showMarkers
|
721
|
-
- **`markerColor`** (optional): Color for video markers (CSS color value)
|
722
|
-
- **`showTvStreamType`** (optional): Whether to show TV stream type indicator
|
723
|
-
- **`showCookiesSettings`** (optional): Whether to show cookies settings
|
724
|
-
- **`showOsd`** (optional, default: `true`): Whether to show the On-Screen Display (OSD)
|
725
|
-
- **`showBufferingSpinner`** (optional, default: `true`): Whether to show buffering spinner
|
726
|
-
|
727
|
-
### Audio Properties
|
728
|
-
|
729
|
-
- **`isMutedByDefault`** (optional): If `true`, the player starts muted but can be unmuted
|
730
|
-
|
731
|
-
### Keyboard Shortcuts Properties
|
732
|
-
|
733
|
-
- **`enableKeyboardShortcuts`** (optional, default: `true`): Whether to enable keyboard shortcuts
|
734
|
-
- **`customShortcuts`** (optional): Custom keyboard shortcuts configuration:
|
735
|
-
```typescript
|
736
|
-
{
|
737
|
-
toggleFullscreen: number[], // Array of key codes
|
738
|
-
togglePause: number[],
|
739
|
-
toggleMute: number[],
|
740
|
-
jumpForward: number[],
|
741
|
-
jumpBack: number[],
|
742
|
-
volumeUp: number[],
|
743
|
-
volumeDown: number[]
|
744
|
-
}
|
745
|
-
```
|
746
|
-
|
747
|
-
### Ad Block Properties
|
748
|
-
|
749
|
-
- **`checkAdBlock`** (optional, default: `false`): Whether to check for ad blockers and show warnings
|
750
|
-
|
751
|
-
## Data hooks
|
752
|
-
Gets information about current user.
|
753
|
-
|
754
|
-
```ts
|
755
|
-
useUser: () => {
|
756
|
-
user: User | null
|
757
|
-
error: string | null
|
758
|
-
isInitialized: boolean
|
759
|
-
}
|
760
|
-
```
|
761
|
-
|
762
|
-
### useRowsInScreen hook
|
763
|
-
Gets array of Rows objects of specific screen and subscribes to its changes.
|
764
|
-
|
765
|
-
```ts
|
766
|
-
/**
|
767
|
-
* Use rows in screen
|
768
|
-
* @param screenId - screen id (from studio.tiv.io)
|
769
|
-
* @param options - subscription options
|
770
|
-
*/
|
771
|
-
useRowsInScreen: (screenId: string, options?: PaginationOptions) => {
|
772
|
-
pagination: PaginationInterface<Row> | null
|
773
|
-
error: Error | null
|
774
|
-
}
|
775
|
-
```
|
776
|
-
|
777
|
-
### useItemsInRow hook
|
778
|
-
Gets array of row items objects of specific row and subscribes to its changes.
|
779
|
-
|
780
|
-
```ts
|
781
|
-
/**
|
782
|
-
* Use row items
|
783
|
-
* @param rowId - row ID
|
784
|
-
* @param options - subscription options
|
785
|
-
*/
|
786
|
-
useItemsInRow: (rowId: string, options?: SubscribeToItemsInRowOptions) => {
|
787
|
-
pagination: PaginationInterface<ItemInRow> | null
|
788
|
-
error: Error | null
|
789
|
-
}
|
790
|
-
```
|
791
|
-
|
792
|
-
### useVideo hook
|
793
|
-
|
794
|
-
Gets Video object and subscribes to its changes.
|
795
|
-
|
796
|
-
```ts
|
797
|
-
/**
|
798
|
-
* Use video
|
799
|
-
* @param videoId - video id
|
800
|
-
*/
|
801
|
-
useVideo: (videoId: string) => {
|
802
|
-
error: string | null;
|
803
|
-
data: Video | null;
|
804
|
-
}
|
805
|
-
```
|
806
|
-
|
807
|
-
### useTaggedVideos hook
|
808
|
-
Gets videos with given tag IDs.
|
809
|
-
|
810
|
-
```ts
|
811
|
-
/**
|
812
|
-
* Use tagged videos
|
813
|
-
* @param tagIds - tag ids
|
814
|
-
* @param options - subscription options
|
815
|
-
* @public
|
816
|
-
*/
|
817
|
-
useTaggedVideos: (tagIds: string[], options?: SubscribeToItemsInRowOptions) => {
|
818
|
-
pagination: PaginationInterface<Video> | null
|
819
|
-
error: Error | null
|
820
|
-
}
|
821
|
-
```
|
1043
|
+
- **`showMarkers`
|