mirror of
https://github.com/hensm/fx_cast.git
synced 2026-06-10 09:39:58 +00:00
Add media controls (#229)
This commit is contained in:
@@ -19,7 +19,8 @@ import {
|
||||
MediaStatus,
|
||||
ReceiverMediaMessage,
|
||||
SenderMediaMessage,
|
||||
SenderMessage
|
||||
SenderMessage,
|
||||
_MediaCommand
|
||||
} from "./types";
|
||||
|
||||
import { SessionStatus } from "./enums";
|
||||
@@ -29,16 +30,6 @@ import { MediaCommand } from "./media/enums";
|
||||
import { LoadRequest, QueueLoadRequest, QueueItem } from "./media/classes";
|
||||
import Media, { NS_MEDIA } from "./media/Media";
|
||||
|
||||
/** supportedMediaCommands bitflag returned in MEDIA_STATUS messages */
|
||||
enum _MediaCommand {
|
||||
PAUSE = 1,
|
||||
SEEK = 2,
|
||||
STREAM_VOLUME = 4,
|
||||
STREAM_MUTE = 8,
|
||||
QUEUE_NEXT = 64,
|
||||
QUEUE_PREV = 128
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a media object and a media status object and merges the status
|
||||
* with the existing media object, updating it with new properties.
|
||||
|
||||
@@ -15,16 +15,6 @@ import {
|
||||
UserAction
|
||||
} from "./enums";
|
||||
|
||||
export class AudiobookChapterMediaMetadata {
|
||||
bookTitle?: string;
|
||||
chapterNumber?: number;
|
||||
chapterTitle?: string;
|
||||
images?: Image[];
|
||||
subtitle?: string;
|
||||
title?: string;
|
||||
type = MetadataType.AUDIOBOOK_CHAPTER;
|
||||
}
|
||||
|
||||
export class AudiobookContainerMetadata {
|
||||
authors?: string[];
|
||||
narrators?: string[];
|
||||
@@ -71,7 +61,7 @@ export class BreakStatus {
|
||||
export class ContainerMetadata {
|
||||
containerDuration?: number;
|
||||
containerImages?: Image[];
|
||||
sections?: MediaMetadata[];
|
||||
sections?: Metadata[];
|
||||
title?: string;
|
||||
|
||||
constructor(
|
||||
@@ -88,16 +78,6 @@ export class EditTracksInfoRequest {
|
||||
) {}
|
||||
}
|
||||
|
||||
export class GenericMediaMetadata {
|
||||
images?: Image[];
|
||||
metadataType = MetadataType.GENERIC;
|
||||
releaseDate?: string;
|
||||
releaseYear?: number;
|
||||
subtitle?: string;
|
||||
title?: string;
|
||||
type = MetadataType.GENERIC;
|
||||
}
|
||||
|
||||
export class GetStatusRequest {
|
||||
customData: unknown = null;
|
||||
}
|
||||
@@ -129,6 +109,7 @@ export class LoadRequest {
|
||||
}
|
||||
|
||||
export type Metadata =
|
||||
| AudiobookChapterMediaMetadata
|
||||
| GenericMediaMetadata
|
||||
| MovieMediaMetadata
|
||||
| MusicTrackMediaMetadata
|
||||
@@ -156,33 +137,60 @@ export class MediaInfo {
|
||||
constructor(public contentId: string, public contentType: string) {}
|
||||
}
|
||||
|
||||
export class MediaMetadata {
|
||||
export abstract class MediaMetadata<T extends MetadataType> {
|
||||
queueItemId?: number;
|
||||
sectionDuration?: number;
|
||||
sectionStartAbsoluteTime?: number;
|
||||
sectionStartTimeInContainer?: number;
|
||||
sectionStartTimeInMedia?: number;
|
||||
type: MetadataType;
|
||||
metadataType: MetadataType;
|
||||
type: T;
|
||||
metadataType: T;
|
||||
|
||||
constructor(type: MetadataType) {
|
||||
constructor(type: T) {
|
||||
this.type = type;
|
||||
this.metadataType = type;
|
||||
}
|
||||
}
|
||||
|
||||
export class MovieMediaMetadata {
|
||||
export class AudiobookChapterMediaMetadata extends MediaMetadata<MetadataType.AUDIOBOOK_CHAPTER> {
|
||||
bookTitle?: string;
|
||||
chapterNumber?: number;
|
||||
chapterTitle?: string;
|
||||
images?: Image[];
|
||||
subtitle?: string;
|
||||
title?: string;
|
||||
|
||||
constructor() {
|
||||
super(MetadataType.AUDIOBOOK_CHAPTER);
|
||||
}
|
||||
}
|
||||
|
||||
export class GenericMediaMetadata extends MediaMetadata<MetadataType.GENERIC> {
|
||||
images?: Image[];
|
||||
releaseDate?: string;
|
||||
releaseYear?: number;
|
||||
subtitle?: string;
|
||||
title?: string;
|
||||
|
||||
constructor() {
|
||||
super(MetadataType.GENERIC);
|
||||
}
|
||||
}
|
||||
|
||||
export class MovieMediaMetadata extends MediaMetadata<MetadataType.MOVIE> {
|
||||
images?: Image[];
|
||||
metadataType = MetadataType.MOVIE;
|
||||
releaseDate?: string;
|
||||
releaseYear?: number;
|
||||
studio?: string;
|
||||
subtitle?: string;
|
||||
title?: string;
|
||||
type = MetadataType.MOVIE;
|
||||
|
||||
constructor() {
|
||||
super(MetadataType.MOVIE);
|
||||
}
|
||||
}
|
||||
|
||||
export class MusicTrackMediaMetadata {
|
||||
export class MusicTrackMediaMetadata extends MediaMetadata<MetadataType.MUSIC_TRACK> {
|
||||
albumArtist?: string;
|
||||
albumName?: string;
|
||||
artist?: string;
|
||||
@@ -190,20 +198,18 @@ export class MusicTrackMediaMetadata {
|
||||
composer?: string;
|
||||
discNumber?: number;
|
||||
images?: Image[];
|
||||
metadataType = MetadataType.MUSIC_TRACK;
|
||||
releaseDate?: string;
|
||||
releaseYear?: number;
|
||||
songName?: string;
|
||||
title?: string;
|
||||
trackNumber?: number;
|
||||
type = MetadataType.MUSIC_TRACK;
|
||||
|
||||
constructor() {
|
||||
super(MetadataType.MUSIC_TRACK);
|
||||
}
|
||||
}
|
||||
|
||||
export class PauseRequest {
|
||||
customData: unknown = null;
|
||||
}
|
||||
|
||||
export class PhotoMediaMetadata {
|
||||
export class PhotoMediaMetadata extends MediaMetadata<MetadataType.PHOTO> {
|
||||
artist?: string;
|
||||
creationDateTime?: string;
|
||||
height?: number;
|
||||
@@ -211,10 +217,33 @@ export class PhotoMediaMetadata {
|
||||
latitude?: number;
|
||||
location?: string;
|
||||
longitude?: number;
|
||||
metadataType = MetadataType.PHOTO;
|
||||
title?: string;
|
||||
type = MetadataType.PHOTO;
|
||||
width?: number;
|
||||
|
||||
constructor() {
|
||||
super(MetadataType.PHOTO);
|
||||
}
|
||||
}
|
||||
|
||||
export class TvShowMediaMetadata extends MediaMetadata<MetadataType.TV_SHOW> {
|
||||
episode?: number;
|
||||
episodeNumber?: number;
|
||||
episodeTitle?: string;
|
||||
images?: Image[];
|
||||
originalAirdate?: string;
|
||||
releaseYear?: number;
|
||||
season?: number;
|
||||
seasonNumber?: number;
|
||||
seriesTitle?: string;
|
||||
title?: string;
|
||||
|
||||
constructor() {
|
||||
super(MetadataType.TV_SHOW);
|
||||
}
|
||||
}
|
||||
|
||||
export class PauseRequest {
|
||||
customData: unknown = null;
|
||||
}
|
||||
|
||||
export class PlayRequest {
|
||||
@@ -339,21 +368,6 @@ export class Track {
|
||||
constructor(public trackId: number, public type: TrackType) {}
|
||||
}
|
||||
|
||||
export class TvShowMediaMetadata {
|
||||
episode?: number;
|
||||
episodeNumber?: number;
|
||||
episodeTitle?: string;
|
||||
images?: Image[];
|
||||
metadataType: number = MetadataType.TV_SHOW;
|
||||
originalAirdate?: string;
|
||||
releaseYear?: number;
|
||||
season?: number;
|
||||
seasonNumber?: number;
|
||||
seriesTitle?: string;
|
||||
title?: string;
|
||||
type = MetadataType.TV_SHOW;
|
||||
}
|
||||
|
||||
export class UserActionState {
|
||||
customData: unknown = null;
|
||||
|
||||
|
||||
@@ -15,15 +15,17 @@ import {
|
||||
} from "./media/enums";
|
||||
|
||||
export interface MediaStatus {
|
||||
activeTrackIds?: number[];
|
||||
currentItemId?: number;
|
||||
mediaSessionId: number;
|
||||
media?: MediaInfo;
|
||||
playbackRate: number;
|
||||
playerState: PlayerState;
|
||||
idleReason?: IdleReason;
|
||||
items?: QueueItem[];
|
||||
currentTime: number;
|
||||
currentTime: Nullable<number>;
|
||||
supportedMediaCommands: number;
|
||||
repeatMode: RepeatMode;
|
||||
repeatMode?: RepeatMode;
|
||||
volume: Volume;
|
||||
customData: unknown;
|
||||
}
|
||||
@@ -66,6 +68,23 @@ export interface CastSessionCreatedDetails extends CastSessionUpdatedDetails {
|
||||
transportId: string;
|
||||
}
|
||||
|
||||
/** supportedMediaCommands bitflag returned in MEDIA_STATUS messages */
|
||||
export enum _MediaCommand {
|
||||
PAUSE = 1,
|
||||
SEEK = 2,
|
||||
STREAM_VOLUME = 4,
|
||||
STREAM_MUTE = 8,
|
||||
QUEUE_NEXT = 64,
|
||||
QUEUE_PREV = 128,
|
||||
QUEUE_SHUFFLE = 256,
|
||||
QUEUE_SKIP_AD = 512,
|
||||
QUEUE_REPEAT_ALL = 1024,
|
||||
QUEUE_REPEAT_ONE = 2048,
|
||||
QUEUE_REPEAT = 3072,
|
||||
EDIT_TRACKS = 4096,
|
||||
PLAYBACK_RATE = 8192
|
||||
}
|
||||
|
||||
interface ReqBase {
|
||||
requestId: number;
|
||||
}
|
||||
@@ -91,77 +110,89 @@ interface MediaReqBase extends ReqBase {
|
||||
export type SenderMediaMessage =
|
||||
| (MediaReqBase & { type: "PLAY" })
|
||||
| (MediaReqBase & { type: "PAUSE" })
|
||||
| (MediaReqBase & { type: "MEDIA_GET_STATUS" })
|
||||
| {
|
||||
type: "MEDIA_GET_STATUS";
|
||||
mediaSessionId?: number;
|
||||
customData?: unknown;
|
||||
requestId: number;
|
||||
}
|
||||
| {
|
||||
type: "GET_STATUS";
|
||||
mediaSessionId?: number;
|
||||
customData?: unknown;
|
||||
requestId: number;
|
||||
}
|
||||
| (MediaReqBase & { type: "STOP" })
|
||||
| (MediaReqBase & { type: "MEDIA_SET_VOLUME"; volume: Partial<Volume> })
|
||||
| (MediaReqBase & { type: "MEDIA_SET_VOLUME"; volume: Volume })
|
||||
| (MediaReqBase & { type: "SET_VOLUME"; volume: Volume })
|
||||
| (MediaReqBase & { type: "SET_PLAYBACK_RATE"; playbackRate: number })
|
||||
| (ReqBase & {
|
||||
type: "LOAD";
|
||||
activeTrackIds: Nullable<number[]>;
|
||||
activeTrackIds?: Nullable<number[]>;
|
||||
atvCredentials?: string;
|
||||
atvCredentialsType?: string;
|
||||
autoplay: Nullable<boolean>;
|
||||
currentTime: Nullable<number>;
|
||||
autoplay?: Nullable<boolean>;
|
||||
currentTime?: Nullable<number>;
|
||||
customData?: unknown;
|
||||
media: MediaInfo;
|
||||
sessionId: Nullable<string>;
|
||||
sessionId?: Nullable<string>;
|
||||
})
|
||||
| (MediaReqBase & {
|
||||
type: "SEEK";
|
||||
resumeState: Nullable<ResumeState>;
|
||||
currentTime: Nullable<number>;
|
||||
resumeState?: Nullable<ResumeState>;
|
||||
currentTime?: Nullable<number>;
|
||||
})
|
||||
| (MediaReqBase & {
|
||||
type: "EDIT_TRACKS_INFO";
|
||||
activeTrackIds: Nullable<number[]>;
|
||||
textTrackStyle: Nullable<string>;
|
||||
activeTrackIds?: Nullable<number[]>;
|
||||
textTrackStyle?: Nullable<string>;
|
||||
})
|
||||
// QueueLoadRequest
|
||||
| (ReqBase & {
|
||||
| (MediaReqBase & {
|
||||
type: "QUEUE_LOAD";
|
||||
items: QueueItem[];
|
||||
startIndex: number;
|
||||
repeatMode: string;
|
||||
sessionId: Nullable<string>;
|
||||
sessionId?: Nullable<string>;
|
||||
})
|
||||
// QueueInsertItemsRequest
|
||||
| (MediaReqBase & {
|
||||
type: "QUEUE_INSERT";
|
||||
items: QueueItem[];
|
||||
insertBefore: Nullable<number>;
|
||||
sessionId: Nullable<string>;
|
||||
insertBefore?: Nullable<number>;
|
||||
sessionId?: Nullable<string>;
|
||||
})
|
||||
// QueueUpdateItemsRequest
|
||||
| (MediaReqBase & {
|
||||
type: "QUEUE_UPDATE";
|
||||
items: QueueItem[];
|
||||
sessionId: Nullable<string>;
|
||||
sessionId?: Nullable<string>;
|
||||
})
|
||||
// QueueJumpRequest
|
||||
| (MediaReqBase & {
|
||||
type: "QUEUE_UPDATE";
|
||||
jump: Nullable<number>;
|
||||
currentItemId: Nullable<number>;
|
||||
sessionId: Nullable<string>;
|
||||
jump?: Nullable<number>;
|
||||
currentItemId?: Nullable<number>;
|
||||
sessionId?: Nullable<string>;
|
||||
})
|
||||
// QueueRemoveItemsRequest
|
||||
| (MediaReqBase & {
|
||||
type: "QUEUE_REMOVE";
|
||||
itemIds: number[];
|
||||
sessionId: Nullable<string>;
|
||||
sessionId?: Nullable<string>;
|
||||
})
|
||||
// QueueReorderItemsRequest
|
||||
| (MediaReqBase & {
|
||||
type: "QUEUE_REORDER";
|
||||
itemIds: number[];
|
||||
insertBefore: Nullable<number>;
|
||||
sessionId: Nullable<string>;
|
||||
insertBefore?: Nullable<number>;
|
||||
sessionId?: Nullable<string>;
|
||||
})
|
||||
// QueueSetPropertiesRequest
|
||||
| (MediaReqBase & {
|
||||
type: "QUEUE_UPDATE";
|
||||
repeatMode: Nullable<string>;
|
||||
sessionId: Nullable<string>;
|
||||
repeatMode?: Nullable<string>;
|
||||
sessionId?: Nullable<string>;
|
||||
});
|
||||
|
||||
export type ReceiverMediaMessage =
|
||||
|
||||
Reference in New Issue
Block a user