Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 102 additions & 0 deletions src/adapters/cast.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
declare global {
interface Window {
cast: any;
chrome: any;
}
}

import { CAST_JOIN_POLICY } from 'constants/cast';
import { URLS } from 'constants/common';
import { loadScript } from 'helpers/common';

class CastAdapter {
private static _instance: CastAdapter;
private castContext: any;
private remotePlayer: any;
private remotePlayerController: any;
private castSession: any;

constructor() {
if (CastAdapter._instance) {
console.warn(
'Instantiation failed: cannot create multiple instances of Cast framework returning existing instance'
);
return CastAdapter._instance;
}
CastAdapter._instance = this;
}

async load() {
await loadScript(
URLS.CAST,
() => {
console.log('Cast framework Loaded');
},
'cast'
)
.then(() => {
this.castContext = window.cast.framework.CastContext.getInstance();
})
.catch((msg: string) => {
console.log(msg);
});

return this.castContext;
}

async init(
receiverId: string = 'CC1AD845',
joinPolicy: keyof typeof CAST_JOIN_POLICY = 'ORIGIN_SCOPED'
) {
const castContext = await this.load();
if (castContext) {
castContext.setOptions({
receiverApplicationId: receiverId,
autoJoinPolicy: CAST_JOIN_POLICY[joinPolicy]
});
}
}

castAudio() {
this.castContext.requestSession().then(() => {
if (!this.castContext.getCurrentSession()) {
Comment thread
afkcodes marked this conversation as resolved.
Outdated
throw new Error(
'Failed to request Cast Session - Device Connection Failed'
);
} else {
this.castSession = this.castContext.getCurrentSession();
this.initializeRemotePlayer();
}
});
}

initializeRemotePlayer() {
this.remotePlayer = new window.cast.framework.RemotePlayer();
this.remotePlayerController =
new window.cast.framework.RemotePlayerController(this.remotePlayer);
}

getRemotePlayer() {
if (this.castSession) {
return this.remotePlayer;
} else {
console.error('Failed to get remotePlayer - No Cast Session active');
}
}

getRemotePlayerController() {
if (this.castSession) {
return this.remotePlayerController;
} else {
console.error(
'Failed to get remotePlayerController - No Cast Session active'
);
}
}

getCastSession() {
return this.castSession ? this.castSession : undefined;
}
}

export default CastAdapter;
21 changes: 21 additions & 0 deletions src/constants/cast.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { JoinPolicy } from 'types/cast.types';

declare global {
interface Window {
cast: any;
chrome: any;
}
}

// ORIGIN_SCOPED - Auto connect from same appId and page origin
// TAB_AND_ORIGIN_SCOPED - Auto connect from same appId, page origin, and tab
// PAGE_SCOPED - No auto connect

const CAST_JOIN_POLICY: JoinPolicy = {
CUSTOM_CONTROLLER_SCOPED: 'custom_controller_scoped',
TAB_AND_ORIGIN_SCOPED: 'tab_and_origin_scoped',
ORIGIN_SCOPED: 'origin_scoped',
PAGE_SCOPED: 'page_scoped'
};

export { CAST_JOIN_POLICY };
3 changes: 2 additions & 1 deletion src/constants/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ const ERROR_MSG_MAP: ErrorMessageMap = Object.freeze({
});

const URLS = {
HLS: 'https://cdn.jsdelivr.net/npm/hls.js/dist/hls.min.js'
HLS: 'https://cdn.jsdelivr.net/npm/hls.js/dist/hls.min.js',
CAST: 'https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1'
};

export { AUDIO_X_CONSTANTS, ERROR_MSG_MAP, PLAYBACK_STATE, URLS };
46 changes: 46 additions & 0 deletions src/events/castEvents.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
const CAST_REMOTE_PLAYER_EVENTS = {
ANY_CHANGE: 'anyChanged',
IS_CONNECTED_CHANGED: 'isConnectedChanged',
IS_MEDIA_LOADED_CHANGED: 'isMediaLoadedChanged',
QUEUE_DATA_CHANGED: 'queueDataChanged',
VIDEO_INFO_CHANGED: 'videoInfoChanged',
DURATION_CHANGED: 'durationChanged',
CURRENT_TIME_CHANGED: 'currentTimeChanged',
IS_PAUSED_CHANGED: 'isPausedChanged',
VOLUME_LEVEL_CHANGED: 'volumeLevelChanged',
CAN_CONTROL_VOLUME_CHANGED: 'canControlVolumeChanged',
IS_MUTED_CHANGED: 'isMutedChanged',
CAN_PAUSE_CHANGED: 'canPauseChanged',
CAN_SEEK_CHANGED: 'canSeekChanged',
DISPLAY_NAME_CHANGED: 'displayNameChanged',
STATUS_TEXT_CHANGED: 'statusTextChanged',
TITLE_CHANGED: 'titleChanged',
DISPLAY_STATUS_CHANGED: 'displayStatusChanged',
MEDIA_INFO_CHANGED: 'mediaInfoChanged',
IMAGE_URL_CHANGED: 'imageUrlChanged',
PLAYER_STATE_CHANGED: 'playerStateChanged',
IS_PLAYING_BREAK_CHANGED: 'isPlayingBreakChanged',
NUMBER_BREAK_CLIPS_CHANGED: 'numberBreakClipsChanged',
CURRENT_BREAK_CLIP_NUMBER_CHANGED: 'currentBreakClipNumberChanged',
CURRENT_BREAK_TIME_CHANGED: 'currentBreakTimeChanged',
CURRENT_BREAK_CLIP_TIME_CHANGED: 'currentBreakClipTimeChanged',
BREAK_ID_CHANGED: 'breakIdChanged',
BREAK_CLIP_ID_CHANGED: 'breakClipIdChanged',
WHEN_SKIPPABLE_CHANGED: 'whenSkippableChanged',
LIVE_SEEKABLE_RANGE_CHANGED: 'liveSeekableRangeChanged'
};

const CAST_SESSION_EVENTS = {
APPLICATION_STATUS_CHANGED: 'applicationstatuschanged',
APPLICATION_METADATA_CHANGED: 'applicationmetadatachanged',
ACTIVE_INPUT_STATE_CHANGED: 'activeinputstatechanged',
VOLUME_CHANGED: 'volumechanged',
MEDIA_SESSION: 'mediasession'
};

const CAST_CONTEXT_STATE = {
CAST_STATE_CHANGED: 'caststatechanged',
SESSION_STATE_CHANGED: 'sessionstatechanged'
};

export { CAST_CONTEXT_STATE, CAST_REMOTE_PLAYER_EVENTS, CAST_SESSION_EVENTS };
18 changes: 18 additions & 0 deletions src/states/castState.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const CAST_SESSION_STATE = {
NO_SESSION: 'NO_SESSION',
SESSION_STARTING: 'SESSION_STARTING',
SESSION_STARTED: 'SESSION_STARTED',
SESSION_START_FAILED: 'SESSION_START_FAILED',
SESSION_ENDING: 'SESSION_ENDING',
SESSION_ENDED: 'SESSION_ENDED',
SESSION_RESUMED: 'SESSION_RESUMED'
};

const CAST_DEVICE_STATE = {
NO_DEVICES_AVAILABLE: 'NO_DEVICES_AVAILABLE',
NOT_CONNECTED: 'NOT_CONNECTED',
CONNECTING: 'CONNECTING',
CONNECTED: 'CONNECTED'
};

export { CAST_DEVICE_STATE, CAST_SESSION_STATE };
8 changes: 8 additions & 0 deletions src/types/cast.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
interface JoinPolicy {
ORIGIN_SCOPED: string;
TAB_AND_ORIGIN_SCOPED: string;
PAGE_SCOPED: string;
CUSTOM_CONTROLLER_SCOPED: string;
}

export { JoinPolicy };