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;
}
if (message.data.message.type === "STOP") {
if (this.clientHeartbeatIntervalId) {
clearInterval(this.clientHeartbeatIntervalId);
}
this.client.close();
}
this.sendMessage("shim:session/sendReceiverMessageResponse", {
messageId: message.data.messageId
, wasError

View File

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

View File

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

View File

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

View File

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

View File

@@ -2,6 +2,10 @@
import { Volume } from "./shim/cast/dataClasses";
import { LoadRequest, QueueInsertItemsRequest, QueueJumpRequest
, QueueLoadRequest, QueueRemoveItemsRequest, QueueReorderItemsRequest
, QueueSetPropertiesRequest, QueueUpdateItemsRequest } from "./shim/cast/media";
export interface ReceiverDevice {
host: string
@@ -31,13 +35,37 @@ export interface ReceiverStatus {
, 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: "STOP", sessionId: string }
| { type: "GET_STATUS" }
| { type: "GET_APP_AVAILABILITY", appId: string[] }
| {
type: "SET_VOLUME"
, volume: { level: number }
| { muted: boolean }
};
| { type: "SET_VOLUME", volume: Partial<Volume> };