mirror of
https://github.com/hensm/fx_cast.git
synced 2026-06-10 09:39:58 +00:00
330 lines
10 KiB
TypeScript
330 lines
10 KiB
TypeScript
"use strict";
|
|
|
|
import logger from "../../../../lib/logger";
|
|
|
|
import uuid from "uuid/v1";
|
|
|
|
import EditTracksInfoRequest from "./EditTracksInfoRequest";
|
|
import GetStatusRequest from "./GetStatusRequest";
|
|
import MediaInfo from "./MediaInfo";
|
|
import PauseRequest from "./PauseRequest";
|
|
import PlayRequest from "./PlayRequest";
|
|
import QueueInsertItemsRequest from "./QueueInsertItemsRequest";
|
|
import QueueItem from "./QueueItem";
|
|
import QueueReorderItemsRequest from "./QueueReorderItemsRequest";
|
|
import QueueUpdateItemsRequest from "./QueueUpdateItemsRequest";
|
|
import SeekRequest from "./SeekRequest";
|
|
import StopRequest from "./StopRequest";
|
|
import VolumeRequest from "./VolumeRequest";
|
|
|
|
import Volume from "../../classes/Volume";
|
|
|
|
import { PlayerState
|
|
, RepeatMode } from "../enums";
|
|
|
|
import _Error from "../../classes/Error";
|
|
import { ErrorCode } from "../../enums";
|
|
|
|
import { onMessage, sendMessageResponse } from "../../../eventMessageChannel";
|
|
|
|
import { CallbacksMap
|
|
, ErrorCallback
|
|
, SuccessCallback
|
|
, UpdateListener } from "../../../types";
|
|
|
|
|
|
const _id = new WeakMap<Media, string>();
|
|
|
|
const _updateListeners = new WeakMap<Media, Set<UpdateListener>>();
|
|
const _sendMediaMessageCallbacks = new WeakMap<Media, CallbacksMap>();
|
|
|
|
const _lastCurrentTime = new WeakMap<Media, number>();
|
|
|
|
|
|
export default class Media {
|
|
public activeTrackIds: (number[] | null) = null;
|
|
public currentItemId: (number | null) = null;
|
|
public customData: any = null;
|
|
public currentTime: number = 0;
|
|
public idleReason: (string | null) = null;
|
|
public items: (QueueItem[] | null) = null;
|
|
public loadingItemId: (number | null) = null;
|
|
public media: (MediaInfo | null) = null;
|
|
public playbackRate: number = 1;
|
|
public playerState: string = PlayerState.IDLE;
|
|
public preloadedItemId: (number | null) = null;
|
|
public repeatMode: string = RepeatMode.OFF;
|
|
public supportedMediaCommands: string[] = [];
|
|
public volume: Volume = new Volume();
|
|
|
|
|
|
constructor (
|
|
public sessionId: string
|
|
, public mediaSessionId: number
|
|
, _internalSessionId: string) {
|
|
|
|
_id.set(this, uuid());
|
|
|
|
_updateListeners.set(this, new Set());
|
|
_sendMediaMessageCallbacks.set(this, new Map());
|
|
|
|
|
|
sendMessageResponse({
|
|
subject: "bridge:/media/initialize"
|
|
, data: {
|
|
sessionId
|
|
, mediaSessionId
|
|
, _internalSessionId
|
|
}
|
|
, _id: _id.get(this)
|
|
});
|
|
|
|
onMessage(message => {
|
|
if (!message._id || message._id !== _id.get(this)) {
|
|
return;
|
|
}
|
|
|
|
switch (message.subject) {
|
|
case "shim:/media/update": {
|
|
const status = message.data;
|
|
|
|
this.currentTime = status.currentTime;
|
|
_lastCurrentTime.set(this, status._lastCurrentTime);
|
|
this.customData = status.customData;
|
|
this.playbackRate = status.playbackRate;
|
|
this.playerState = status.playerState;
|
|
this.repeatMode = status.repeatMode;
|
|
|
|
if (status.volume) {
|
|
this.volume = new Volume(
|
|
status._volumeLevel
|
|
, status._volumeMuted);
|
|
}
|
|
|
|
if (status.media) {
|
|
this.media = status.media;
|
|
}
|
|
if (status.mediaSessionId) {
|
|
this.mediaSessionId = status.mediaSessionId;
|
|
}
|
|
|
|
// Call update listeners
|
|
const updateListeners = _updateListeners.get(this);
|
|
if (updateListeners) {
|
|
for (const listener of updateListeners) {
|
|
listener(true);
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case "shim:/media/sendMediaMessageResponse": {
|
|
const { messageId, error }
|
|
: { messageId: string, error: any } = message.data;
|
|
|
|
const [ successCallback, errorCallback ]
|
|
= _sendMediaMessageCallbacks
|
|
.get(this)?.get(messageId) ?? [];
|
|
|
|
if (error && errorCallback) {
|
|
errorCallback(new _Error(ErrorCode.SESSION_ERROR));
|
|
} else if (successCallback) {
|
|
successCallback();
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
}
|
|
});
|
|
}
|
|
|
|
public addUpdateListener (listener: UpdateListener): void {
|
|
_updateListeners.get(this)?.add(listener);
|
|
}
|
|
|
|
public editTracksInfo (
|
|
_editTracksInfoRequest: EditTracksInfoRequest
|
|
, _successCallback?: SuccessCallback
|
|
, _errorCallback?: ErrorCallback): void {
|
|
|
|
logger.info("STUB :: Media#editTracksInfo");
|
|
}
|
|
|
|
public getEstimatedTime (): number {
|
|
const lastTime = _lastCurrentTime.get(this);
|
|
|
|
if (this.currentTime === undefined || lastTime === undefined) {
|
|
return 0;
|
|
}
|
|
|
|
return this.currentTime + ((Date.now() / 1000) - lastTime);
|
|
}
|
|
|
|
public getStatus (
|
|
_getStatusRequest?: GetStatusRequest
|
|
, successCallback?: SuccessCallback
|
|
, errorCallback?: ErrorCallback): void {
|
|
|
|
this._sendMediaMessage({ type: "MEDIA_GET_STATUS" }
|
|
, successCallback, errorCallback);
|
|
}
|
|
|
|
public pause (
|
|
_pauseRequest?: PauseRequest
|
|
, successCallback?: SuccessCallback
|
|
, errorCallback?: ErrorCallback): void {
|
|
|
|
this._sendMediaMessage({ type: "PAUSE" }
|
|
, successCallback, errorCallback);
|
|
}
|
|
|
|
public play (
|
|
_playRequest?: PlayRequest
|
|
, successCallback?: SuccessCallback
|
|
, errorCallback?: ErrorCallback): void {
|
|
|
|
this._sendMediaMessage({ type: "PLAY" }
|
|
, successCallback, errorCallback);
|
|
}
|
|
|
|
public queueAppendItem (
|
|
_item: QueueItem
|
|
, _successCallback?: SuccessCallback
|
|
, _errorCallback?: ErrorCallback): void {
|
|
logger.info("STUB :: Media#queueAppendItem");
|
|
}
|
|
|
|
public queueInsertItems (
|
|
_queueInsertItemsRequest: QueueInsertItemsRequest
|
|
, _successCallback?: SuccessCallback
|
|
, _errorCallback?: ErrorCallback): void {
|
|
logger.info("STUB :: Media#queueInsertItems");
|
|
}
|
|
|
|
public queueJumpToItem (
|
|
_itemId: number
|
|
, _successCallback?: SuccessCallback
|
|
, _errorCallback?: ErrorCallback): void {
|
|
logger.info("STUB :: Media#queueJumpToItem");
|
|
}
|
|
|
|
public queueMoveItemToNewIndex (
|
|
_itemId: number
|
|
, _newIndex: number
|
|
, _successCallback?: SuccessCallback
|
|
, _errorCallback?: ErrorCallback): void {
|
|
logger.info("STUB :: Media#queueMoveItemToNewIndex");
|
|
}
|
|
|
|
public queueNext (
|
|
_successCallback?: SuccessCallback
|
|
, _errorCallback?: ErrorCallback): void {
|
|
logger.info("STUB :: Media#queueNext");
|
|
}
|
|
|
|
public queuePrev (
|
|
_successCallback?: SuccessCallback
|
|
, _errorCallback?: ErrorCallback): void {
|
|
logger.info("STUB :: Media#queuePrev");
|
|
}
|
|
|
|
public queueRemoveItem (
|
|
_itemId: number
|
|
, _successCallback?: SuccessCallback
|
|
, _errorCallback?: ErrorCallback): void {
|
|
logger.info("STUB :: Media#queueRemoveItem");
|
|
}
|
|
|
|
public queueReorderItems (
|
|
_queueReorderItemsRequest: QueueReorderItemsRequest
|
|
, _successCallback?: SuccessCallback
|
|
, _errorCallback?: ErrorCallback): void {
|
|
logger.info("STUB :: Media#queueReorderItems");
|
|
}
|
|
|
|
public queueSetRepeatMode (
|
|
_repeatMode: string
|
|
, _successCallback?: SuccessCallback
|
|
, _errorCallback?: ErrorCallback): void {
|
|
logger.info("STUB :: Media#queueSetRepeatMode");
|
|
}
|
|
|
|
public queueUpdateItems (
|
|
_queueUpdateItemsRequest: QueueUpdateItemsRequest
|
|
, _successCallback?: SuccessCallback
|
|
, _errorCallback?: ErrorCallback): void {
|
|
logger.info("STUB :: Media#queueUpdateItems");
|
|
}
|
|
|
|
public removeUpdateListener (listener: UpdateListener) {
|
|
_updateListeners.get(this)?.delete(listener);
|
|
}
|
|
|
|
public seek (
|
|
seekRequest: SeekRequest
|
|
, successCallback?: SuccessCallback
|
|
, errorCallback?: ErrorCallback): void {
|
|
|
|
this._sendMediaMessage({
|
|
type: "SEEK"
|
|
, currentTime: seekRequest.currentTime
|
|
}, successCallback, errorCallback);
|
|
}
|
|
|
|
public setVolume (
|
|
volumeRequest: VolumeRequest
|
|
, successCallback?: SuccessCallback
|
|
, errorCallback?: ErrorCallback): void {
|
|
|
|
this._sendMediaMessage({
|
|
type: "SET_VOLUME"
|
|
, volume: volumeRequest.volume
|
|
}, successCallback, errorCallback);
|
|
}
|
|
|
|
public stop (
|
|
_stopRequest: StopRequest
|
|
, successCallback?: SuccessCallback
|
|
, errorCallback?: ErrorCallback): void {
|
|
|
|
this._sendMediaMessage({
|
|
type: "STOP"
|
|
}, successCallback, errorCallback);
|
|
}
|
|
|
|
public supportsCommand (_command: string): boolean {
|
|
logger.info("STUB :: Media#supportsCommand");
|
|
return true;
|
|
}
|
|
|
|
|
|
public _sendMediaMessage (
|
|
message: any
|
|
, successCallback?: SuccessCallback
|
|
, errorCallback?: ErrorCallback) {
|
|
|
|
message.mediaSessionId = this.mediaSessionId;
|
|
message.requestId = 0;
|
|
message.sessionId = this.sessionId;
|
|
message.customData = null;
|
|
|
|
const messageId = uuid();
|
|
|
|
_sendMediaMessageCallbacks.get(this)?.set(messageId, [
|
|
successCallback
|
|
, errorCallback
|
|
]);
|
|
|
|
sendMessageResponse({
|
|
subject: "bridge:/media/sendMediaMessage"
|
|
, data: {
|
|
message
|
|
, messageId
|
|
}
|
|
, _id: _id.get(this)
|
|
});
|
|
}
|
|
}
|