Skip to content

Commit

Permalink
Merge pull request #701 from 3flex/add-streaminfo
Browse files Browse the repository at this point in the history
Add StreamInfo type
  • Loading branch information
nielsvanvelzen authored Nov 11, 2024
2 parents 745dc16 + 0e35f1d commit 8b30991
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 29 deletions.
6 changes: 3 additions & 3 deletions src/components/jellyfinActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand Down
16 changes: 7 additions & 9 deletions src/components/maincontroller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -808,7 +808,6 @@ export function setTextTrack(index: number | null): void {
}
}

// TODO no any types
/**
* createMediaInformation
* @param playSessionId - playSessionId
Expand All @@ -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();

Expand All @@ -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
};

Expand All @@ -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)
);
Expand Down
5 changes: 3 additions & 2 deletions src/components/playbackManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);

Expand Down
20 changes: 11 additions & 9 deletions src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;

Expand All @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand All @@ -405,7 +403,7 @@ export function createStreamInfo(
playerStartPositionTicks: playerStartPositionTicks,
startPositionTicks: startPosition,
streamContainer: streamContainer,
subtitleStreamIndex: mediaSource.DefaultSubtitleStreamIndex,
subtitleStreamIndex: mediaSource.DefaultSubtitleStreamIndex ?? null,
url: mediaUrl
};

Expand All @@ -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
Expand Down
32 changes: 26 additions & 6 deletions src/types/global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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;
Expand All @@ -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;
}
}

0 comments on commit 8b30991

Please sign in to comment.