mirror of
https://github.com/jellyfin/jellyfin-chromecast.git
synced 2024-11-26 15:50:32 +00:00
commit
8b309917c8
@ -232,9 +232,9 @@ export async function getPlaybackInfo(
|
||||
maxBitrate: number,
|
||||
deviceProfile: DeviceProfile,
|
||||
startPosition: number,
|
||||
mediaSourceId: string,
|
||||
audioStreamIndex: number,
|
||||
subtitleStreamIndex: number,
|
||||
mediaSourceId: string | null,
|
||||
audioStreamIndex: number | null,
|
||||
subtitleStreamIndex: number | null,
|
||||
liveStreamId: string | null = null
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
): Promise<any> {
|
||||
|
@ -28,7 +28,7 @@ import { JellyfinApi } from './jellyfinApi';
|
||||
import { PlaybackManager, PlaybackState } from './playbackManager';
|
||||
import { CommandHandler } from './commandHandler';
|
||||
import { getMaxBitrateSupport } from './codecSupportHelper';
|
||||
import { PlayRequest } from '~/types/global';
|
||||
import { PlayRequest, StreamInfo } from '~/types/global';
|
||||
|
||||
window.castReceiverContext = cast.framework.CastReceiverContext.getInstance();
|
||||
window.playerManager = window.castReceiverContext.getPlayerManager();
|
||||
@ -808,7 +808,6 @@ export function setTextTrack(index: number | null): void {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO no any types
|
||||
/**
|
||||
* createMediaInformation
|
||||
* @param playSessionId - playSessionId
|
||||
@ -819,8 +818,7 @@ export function setTextTrack(index: number | null): void {
|
||||
export function createMediaInformation(
|
||||
playSessionId: string,
|
||||
item: BaseItemDto,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
streamInfo: any
|
||||
streamInfo: StreamInfo
|
||||
): framework.messages.MediaInformation {
|
||||
const mediaInfo = new cast.framework.messages.MediaInformation();
|
||||
|
||||
@ -831,12 +829,12 @@ export function createMediaInformation(
|
||||
canClientSeek: streamInfo.canClientSeek,
|
||||
canSeek: streamInfo.canSeek,
|
||||
itemId: item.Id,
|
||||
liveStreamId: streamInfo.mediaSource.LiveStreamId,
|
||||
mediaSourceId: streamInfo.mediaSource.Id,
|
||||
liveStreamId: streamInfo.mediaSource?.LiveStreamId ?? null,
|
||||
mediaSourceId: streamInfo.mediaSource?.Id ?? null,
|
||||
playMethod: streamInfo.isStatic ? 'DirectStream' : 'Transcode',
|
||||
playSessionId: playSessionId,
|
||||
runtimeTicks: streamInfo.mediaSource.RunTimeTicks,
|
||||
startPositionTicks: streamInfo.startPositionTicks || 0,
|
||||
runtimeTicks: streamInfo.mediaSource?.RunTimeTicks ?? null,
|
||||
startPositionTicks: streamInfo.startPositionTicks ?? 0,
|
||||
subtitleStreamIndex: streamInfo.subtitleStreamIndex
|
||||
};
|
||||
|
||||
@ -845,7 +843,7 @@ export function createMediaInformation(
|
||||
mediaInfo.streamType = cast.framework.messages.StreamType.BUFFERED;
|
||||
mediaInfo.tracks = streamInfo.tracks;
|
||||
|
||||
if (streamInfo.mediaSource.RunTimeTicks) {
|
||||
if (streamInfo.mediaSource?.RunTimeTicks) {
|
||||
mediaInfo.duration = Math.floor(
|
||||
ticksToSeconds(streamInfo.mediaSource.RunTimeTicks)
|
||||
);
|
||||
|
@ -4,6 +4,7 @@ import type {
|
||||
PlayMethod
|
||||
} from '@jellyfin/sdk/lib/generated-client';
|
||||
import { RepeatMode } from '@jellyfin/sdk/lib/generated-client';
|
||||
import { MediaInformationCustomData } from 'chromecast-caf-receiver/cast.framework.messages';
|
||||
import { AppStatus } from '../types/appStatus';
|
||||
import {
|
||||
broadcastConnectionErrorMessage,
|
||||
@ -33,7 +34,7 @@ export interface PlaybackState {
|
||||
mediaType: string | null | undefined;
|
||||
itemId: string;
|
||||
|
||||
audioStreamIndex: null;
|
||||
audioStreamIndex: number | null;
|
||||
subtitleStreamIndex: number | null;
|
||||
mediaSource: MediaSourceInfo | null;
|
||||
mediaSourceId: string;
|
||||
@ -199,7 +200,7 @@ export abstract class PlaybackManager {
|
||||
// Would set private, but some refactorings need to happen first.
|
||||
static async playItemInternal(
|
||||
item: BaseItemDto,
|
||||
options: any // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||
options: MediaInformationCustomData
|
||||
): Promise<void> {
|
||||
DocumentManager.setAppStatus(AppStatus.Loading);
|
||||
|
||||
|
@ -22,7 +22,7 @@ import {
|
||||
} from '@jellyfin/sdk/lib/utils/api';
|
||||
import { JellyfinApi } from './components/jellyfinApi';
|
||||
import { PlaybackManager, PlaybackState } from './components/playbackManager';
|
||||
import { BusMessage } from './types/global';
|
||||
import { BusMessage, StreamInfo } from './types/global';
|
||||
|
||||
type InstantMixApiRequest =
|
||||
| InstantMixApiGetInstantMixFromAlbumRequest
|
||||
@ -309,8 +309,7 @@ export function createStreamInfo(
|
||||
item: BaseItemDto,
|
||||
mediaSource: MediaSourceInfo,
|
||||
startPosition: number | null
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
): any {
|
||||
): StreamInfo {
|
||||
let mediaUrl;
|
||||
let contentType;
|
||||
|
||||
@ -332,7 +331,7 @@ export function createStreamInfo(
|
||||
if (type == 'video') {
|
||||
contentType = `video/${mediaSource.Container}`;
|
||||
|
||||
if (mediaSource.SupportsDirectPlay) {
|
||||
if (mediaSource.SupportsDirectPlay && mediaSource.Path) {
|
||||
mediaUrl = mediaSource.Path;
|
||||
isStatic = true;
|
||||
} else if (mediaSource.SupportsDirectStream) {
|
||||
@ -363,7 +362,7 @@ export function createStreamInfo(
|
||||
} else {
|
||||
contentType = `audio/${mediaSource.Container}`;
|
||||
|
||||
if (mediaSource.SupportsDirectPlay) {
|
||||
if (mediaSource.SupportsDirectPlay && mediaSource.Path) {
|
||||
mediaUrl = mediaSource.Path;
|
||||
isStatic = true;
|
||||
playerStartPositionTicks = startPosition ?? 0;
|
||||
@ -394,9 +393,8 @@ export function createStreamInfo(
|
||||
// It is a pain and will require unbinding all event handlers during the operation
|
||||
const canSeek = (mediaSource.RunTimeTicks ?? 0) > 0;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const info: any = {
|
||||
audioStreamIndex: mediaSource.DefaultAudioStreamIndex,
|
||||
const info: StreamInfo = {
|
||||
audioStreamIndex: mediaSource.DefaultAudioStreamIndex ?? null,
|
||||
canClientSeek: isStatic || (canSeek && streamContainer == 'm3u8'),
|
||||
canSeek: canSeek,
|
||||
contentType: contentType,
|
||||
@ -405,7 +403,7 @@ export function createStreamInfo(
|
||||
playerStartPositionTicks: playerStartPositionTicks,
|
||||
startPositionTicks: startPosition,
|
||||
streamContainer: streamContainer,
|
||||
subtitleStreamIndex: mediaSource.DefaultSubtitleStreamIndex,
|
||||
subtitleStreamIndex: mediaSource.DefaultSubtitleStreamIndex ?? null,
|
||||
url: mediaUrl
|
||||
};
|
||||
|
||||
@ -431,6 +429,10 @@ export function createStreamInfo(
|
||||
? subtitleStream.DeliveryUrl
|
||||
: JellyfinApi.createUrl(subtitleStream.DeliveryUrl);
|
||||
|
||||
if (!info.subtitleStreamIndex) {
|
||||
return;
|
||||
}
|
||||
|
||||
const track = new cast.framework.messages.Track(
|
||||
info.subtitleStreamIndex,
|
||||
cast.framework.messages.TrackType.TEXT
|
||||
|
32
src/types/global.d.ts
vendored
32
src/types/global.d.ts
vendored
@ -5,9 +5,13 @@ import {
|
||||
import { SystemVolumeData } from 'chromecast-caf-receiver/cast.framework.system';
|
||||
import type {
|
||||
BaseItemDto,
|
||||
MediaSourceInfo,
|
||||
RepeatMode
|
||||
} from '@jellyfin/sdk/lib/generated-client';
|
||||
import { TextTrackEdgeType } from 'chromecast-caf-receiver/cast.framework.messages';
|
||||
import type {
|
||||
TextTrackEdgeType,
|
||||
Track
|
||||
} from 'chromecast-caf-receiver/cast.framework.messages';
|
||||
|
||||
// Messagebus message
|
||||
export interface BusMessage {
|
||||
@ -70,6 +74,22 @@ interface SubtitleAppearance {
|
||||
textSize: 'smaller' | 'small' | 'large' | 'larger' | 'extralarge';
|
||||
}
|
||||
|
||||
interface StreamInfo {
|
||||
tracks?: Track[];
|
||||
audioStreamIndex: number | null;
|
||||
canClientSeek: boolean;
|
||||
canSeek: boolean;
|
||||
contentType: string;
|
||||
isStatic: boolean;
|
||||
mediaSource?: MediaSourceInfo;
|
||||
playerStartPositionTicks?: number;
|
||||
startPositionTicks: number | null;
|
||||
streamContainer?: string | null;
|
||||
subtitleStreamIndex: number | null;
|
||||
subtitleStreamUrl?: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
declare global {
|
||||
export interface Window {
|
||||
mediaElement: HTMLElement | null;
|
||||
@ -86,16 +106,16 @@ declare global {
|
||||
|
||||
declare module 'chromecast-caf-receiver/cast.framework.messages' {
|
||||
interface MediaInformationCustomData {
|
||||
audioStreamIndex: string;
|
||||
audioStreamIndex: number | null;
|
||||
canClientSeek: boolean;
|
||||
canSeek: boolean;
|
||||
itemId: string | undefined;
|
||||
liveStreamId: number;
|
||||
mediaSourceId: number;
|
||||
liveStreamId: string | null;
|
||||
mediaSourceId: string | null;
|
||||
playMethod: 'DirectStream' | 'Transcode';
|
||||
playSessionId: string;
|
||||
runtimeTicks: number;
|
||||
runtimeTicks: number | null;
|
||||
startPositionTicks: number;
|
||||
subtitleStreamIndex: number;
|
||||
subtitleStreamIndex: number | null;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user