@thestatic-tv/dcl-sdk 2.5.1 → 2.5.3
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/dist/index.d.mts +30 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.js +98 -7
- package/dist/index.mjs +99 -8
- package/package.json +3 -1
package/dist/index.d.mts
CHANGED
|
@@ -995,6 +995,10 @@ declare class StaticTVClient {
|
|
|
995
995
|
*/
|
|
996
996
|
getConfig(): StaticTVConfig;
|
|
997
997
|
private _currentVideoUrl;
|
|
998
|
+
private _pendingVideoData;
|
|
999
|
+
private _streamVerified;
|
|
1000
|
+
private _verificationTimeoutId;
|
|
1001
|
+
private _videoEventsRegistered;
|
|
998
1002
|
/**
|
|
999
1003
|
* Play a video on the configured videoScreen entity.
|
|
1000
1004
|
* Called by Guide UI and Admin Panel.
|
|
@@ -1013,15 +1017,41 @@ declare class StaticTVClient {
|
|
|
1013
1017
|
* @internal
|
|
1014
1018
|
*/
|
|
1015
1019
|
private _playVideoInternal;
|
|
1020
|
+
/**
|
|
1021
|
+
* Register video event handlers for stream verification
|
|
1022
|
+
* @internal
|
|
1023
|
+
*/
|
|
1024
|
+
private _registerVideoEvents;
|
|
1025
|
+
/**
|
|
1026
|
+
* Start stream verification timeout
|
|
1027
|
+
* @internal
|
|
1028
|
+
*/
|
|
1029
|
+
private _startStreamVerification;
|
|
1030
|
+
/**
|
|
1031
|
+
* Handle stream that's offline or failed to verify
|
|
1032
|
+
* @internal
|
|
1033
|
+
*/
|
|
1034
|
+
private _handleStreamOffline;
|
|
1035
|
+
/**
|
|
1036
|
+
* Clear verification timeout
|
|
1037
|
+
* @internal
|
|
1038
|
+
*/
|
|
1039
|
+
private _clearVerificationTimeout;
|
|
1016
1040
|
/**
|
|
1017
1041
|
* Get the currently playing video URL
|
|
1018
1042
|
*/
|
|
1019
1043
|
get currentVideoUrl(): string;
|
|
1020
1044
|
/**
|
|
1021
1045
|
* Internal handler for Guide video selection
|
|
1046
|
+
* Tries to play the stream and verifies it's working (like M1D-HQ behavior)
|
|
1022
1047
|
* @internal
|
|
1023
1048
|
*/
|
|
1024
1049
|
_handleGuideVideoSelect(video: GuideVideo): void;
|
|
1050
|
+
/**
|
|
1051
|
+
* Play video with stream verification for live content
|
|
1052
|
+
* @internal
|
|
1053
|
+
*/
|
|
1054
|
+
private _playVideoWithVerification;
|
|
1025
1055
|
/**
|
|
1026
1056
|
* Internal handler for broadcast messages
|
|
1027
1057
|
* @internal
|
package/dist/index.d.ts
CHANGED
|
@@ -995,6 +995,10 @@ declare class StaticTVClient {
|
|
|
995
995
|
*/
|
|
996
996
|
getConfig(): StaticTVConfig;
|
|
997
997
|
private _currentVideoUrl;
|
|
998
|
+
private _pendingVideoData;
|
|
999
|
+
private _streamVerified;
|
|
1000
|
+
private _verificationTimeoutId;
|
|
1001
|
+
private _videoEventsRegistered;
|
|
998
1002
|
/**
|
|
999
1003
|
* Play a video on the configured videoScreen entity.
|
|
1000
1004
|
* Called by Guide UI and Admin Panel.
|
|
@@ -1013,15 +1017,41 @@ declare class StaticTVClient {
|
|
|
1013
1017
|
* @internal
|
|
1014
1018
|
*/
|
|
1015
1019
|
private _playVideoInternal;
|
|
1020
|
+
/**
|
|
1021
|
+
* Register video event handlers for stream verification
|
|
1022
|
+
* @internal
|
|
1023
|
+
*/
|
|
1024
|
+
private _registerVideoEvents;
|
|
1025
|
+
/**
|
|
1026
|
+
* Start stream verification timeout
|
|
1027
|
+
* @internal
|
|
1028
|
+
*/
|
|
1029
|
+
private _startStreamVerification;
|
|
1030
|
+
/**
|
|
1031
|
+
* Handle stream that's offline or failed to verify
|
|
1032
|
+
* @internal
|
|
1033
|
+
*/
|
|
1034
|
+
private _handleStreamOffline;
|
|
1035
|
+
/**
|
|
1036
|
+
* Clear verification timeout
|
|
1037
|
+
* @internal
|
|
1038
|
+
*/
|
|
1039
|
+
private _clearVerificationTimeout;
|
|
1016
1040
|
/**
|
|
1017
1041
|
* Get the currently playing video URL
|
|
1018
1042
|
*/
|
|
1019
1043
|
get currentVideoUrl(): string;
|
|
1020
1044
|
/**
|
|
1021
1045
|
* Internal handler for Guide video selection
|
|
1046
|
+
* Tries to play the stream and verifies it's working (like M1D-HQ behavior)
|
|
1022
1047
|
* @internal
|
|
1023
1048
|
*/
|
|
1024
1049
|
_handleGuideVideoSelect(video: GuideVideo): void;
|
|
1050
|
+
/**
|
|
1051
|
+
* Play video with stream verification for live content
|
|
1052
|
+
* @internal
|
|
1053
|
+
*/
|
|
1054
|
+
private _playVideoWithVerification;
|
|
1025
1055
|
/**
|
|
1026
1056
|
* Internal handler for broadcast messages
|
|
1027
1057
|
* @internal
|
package/dist/index.js
CHANGED
|
@@ -3493,6 +3493,7 @@ function setupStaticUI(client) {
|
|
|
3493
3493
|
|
|
3494
3494
|
// src/StaticTVClient.ts
|
|
3495
3495
|
var import_ecs3 = require("@dcl/sdk/ecs");
|
|
3496
|
+
var utils = __toESM(require("@dcl-sdk/utils"));
|
|
3496
3497
|
var DEFAULT_BASE_URL = "https://thestatic.tv/api/v1/dcl";
|
|
3497
3498
|
var DEFAULT_FALLBACK_VIDEO = "https://media.thestatic.tv/fallback-loop.mp4";
|
|
3498
3499
|
var KEY_TYPE_CHANNEL = "channel";
|
|
@@ -3557,6 +3558,11 @@ var StaticTVClient = class {
|
|
|
3557
3558
|
// --- VIDEO PLAYBACK (Internal handler for videoScreen) ---
|
|
3558
3559
|
// =============================================================================
|
|
3559
3560
|
this._currentVideoUrl = "";
|
|
3561
|
+
this._pendingVideoData = null;
|
|
3562
|
+
this._streamVerified = false;
|
|
3563
|
+
this._verificationTimeoutId = null;
|
|
3564
|
+
// DCL timer ID
|
|
3565
|
+
this._videoEventsRegistered = false;
|
|
3560
3566
|
this._featuresReadyPromise = new Promise((resolve) => {
|
|
3561
3567
|
this._featuresReadyResolve = resolve;
|
|
3562
3568
|
});
|
|
@@ -3779,9 +3785,11 @@ var StaticTVClient = class {
|
|
|
3779
3785
|
* Internal video player - handles both regular videos and fallback
|
|
3780
3786
|
* @internal
|
|
3781
3787
|
*/
|
|
3782
|
-
_playVideoInternal(url, isFallback = false) {
|
|
3788
|
+
_playVideoInternal(url, isFallback = false, isLiveStream = false) {
|
|
3783
3789
|
const screen = this.config.videoScreen;
|
|
3784
3790
|
if (screen === void 0) return;
|
|
3791
|
+
this._clearVerificationTimeout();
|
|
3792
|
+
this._streamVerified = false;
|
|
3785
3793
|
if (import_ecs3.VideoPlayer.has(screen)) {
|
|
3786
3794
|
import_ecs3.VideoPlayer.deleteFrom(screen);
|
|
3787
3795
|
}
|
|
@@ -3795,6 +3803,74 @@ var StaticTVClient = class {
|
|
|
3795
3803
|
import_ecs3.Material.setBasicMaterial(screen, {
|
|
3796
3804
|
texture: import_ecs3.Material.Texture.Video({ videoPlayerEntity: screen })
|
|
3797
3805
|
});
|
|
3806
|
+
if (!this._videoEventsRegistered) {
|
|
3807
|
+
this._registerVideoEvents();
|
|
3808
|
+
}
|
|
3809
|
+
if (isLiveStream && !isFallback) {
|
|
3810
|
+
this._startStreamVerification();
|
|
3811
|
+
}
|
|
3812
|
+
}
|
|
3813
|
+
/**
|
|
3814
|
+
* Register video event handlers for stream verification
|
|
3815
|
+
* @internal
|
|
3816
|
+
*/
|
|
3817
|
+
_registerVideoEvents() {
|
|
3818
|
+
const screen = this.config.videoScreen;
|
|
3819
|
+
if (screen === void 0) return;
|
|
3820
|
+
this._videoEventsRegistered = true;
|
|
3821
|
+
import_ecs3.videoEventsSystem.registerVideoEventsEntity(screen, (videoEvent) => {
|
|
3822
|
+
if (videoEvent.state === import_ecs3.VideoState.VS_READY || videoEvent.state === import_ecs3.VideoState.VS_PLAYING) {
|
|
3823
|
+
if (this._pendingVideoData && !this._streamVerified) {
|
|
3824
|
+
this._streamVerified = true;
|
|
3825
|
+
this._clearVerificationTimeout();
|
|
3826
|
+
this.log(`Stream verified: ${this._pendingVideoData.name}`);
|
|
3827
|
+
}
|
|
3828
|
+
}
|
|
3829
|
+
if (videoEvent.state === import_ecs3.VideoState.VS_ERROR) {
|
|
3830
|
+
if (this._pendingVideoData) {
|
|
3831
|
+
this.log(`Stream error for: ${this._pendingVideoData.name}`);
|
|
3832
|
+
this._handleStreamOffline();
|
|
3833
|
+
}
|
|
3834
|
+
}
|
|
3835
|
+
});
|
|
3836
|
+
}
|
|
3837
|
+
/**
|
|
3838
|
+
* Start stream verification timeout
|
|
3839
|
+
* @internal
|
|
3840
|
+
*/
|
|
3841
|
+
_startStreamVerification() {
|
|
3842
|
+
if (this._pendingVideoData) {
|
|
3843
|
+
this.showNotification(`Connecting to ${this._pendingVideoData.name}...`, 1e4);
|
|
3844
|
+
}
|
|
3845
|
+
this._verificationTimeoutId = utils.timers.setTimeout(() => {
|
|
3846
|
+
if (!this._streamVerified && this._pendingVideoData) {
|
|
3847
|
+
this.log(`Stream verification timeout for: ${this._pendingVideoData.name}`);
|
|
3848
|
+
this._handleStreamOffline();
|
|
3849
|
+
}
|
|
3850
|
+
}, 8e3);
|
|
3851
|
+
}
|
|
3852
|
+
/**
|
|
3853
|
+
* Handle stream that's offline or failed to verify
|
|
3854
|
+
* @internal
|
|
3855
|
+
*/
|
|
3856
|
+
_handleStreamOffline() {
|
|
3857
|
+
const videoData = this._pendingVideoData;
|
|
3858
|
+
this._pendingVideoData = null;
|
|
3859
|
+
this._clearVerificationTimeout();
|
|
3860
|
+
if (videoData) {
|
|
3861
|
+
this.showNotification(`${videoData.name} is offline`, 4e3);
|
|
3862
|
+
}
|
|
3863
|
+
this.stopVideo();
|
|
3864
|
+
}
|
|
3865
|
+
/**
|
|
3866
|
+
* Clear verification timeout
|
|
3867
|
+
* @internal
|
|
3868
|
+
*/
|
|
3869
|
+
_clearVerificationTimeout() {
|
|
3870
|
+
if (this._verificationTimeoutId) {
|
|
3871
|
+
utils.timers.clearTimeout(this._verificationTimeoutId);
|
|
3872
|
+
this._verificationTimeoutId = null;
|
|
3873
|
+
}
|
|
3798
3874
|
}
|
|
3799
3875
|
/**
|
|
3800
3876
|
* Get the currently playing video URL
|
|
@@ -3804,16 +3880,31 @@ var StaticTVClient = class {
|
|
|
3804
3880
|
}
|
|
3805
3881
|
/**
|
|
3806
3882
|
* Internal handler for Guide video selection
|
|
3883
|
+
* Tries to play the stream and verifies it's working (like M1D-HQ behavior)
|
|
3807
3884
|
* @internal
|
|
3808
3885
|
*/
|
|
3809
3886
|
_handleGuideVideoSelect(video) {
|
|
3810
|
-
if (video.
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
|
|
3887
|
+
if (!video.src) return;
|
|
3888
|
+
this._pendingVideoData = video;
|
|
3889
|
+
const isLiveStream = video.channelId !== void 0 || video.src.includes(".m3u8") || video.src.includes("media.thestatic.tv");
|
|
3890
|
+
this._playVideoWithVerification(video, isLiveStream);
|
|
3891
|
+
}
|
|
3892
|
+
/**
|
|
3893
|
+
* Play video with stream verification for live content
|
|
3894
|
+
* @internal
|
|
3895
|
+
*/
|
|
3896
|
+
_playVideoWithVerification(video, isLiveStream) {
|
|
3897
|
+
const screen = this.config.videoScreen;
|
|
3898
|
+
if (screen !== void 0) {
|
|
3899
|
+
this.log(`Playing video: ${video.src} (live: ${isLiveStream})`);
|
|
3900
|
+
this._currentVideoUrl = video.src;
|
|
3901
|
+
this._playVideoInternal(video.src, false, isLiveStream);
|
|
3902
|
+
if (this.guideUI) {
|
|
3903
|
+
this.guideUI.currentVideoId = video.id;
|
|
3904
|
+
}
|
|
3814
3905
|
}
|
|
3815
|
-
if (
|
|
3816
|
-
this.
|
|
3906
|
+
if (this.config.onVideoPlay) {
|
|
3907
|
+
this.config.onVideoPlay(video.src);
|
|
3817
3908
|
}
|
|
3818
3909
|
}
|
|
3819
3910
|
/**
|
package/dist/index.mjs
CHANGED
|
@@ -3449,7 +3449,8 @@ function setupStaticUI(client) {
|
|
|
3449
3449
|
}
|
|
3450
3450
|
|
|
3451
3451
|
// src/StaticTVClient.ts
|
|
3452
|
-
import { VideoPlayer, Material } from "@dcl/sdk/ecs";
|
|
3452
|
+
import { VideoPlayer, Material, videoEventsSystem, VideoState } from "@dcl/sdk/ecs";
|
|
3453
|
+
import * as utils from "@dcl-sdk/utils";
|
|
3453
3454
|
var DEFAULT_BASE_URL = "https://thestatic.tv/api/v1/dcl";
|
|
3454
3455
|
var DEFAULT_FALLBACK_VIDEO = "https://media.thestatic.tv/fallback-loop.mp4";
|
|
3455
3456
|
var KEY_TYPE_CHANNEL = "channel";
|
|
@@ -3514,6 +3515,11 @@ var StaticTVClient = class {
|
|
|
3514
3515
|
// --- VIDEO PLAYBACK (Internal handler for videoScreen) ---
|
|
3515
3516
|
// =============================================================================
|
|
3516
3517
|
this._currentVideoUrl = "";
|
|
3518
|
+
this._pendingVideoData = null;
|
|
3519
|
+
this._streamVerified = false;
|
|
3520
|
+
this._verificationTimeoutId = null;
|
|
3521
|
+
// DCL timer ID
|
|
3522
|
+
this._videoEventsRegistered = false;
|
|
3517
3523
|
this._featuresReadyPromise = new Promise((resolve) => {
|
|
3518
3524
|
this._featuresReadyResolve = resolve;
|
|
3519
3525
|
});
|
|
@@ -3736,9 +3742,11 @@ var StaticTVClient = class {
|
|
|
3736
3742
|
* Internal video player - handles both regular videos and fallback
|
|
3737
3743
|
* @internal
|
|
3738
3744
|
*/
|
|
3739
|
-
_playVideoInternal(url, isFallback = false) {
|
|
3745
|
+
_playVideoInternal(url, isFallback = false, isLiveStream = false) {
|
|
3740
3746
|
const screen = this.config.videoScreen;
|
|
3741
3747
|
if (screen === void 0) return;
|
|
3748
|
+
this._clearVerificationTimeout();
|
|
3749
|
+
this._streamVerified = false;
|
|
3742
3750
|
if (VideoPlayer.has(screen)) {
|
|
3743
3751
|
VideoPlayer.deleteFrom(screen);
|
|
3744
3752
|
}
|
|
@@ -3752,6 +3760,74 @@ var StaticTVClient = class {
|
|
|
3752
3760
|
Material.setBasicMaterial(screen, {
|
|
3753
3761
|
texture: Material.Texture.Video({ videoPlayerEntity: screen })
|
|
3754
3762
|
});
|
|
3763
|
+
if (!this._videoEventsRegistered) {
|
|
3764
|
+
this._registerVideoEvents();
|
|
3765
|
+
}
|
|
3766
|
+
if (isLiveStream && !isFallback) {
|
|
3767
|
+
this._startStreamVerification();
|
|
3768
|
+
}
|
|
3769
|
+
}
|
|
3770
|
+
/**
|
|
3771
|
+
* Register video event handlers for stream verification
|
|
3772
|
+
* @internal
|
|
3773
|
+
*/
|
|
3774
|
+
_registerVideoEvents() {
|
|
3775
|
+
const screen = this.config.videoScreen;
|
|
3776
|
+
if (screen === void 0) return;
|
|
3777
|
+
this._videoEventsRegistered = true;
|
|
3778
|
+
videoEventsSystem.registerVideoEventsEntity(screen, (videoEvent) => {
|
|
3779
|
+
if (videoEvent.state === VideoState.VS_READY || videoEvent.state === VideoState.VS_PLAYING) {
|
|
3780
|
+
if (this._pendingVideoData && !this._streamVerified) {
|
|
3781
|
+
this._streamVerified = true;
|
|
3782
|
+
this._clearVerificationTimeout();
|
|
3783
|
+
this.log(`Stream verified: ${this._pendingVideoData.name}`);
|
|
3784
|
+
}
|
|
3785
|
+
}
|
|
3786
|
+
if (videoEvent.state === VideoState.VS_ERROR) {
|
|
3787
|
+
if (this._pendingVideoData) {
|
|
3788
|
+
this.log(`Stream error for: ${this._pendingVideoData.name}`);
|
|
3789
|
+
this._handleStreamOffline();
|
|
3790
|
+
}
|
|
3791
|
+
}
|
|
3792
|
+
});
|
|
3793
|
+
}
|
|
3794
|
+
/**
|
|
3795
|
+
* Start stream verification timeout
|
|
3796
|
+
* @internal
|
|
3797
|
+
*/
|
|
3798
|
+
_startStreamVerification() {
|
|
3799
|
+
if (this._pendingVideoData) {
|
|
3800
|
+
this.showNotification(`Connecting to ${this._pendingVideoData.name}...`, 1e4);
|
|
3801
|
+
}
|
|
3802
|
+
this._verificationTimeoutId = utils.timers.setTimeout(() => {
|
|
3803
|
+
if (!this._streamVerified && this._pendingVideoData) {
|
|
3804
|
+
this.log(`Stream verification timeout for: ${this._pendingVideoData.name}`);
|
|
3805
|
+
this._handleStreamOffline();
|
|
3806
|
+
}
|
|
3807
|
+
}, 8e3);
|
|
3808
|
+
}
|
|
3809
|
+
/**
|
|
3810
|
+
* Handle stream that's offline or failed to verify
|
|
3811
|
+
* @internal
|
|
3812
|
+
*/
|
|
3813
|
+
_handleStreamOffline() {
|
|
3814
|
+
const videoData = this._pendingVideoData;
|
|
3815
|
+
this._pendingVideoData = null;
|
|
3816
|
+
this._clearVerificationTimeout();
|
|
3817
|
+
if (videoData) {
|
|
3818
|
+
this.showNotification(`${videoData.name} is offline`, 4e3);
|
|
3819
|
+
}
|
|
3820
|
+
this.stopVideo();
|
|
3821
|
+
}
|
|
3822
|
+
/**
|
|
3823
|
+
* Clear verification timeout
|
|
3824
|
+
* @internal
|
|
3825
|
+
*/
|
|
3826
|
+
_clearVerificationTimeout() {
|
|
3827
|
+
if (this._verificationTimeoutId) {
|
|
3828
|
+
utils.timers.clearTimeout(this._verificationTimeoutId);
|
|
3829
|
+
this._verificationTimeoutId = null;
|
|
3830
|
+
}
|
|
3755
3831
|
}
|
|
3756
3832
|
/**
|
|
3757
3833
|
* Get the currently playing video URL
|
|
@@ -3761,16 +3837,31 @@ var StaticTVClient = class {
|
|
|
3761
3837
|
}
|
|
3762
3838
|
/**
|
|
3763
3839
|
* Internal handler for Guide video selection
|
|
3840
|
+
* Tries to play the stream and verifies it's working (like M1D-HQ behavior)
|
|
3764
3841
|
* @internal
|
|
3765
3842
|
*/
|
|
3766
3843
|
_handleGuideVideoSelect(video) {
|
|
3767
|
-
if (video.
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
3844
|
+
if (!video.src) return;
|
|
3845
|
+
this._pendingVideoData = video;
|
|
3846
|
+
const isLiveStream = video.channelId !== void 0 || video.src.includes(".m3u8") || video.src.includes("media.thestatic.tv");
|
|
3847
|
+
this._playVideoWithVerification(video, isLiveStream);
|
|
3848
|
+
}
|
|
3849
|
+
/**
|
|
3850
|
+
* Play video with stream verification for live content
|
|
3851
|
+
* @internal
|
|
3852
|
+
*/
|
|
3853
|
+
_playVideoWithVerification(video, isLiveStream) {
|
|
3854
|
+
const screen = this.config.videoScreen;
|
|
3855
|
+
if (screen !== void 0) {
|
|
3856
|
+
this.log(`Playing video: ${video.src} (live: ${isLiveStream})`);
|
|
3857
|
+
this._currentVideoUrl = video.src;
|
|
3858
|
+
this._playVideoInternal(video.src, false, isLiveStream);
|
|
3859
|
+
if (this.guideUI) {
|
|
3860
|
+
this.guideUI.currentVideoId = video.id;
|
|
3861
|
+
}
|
|
3771
3862
|
}
|
|
3772
|
-
if (
|
|
3773
|
-
this.
|
|
3863
|
+
if (this.config.onVideoPlay) {
|
|
3864
|
+
this.config.onVideoPlay(video.src);
|
|
3774
3865
|
}
|
|
3775
3866
|
}
|
|
3776
3867
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thestatic-tv/dcl-sdk",
|
|
3
|
-
"version": "2.5.
|
|
3
|
+
"version": "2.5.3",
|
|
4
4
|
"description": "Connect your Decentraland scene to thestatic.tv - full channel lineup, metrics tracking, and interactions",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -46,9 +46,11 @@
|
|
|
46
46
|
"url": "https://github.com/thestatic-tv/dcl-sdk/issues"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
49
|
+
"@dcl-sdk/utils": ">=1.0.0",
|
|
49
50
|
"@dcl/sdk": ">=7.0.0"
|
|
50
51
|
},
|
|
51
52
|
"devDependencies": {
|
|
53
|
+
"@dcl-sdk/utils": "^1.4.0",
|
|
52
54
|
"@dcl/sdk": "^7.0.0",
|
|
53
55
|
"@vitest/coverage-v8": "^4.0.16",
|
|
54
56
|
"tsup": "^8.0.0",
|