Refactor media message handling

This commit is contained in:
hensm
2021-04-29 01:36:50 +01:00
parent fce3fa31be
commit d6ea8b9856
6 changed files with 150 additions and 158 deletions

View File

@@ -138,6 +138,14 @@ export default class Session {
wasError = true; wasError = true;
} }
if (message.data.message.type === "STOP") {
if (this.clientHeartbeatIntervalId) {
clearInterval(this.clientHeartbeatIntervalId);
}
this.client.close();
}
this.sendMessage("shim:session/sendReceiverMessageResponse", { this.sendMessage("shim:session/sendReceiverMessageResponse", {
messageId: message.data.messageId messageId: message.data.messageId
, wasError , wasError

View File

@@ -6,7 +6,7 @@ import { TypedPort } from "./lib/TypedPort";
import { BridgeInfo } from "./lib/bridge"; import { BridgeInfo } from "./lib/bridge";
import { ReceiverDevice import { ReceiverDevice
, ReceiverMessage , SessionReceiverMessage
, ReceiverStatus } from "./types"; , ReceiverStatus } from "./types";
import { ReceiverSelectorMediaType } from "./background/receiverSelector"; import { ReceiverSelectorMediaType } from "./background/receiverSelector";
@@ -103,7 +103,7 @@ type AppMessageDefinitions = {
} }
, "bridge:session/close": {} , "bridge:session/close": {}
, "bridge:session/sendReceiverMessage": { , "bridge:session/sendReceiverMessage": {
message: ReceiverMessage message: SessionReceiverMessage
, messageId: string , messageId: string
, _id: string , _id: string
} }

View File

@@ -270,10 +270,7 @@ async function registerMediaElementListeners() {
}); });
mediaElement.addEventListener("ratechange", () => { mediaElement.addEventListener("ratechange", () => {
// TODO: Fix types // TODO: Re-implement this
currentMedia._sendMediaMessage("SET_PLAYBACK_RATE", {
playbackRate: mediaElement.playbackRate
} as any);
}); });
mediaElement.addEventListener("volumechange", () => { mediaElement.addEventListener("volumechange", () => {

View File

@@ -3,7 +3,7 @@
import { v4 as uuid } from "uuid"; import { v4 as uuid } from "uuid";
import logger from "../../lib/logger"; import logger from "../../lib/logger";
import { ReceiverMessage } from "../../types"; import { SessionMediaMessage, SessionReceiverMessage } from "../../types";
import { onMessage import { onMessage
, sendMessageResponse } from "../eventMessageChannel"; , sendMessageResponse } from "../eventMessageChannel";
@@ -365,8 +365,12 @@ export default class Session {
* receiver device. Promise resolves once the message is sent * receiver device. Promise resolves once the message is sent
* or an error occurs. * or an error occurs.
*/ */
#sendReceiverMessage = (message: ReceiverMessage) => { #sendReceiverMessage = (message: SessionReceiverMessage) => {
return new Promise<void>((resolve, reject) => { return new Promise<void>((resolve, reject) => {
if (!(message as any).requestId) {
(message as any).requestId = 0;
}
const messageId = uuid(); const messageId = uuid();
sendMessageResponse({ sendMessageResponse({
subject: "bridge:session/sendReceiverMessage" subject: "bridge:session/sendReceiverMessage"

View File

@@ -38,36 +38,7 @@ import { Callbacks
, SuccessCallback , SuccessCallback
, UpdateListener } from "../../types"; , UpdateListener } from "../../types";
import { SessionMediaMessage } from "../../../types";
type MediaRequest =
EditTracksInfoRequest
| GetStatusRequest
| PauseRequest
| PlayRequest
| QueueInsertItemsRequest
| QueueJumpRequest
| QueueRemoveItemsRequest
| QueueReorderItemsRequest
| QueueUpdateItemsRequest
| SeekRequest
| StopRequest
| VolumeRequest;
enum MediaMessageType {
Play = "PLAY"
, Load = "LOAD"
, Pause = "PAUSE"
, Seek = "SEEK"
, Stop = "STOP"
, MediaSetVolume = "MEDIA_SET_VOLUME"
, MediaGetStatus = "MEDIA_GET_STATUS"
, EditTracksInfo = "EDIT_TRACKS_INFO"
, QueueLoad = "QUEUE_LOAD"
, QueueInsert = "QUEUE_INSERT"
, QueueUpdate = "QUEUE_UPDATE"
, QueueRemove = "QUEUE_REMOVE"
, QueueReorder = "QUEUE_REORDER"
}
export default class Media { export default class Media {
@@ -177,10 +148,10 @@ export default class Media {
, successCallback?: SuccessCallback , successCallback?: SuccessCallback
, errorCallback?: ErrorCallback): void { , errorCallback?: ErrorCallback): void {
this._sendMediaMessage( this.#sendMediaMessage(
MediaMessageType.EditTracksInfo { type: "EDIT_TRACKS_INFO", ...editTracksInfoRequest })
, editTracksInfoRequest .then(successCallback)
, successCallback, errorCallback); .catch(errorCallback);
} }
public getEstimatedBreakClipTime() { public getEstimatedBreakClipTime() {
@@ -220,10 +191,10 @@ export default class Media {
getStatusRequest = new GetStatusRequest(); getStatusRequest = new GetStatusRequest();
} }
this._sendMediaMessage( this.#sendMediaMessage(
MediaMessageType.MediaGetStatus { type: "MEDIA_GET_STATUS", ...getStatusRequest })
, getStatusRequest .then(successCallback)
, successCallback, errorCallback); .catch(errorCallback);
} }
public pause( public pause(
@@ -235,10 +206,10 @@ export default class Media {
pauseRequest = new PauseRequest(); pauseRequest = new PauseRequest();
} }
this._sendMediaMessage( this.#sendMediaMessage(
MediaMessageType.Pause { type: "PAUSE", ...pauseRequest })
, pauseRequest .then(successCallback)
, successCallback, errorCallback); .catch(errorCallback);
} }
public play( public play(
@@ -250,10 +221,10 @@ export default class Media {
playRequest = new PlayRequest(); playRequest = new PlayRequest();
} }
this._sendMediaMessage( this.#sendMediaMessage(
MediaMessageType.Play { type: "PLAY", ...playRequest })
, playRequest .then(successCallback)
, successCallback, errorCallback); .catch(errorCallback);
} }
public queueAppendItem( public queueAppendItem(
@@ -261,10 +232,9 @@ export default class Media {
, successCallback?: SuccessCallback , successCallback?: SuccessCallback
, errorCallback?: ErrorCallback): void { , errorCallback?: ErrorCallback): void {
this._sendMediaMessage( this.#sendMediaMessage(new QueueInsertItemsRequest([ item ]))
MediaMessageType.QueueInsert .then(successCallback)
, new QueueInsertItemsRequest([ item ]) .catch(errorCallback);
, successCallback, errorCallback);
} }
public queueInsertItems( public queueInsertItems(
@@ -272,10 +242,10 @@ export default class Media {
, successCallback?: SuccessCallback , successCallback?: SuccessCallback
, errorCallback?: ErrorCallback): void { , errorCallback?: ErrorCallback): void {
this._sendMediaMessage( this.#sendMediaMessage(queueInsertItemsRequest)
MediaMessageType.QueueInsert .then(successCallback)
, queueInsertItemsRequest .catch(errorCallback);
, successCallback, errorCallback);
} }
public queueJumpToItem( public queueJumpToItem(
@@ -287,10 +257,9 @@ export default class Media {
const jumpRequest = new QueueJumpRequest(); const jumpRequest = new QueueJumpRequest();
jumpRequest.currentItemId = itemId; jumpRequest.currentItemId = itemId;
this._sendMediaMessage( this.#sendMediaMessage(jumpRequest)
MediaMessageType.QueueUpdate .then(successCallback)
, jumpRequest .catch(errorCallback);
, successCallback, errorCallback);
} }
} }
@@ -327,10 +296,9 @@ export default class Media {
reorderItemsRequest.insertBefore = existingItem.itemId; reorderItemsRequest.insertBefore = existingItem.itemId;
} }
this._sendMediaMessage( this.#sendMediaMessage(reorderItemsRequest)
MediaMessageType.QueueReorder .then(successCallback)
, reorderItemsRequest .catch(errorCallback);
, successCallback, errorCallback);
} }
} }
@@ -341,10 +309,9 @@ export default class Media {
const jumpRequest = new QueueJumpRequest(); const jumpRequest = new QueueJumpRequest();
jumpRequest.jump = 1; jumpRequest.jump = 1;
this._sendMediaMessage( this.#sendMediaMessage(jumpRequest)
MediaMessageType.QueueUpdate .then(successCallback)
, jumpRequest .catch(errorCallback);
, successCallback, errorCallback);
} }
public queuePrev( public queuePrev(
@@ -354,10 +321,9 @@ export default class Media {
const jumpRequest = new QueueJumpRequest(); const jumpRequest = new QueueJumpRequest();
jumpRequest.jump = -1; jumpRequest.jump = -1;
this._sendMediaMessage( this.#sendMediaMessage(jumpRequest)
MediaMessageType.QueueUpdate .then(successCallback)
, jumpRequest .catch(errorCallback);
, successCallback, errorCallback);
} }
public queueRemoveItem( public queueRemoveItem(
@@ -367,11 +333,12 @@ export default class Media {
const item = this.items?.find(item => item.itemId === itemId); const item = this.items?.find(item => item.itemId === itemId);
if (item) { if (item) {
const removeItemsRequest = new QueueRemoveItemsRequest([ itemId ]); const queueRemoveItemsRequest =
this._sendMediaMessage( new QueueRemoveItemsRequest([ itemId ]);
MediaMessageType.QueueRemove
, removeItemsRequest this.#sendMediaMessage(queueRemoveItemsRequest)
, successCallback, errorCallback); .then(successCallback)
.catch(errorCallback);
} }
} }
@@ -380,10 +347,9 @@ export default class Media {
, successCallback?: SuccessCallback , successCallback?: SuccessCallback
, errorCallback?: ErrorCallback): void { , errorCallback?: ErrorCallback): void {
this._sendMediaMessage( this.#sendMediaMessage(queueRemoveItemsRequest)
MediaMessageType.QueueRemove .then(successCallback)
, queueRemoveItemsRequest .catch(errorCallback);
, successCallback, errorCallback);
} }
public queueReorderItems( public queueReorderItems(
@@ -391,10 +357,9 @@ export default class Media {
, successCallback?: SuccessCallback , successCallback?: SuccessCallback
, errorCallback?: ErrorCallback): void { , errorCallback?: ErrorCallback): void {
this._sendMediaMessage( this.#sendMediaMessage(queueReorderItemsRequest)
MediaMessageType.QueueReorder .then(successCallback)
, queueReorderItemsRequest .catch(errorCallback);
, successCallback, errorCallback);
} }
public queueSetRepeatMode( public queueSetRepeatMode(
@@ -405,10 +370,9 @@ export default class Media {
const setPropertiesRequest = new QueueSetPropertiesRequest(); const setPropertiesRequest = new QueueSetPropertiesRequest();
setPropertiesRequest.repeatMode = repeatMode; setPropertiesRequest.repeatMode = repeatMode;
this._sendMediaMessage( this.#sendMediaMessage(setPropertiesRequest)
MediaMessageType.QueueUpdate .then(successCallback)
, setPropertiesRequest .catch(errorCallback);
, successCallback, errorCallback);
} }
public queueUpdateItems( public queueUpdateItems(
@@ -416,10 +380,9 @@ export default class Media {
, successCallback?: SuccessCallback , successCallback?: SuccessCallback
, errorCallback?: ErrorCallback): void { , errorCallback?: ErrorCallback): void {
this._sendMediaMessage( this.#sendMediaMessage(queueUpdateItemsRequest)
MediaMessageType.QueueUpdate .then(successCallback)
, queueUpdateItemsRequest .catch(errorCallback);
, successCallback, errorCallback);
} }
public removeUpdateListener(listener: UpdateListener) { public removeUpdateListener(listener: UpdateListener) {
@@ -431,11 +394,10 @@ export default class Media {
, successCallback?: SuccessCallback , successCallback?: SuccessCallback
, errorCallback?: ErrorCallback): void { , errorCallback?: ErrorCallback): void {
this.#sendMediaMessage(
this._sendMediaMessage( { type: "SEEK", ...seekRequest })
MediaMessageType.Seek .then(successCallback)
, seekRequest .catch(errorCallback);
, successCallback, errorCallback);
} }
public setVolume( public setVolume(
@@ -443,11 +405,10 @@ export default class Media {
, successCallback?: SuccessCallback , successCallback?: SuccessCallback
, errorCallback?: ErrorCallback): void { , errorCallback?: ErrorCallback): void {
this.#sendMediaMessage(
this._sendMediaMessage( { type: "MEDIA_SET_VOLUME", ...volumeRequest })
MediaMessageType.MediaSetVolume .then(successCallback)
, volumeRequest .catch(errorCallback);
, successCallback, errorCallback);
} }
public stop( public stop(
@@ -459,18 +420,17 @@ export default class Media {
stopRequest = new StopRequest(); stopRequest = new StopRequest();
} }
this._sendMediaMessage( this.#sendMediaMessage({
MediaMessageType.Stop type: "STOP"
, stopRequest , ...stopRequest
, () => { }).then(() => {
this.#isActive = false; this.#isActive = false;
this.#listener.disconnect(); this.#listener.disconnect();
if (successCallback) { if (successCallback) {
successCallback(); successCallback();
} }
} }).catch(errorCallback);
, errorCallback);
} }
public supportsCommand(command: string): boolean { public supportsCommand(command: string): boolean {
@@ -478,48 +438,43 @@ export default class Media {
} }
public _sendMediaMessage( #sendMediaMessage = async (message: SessionMediaMessage) => {
messageType: string if (!this.media) {
, message: MediaRequest return;
, successCallback?: SuccessCallback }
, errorCallback?: ErrorCallback) {
// TODO: Handle this and other errors better // TODO: Handle this and other errors better
if (!this.#isActive) { if (!this.#isActive) {
if (errorCallback) { throw new _Error(ErrorCode.SESSION_ERROR
errorCallback(new _Error(ErrorCode.SESSION_ERROR , "INVALID_MEDIA_SESSION_ID"
, "INVALID_MEDIA_SESSION_ID" , {
, { type: "INVALID_REQUEST"
type: "INVALID_REQUEST" , reason: "INVALID_MEDIA_SESSION_ID"
, reason: "INVALID_MEDIA_SESSION_ID" });
}));
}
return; return;
} }
// TODO: Fix this return new Promise<void>((resolve, reject) => {
(message as any).type = messageType; // TODO: Look at this again
(message as any).mediaSessionId = this.mediaSessionId;
(message as any).requestId = 0;
(message as any).sessionId = this.sessionId;
(message as any).mediaSessionId = this.mediaSessionId; const messageId = uuid();
(message as any).requestId = 0;
(message as any).sessionId = this.sessionId;
(message as any).customData = null;
const messageId = uuid(); this.#sendMediaMessageCallbacks.set(messageId, [
resolve, reject
]);
this.#sendMediaMessageCallbacks.set(messageId, [ sendMessageResponse({
successCallback subject: "bridge:media/sendMediaMessage"
, errorCallback , data: {
]); message
, messageId
sendMessageResponse({ , _id: this.#id
subject: "bridge:media/sendMediaMessage" }
, data: { });
message
, messageId
, _id: this.#id
}
}); });
} }
} }

View File

@@ -2,6 +2,10 @@
import { Volume } from "./shim/cast/dataClasses"; import { Volume } from "./shim/cast/dataClasses";
import { LoadRequest, QueueInsertItemsRequest, QueueJumpRequest
, QueueLoadRequest, QueueRemoveItemsRequest, QueueReorderItemsRequest
, QueueSetPropertiesRequest, QueueUpdateItemsRequest } from "./shim/cast/media";
export interface ReceiverDevice { export interface ReceiverDevice {
host: string host: string
@@ -31,13 +35,37 @@ export interface ReceiverStatus {
, volume: Volume , volume: Volume
} }
export type ReceiverMessage =
export type SessionMediaMessage =
{ type: "PLAY", customData: (any | null) }
| { type: "PAUSE", customData: (any | null) }
| { type: "SEEK", customData: (any | null) }
| { type: "STOP", customData: (any | null) }
| { type: "MEDIA_GET_STATUS", customData: (any | null) }
| { type: "SET_PLAYBACK_RATE", playbackRate: number }
| {
type: "MEDIA_SET_VOLUME"
, volume: Partial<Volume>
, customData: (any | null)
}
| {
type: "EDIT_TRACKS_INFO"
, requestId: number
, activeTrackIds?: (number[] | null)
, textTrackStyle?: (string | null)
}
| LoadRequest
| QueueLoadRequest
| QueueInsertItemsRequest
| QueueUpdateItemsRequest
| QueueJumpRequest
| QueueRemoveItemsRequest
| QueueReorderItemsRequest
| QueueSetPropertiesRequest;
export type SessionReceiverMessage =
{ type: "LAUNCH", appId: string } { type: "LAUNCH", appId: string }
| { type: "STOP", sessionId: string } | { type: "STOP", sessionId: string }
| { type: "GET_STATUS" } | { type: "GET_STATUS" }
| { type: "GET_APP_AVAILABILITY", appId: string[] } | { type: "GET_APP_AVAILABILITY", appId: string[] }
| { | { type: "SET_VOLUME", volume: Partial<Volume> };
type: "SET_VOLUME"
, volume: { level: number }
| { muted: boolean }
};