Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement ykb tnye fixes #465

Merged
merged 37 commits into from
Sep 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
5f96fe0
use window width instead because HLS is strict
hawken93 Dec 31, 2020
114aab7
Fix start seek
hawken93 Dec 21, 2020
18b3db2
add event listeners for start/stop reporting where the player probabl…
hawken93 Dec 21, 2020
a76e8b8
fix stream change
hawken93 Dec 25, 2020
94aba9c
fix playerManager.stop -> onStopped to avoid telling the cast to stop…
hawken93 Dec 25, 2020
921467a
getMaxBitrate: Always cap to device max bitrate
hawken93 Dec 29, 2020
482cf58
try to get more accurate bitrate
hawken93 Dec 29, 2020
4f17065
refactor window.playlist into playbackmanager and make playbackmanage…
hawken93 Jan 1, 2021
c8b1b15
try to fix the startIndex issue
hawken93 Jan 4, 2021
f613aee
fix bug when client reconnects and chromecast is in details page
hawken93 Jan 14, 2021
3bb63c3
Merge remote-tracking branch 'source/master' into misc-fixes
tnyeanderson Mar 24, 2022
019bb8c
fix errors from merge
tnyeanderson Mar 24, 2022
23597e2
make appstatus an enum
tnyeanderson Mar 24, 2022
166b950
fix case for enum
tnyeanderson Mar 24, 2022
6cb8f0d
remove TODO statement
tnyeanderson Mar 24, 2022
323983a
hopefully fix buffering bug
tnyeanderson Mar 24, 2022
ffebe17
add ticksToSeconds function
tnyeanderson Mar 24, 2022
308cc23
fix null exception
tnyeanderson Mar 24, 2022
3fc8967
onStopped -> onStop
tnyeanderson Mar 24, 2022
8732560
use RepeatMode enum
tnyeanderson Mar 24, 2022
12d2ae3
isHlsStream function
tnyeanderson Mar 24, 2022
4444777
Fix some github actions lint errors
tnyeanderson Mar 24, 2022
9e668e1
try to fix hls width issue
tnyeanderson Mar 25, 2022
1e24419
Merge remote-tracking branch 'upstream/master' into misc-fixes-tnye-m…
YouKnowBlom Dec 20, 2022
3106926
Update old mentions of playbackMgr
YouKnowBlom Dec 20, 2022
7fb0fd6
Update old mentions of $scope
YouKnowBlom Dec 20, 2022
625171d
Fix webpack failing to resolve global types and generated api
YouKnowBlom Dec 20, 2022
df9404b
Merge branch 'misc-fixes-tnye-merge' into implement-ykb-tnye-fixes
Sky-High Sep 25, 2023
edbd063
pacify es-lint 1
Sky-High Sep 25, 2023
a909ba9
pacify es-lint 2
Sky-High Sep 25, 2023
db5eb70
continued pacification of es-lint
Sky-High Sep 25, 2023
9d50636
Merge branch 'jellyfin:master' into implement-ykb-tnye-fixes
Sky-High Sep 25, 2023
5a33f3a
Merge branch 'jellyfin:master' into implement-ykb-tnye-fixes
Sky-High Sep 25, 2023
41ec7e4
Merge branch 'jellyfin:master' into implement-ykb-tnye-fixes
Sky-High Sep 25, 2023
c9bc767
Merge branch 'jellyfin:master' into implement-ykb-tnye-fixes
Sky-High Sep 25, 2023
1e089c3
Merge branch 'jellyfin:master' into implement-ykb-tnye-fixes
Sky-High Sep 26, 2023
6d3980a
revert unintended changes to package.json
Sky-High Sep 26, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,4 @@ import './css/jellyfin.css';

window.mediaElement = document.getElementById('video-player');

window.playlist = [];
window.currentPlaylistIndex = -1;
window.repeatMode = RepeatMode.RepeatNone;
4 changes: 2 additions & 2 deletions src/components/__tests__/jellyfinApi.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { JellyfinApi } from '../jellyfinApi';

const setupMockCastSenders = (): void => {
const getSenders = (): Array<any> => [{ id: 'thisIsSenderId' }];
const getInstance = (): any => ({ getSenders });
const getSenders = (): Array<any> => [{ id: 'thisIsSenderId' }]; // eslint-disable-line @typescript-eslint/no-explicit-any
const getInstance = (): any => ({ getSenders }); // eslint-disable-line @typescript-eslint/no-explicit-any

// @ts-expect-error cast is already defined globally, however since we're mocking it we need to redefine it.
global.cast = {
Expand Down
13 changes: 12 additions & 1 deletion src/components/codecSupportHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,20 @@ export function getMaxBitrateSupport(): number {
/**
* Get the max supported video width the active Cast device supports.
* @param deviceId - Cast device id.
* @param codec - Video codec.
* @returns Max supported width.
*/
export function getMaxWidthSupport(deviceId: number): number {
export function getMaxWidthSupport(deviceId: number, codec?: string): number {
if (codec === 'h264') {
// with HLS, it will produce a manifest error if we
// send any stream larger than the screen size...
return window.innerWidth;
}

// mkv playback can use the device limitations.
// The devices are capable of decoding and downscaling,
// they just refuse to do it with HLS. This increases
// the rate of direct playback.
switch (deviceId) {
case deviceIds.ULTRA:
case deviceIds.CCGTV:
Expand Down
48 changes: 21 additions & 27 deletions src/components/commandHandler.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { getReportingParams } from '../helpers';
import {
import { getReportingParams, TicksPerSecond } from '../helpers';
import type {
DataMessage,
DisplayRequest,
PlayRequest,
Expand All @@ -8,6 +8,7 @@ import {
SetRepeatModeRequest,
SupportedCommands
} from '../types/global';
import { AppStatus } from '../types/appStatus';
import {
translateItems,
shuffle,
Expand All @@ -16,16 +17,12 @@ import {
setSubtitleStreamIndex,
seek
} from './maincontroller';

import { reportPlaybackProgress } from './jellyfinActions';

import { playbackManager } from './playbackManager';

import { PlaybackManager } from './playbackManager';
import { DocumentManager } from './documentManager';

export abstract class CommandHandler {
private static playerManager: framework.PlayerManager;
private static playbackManager: playbackManager;
private static supportedCommands: SupportedCommands = {
DisplayContent: CommandHandler.displayContentHandler,
Identify: CommandHandler.IdentifyHandler,
Expand All @@ -52,12 +49,8 @@ export abstract class CommandHandler {
VolumeUp: CommandHandler.VolumeUpHandler
};

static configure(
playerManager: framework.PlayerManager,
playbackManager: playbackManager
): void {
static configure(playerManager: framework.PlayerManager): void {
this.playerManager = playerManager;
this.playbackManager = playbackManager;
}

static playNextHandler(data: DataMessage): void {
Expand Down Expand Up @@ -89,36 +82,33 @@ export abstract class CommandHandler {
}

static displayContentHandler(data: DataMessage): void {
if (!this.playbackManager.isPlaying()) {
if (!PlaybackManager.isPlaying()) {
DocumentManager.showItemId((<DisplayRequest>data.options).ItemId);
}
}

static nextTrackHandler(): void {
if (
window.playlist &&
window.currentPlaylistIndex < window.playlist.length - 1
) {
this.playbackManager.playNextItem({}, true);
if (PlaybackManager.hasNextItem()) {
PlaybackManager.playNextItem({}, true);
}
}

static previousTrackHandler(): void {
if (window.playlist && window.currentPlaylistIndex > 0) {
this.playbackManager.playPreviousItem({});
if (PlaybackManager.hasPrevItem()) {
PlaybackManager.playPreviousItem({});
}
}

static setAudioStreamIndexHandler(data: DataMessage): void {
setAudioStreamIndex(
this.playbackManager.playbackState,
PlaybackManager.playbackState,
(<SetIndexRequest>data.options).index
);
}

static setSubtitleStreamIndexHandler(data: DataMessage): void {
setSubtitleStreamIndex(
this.playbackManager.playbackState,
PlaybackManager.playbackState,
(<SetIndexRequest>data.options).index
);
}
Expand All @@ -144,13 +134,17 @@ export abstract class CommandHandler {
}

static IdentifyHandler(): void {
if (!this.playbackManager.isPlaying()) {
if (!PlaybackManager.isPlaying()) {
if (!PlaybackManager.isBuffering()) {
DocumentManager.setAppStatus(AppStatus.Waiting);
}

DocumentManager.startBackdropInterval();
} else {
// When a client connects send back the initial device state (volume etc) via a playbackstop message
reportPlaybackProgress(
this.playbackManager.playbackState,
getReportingParams(this.playbackManager.playbackState),
PlaybackManager.playbackState,
getReportingParams(PlaybackManager.playbackState),
true,
'playbackstop'
);
Expand All @@ -159,8 +153,8 @@ export abstract class CommandHandler {

static SeekHandler(data: DataMessage): void {
seek(
this.playbackManager.playbackState,
(<SeekRequest>data.options).position * 10000000
PlaybackManager.playbackState,
(<SeekRequest>data.options).position * TicksPerSecond
);
}

Expand Down
12 changes: 10 additions & 2 deletions src/components/deviceprofileBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ let profileOptions: ProfileOptions;
let currentDeviceId: number;

/**
* Create and return a new ProfileCondition
* @param Property - What property the condition should test.
* @param Condition - The condition to test the values for.
* @param Value - The value to compare against.
Expand All @@ -66,13 +67,16 @@ function createProfileCondition(
}

/**
* Get container profiles
* @todo Why does this always return an empty array?
* @returns Container profiles.
*/
function getContainerProfiles(): Array<ContainerProfile> {
return [];
}

/**
* Get response profiles
* @returns Response profiles.
*/
function getResponseProfiles(): Array<ResponseProfile> {
Expand All @@ -87,6 +91,7 @@ function getResponseProfiles(): Array<ResponseProfile> {
}

/**
* Get direct play profiles
* @returns Direct play profiles.
*/
function getDirectPlayProfiles(): Array<DirectPlayProfile> {
Expand Down Expand Up @@ -150,6 +155,7 @@ function getDirectPlayProfiles(): Array<DirectPlayProfile> {
}

/**
* Get codec profiles
* @returns Codec profiles.
*/
function getCodecProfiles(): Array<CodecProfile> {
Expand Down Expand Up @@ -224,7 +230,7 @@ function getCodecProfiles(): Array<CodecProfile> {
createProfileCondition(
ProfileConditionValue.Width,
ProfileConditionType.LessThanEqual,
maxWidth.toString(),
getMaxWidthSupport(currentDeviceId, 'h264').toString(),
true
)
],
Expand Down Expand Up @@ -271,7 +277,7 @@ function getCodecProfiles(): Array<CodecProfile> {
createProfileCondition(
ProfileConditionValue.Width,
ProfileConditionType.LessThanEqual,
maxWidth.toString(),
getMaxWidthSupport(currentDeviceId).toString(),
true
)
],
Expand All @@ -297,6 +303,7 @@ function getCodecProfiles(): Array<CodecProfile> {
}

/**
* Get transcoding profiles
* @returns Transcoding profiles.
*/
function getTranscodingProfiles(): Array<TranscodingProfile> {
Expand Down Expand Up @@ -375,6 +382,7 @@ function getTranscodingProfiles(): Array<TranscodingProfile> {
}

/**
* Get subtitle profiles
* @returns Subtitle profiles.
*/
function getSubtitleProfiles(): Array<SubtitleProfile> {
Expand Down
36 changes: 16 additions & 20 deletions src/components/documentManager.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
import type { BaseItemDto } from '@jellyfin/sdk/lib/generated-client';

import { parseISO8601Date } from '../helpers';
import { AppStatus } from '../types/appStatus';
import { parseISO8601Date, TicksPerSecond, ticksToSeconds } from '../helpers';
import { JellyfinApi } from './jellyfinApi';
import { deviceIds, getActiveDeviceId } from './castDevices';

export abstract class DocumentManager {
// Duration between each backdrop switch in ms
private static backdropPeriodMs: number | null = 30000;
// Timer state - so that we don't start the interval more than necessary
private static backdropTimer = 0;
private static backdropTimer: NodeJS.Timer | null = null;

// TODO make enum
private static status = '';
private static status = AppStatus.Unset;

/**
* Hide the document body on chromecast audio to save resources
Expand Down Expand Up @@ -181,7 +180,7 @@ export abstract class DocumentManager {
}

// Switch visible view!
this.setAppStatus('details');
this.setAppStatus(AppStatus.Details);
});
}

Expand Down Expand Up @@ -277,7 +276,7 @@ export abstract class DocumentManager {
* to the corresponding one.
* @param status - to set
*/
public static setAppStatus(status: string): void {
public static setAppStatus(status: AppStatus): void {
this.status = status;
document.body.className = status;
}
Expand All @@ -286,7 +285,7 @@ export abstract class DocumentManager {
* Get the status of the app
* @returns app status
*/
public static getAppStatus(): string {
public static getAppStatus(): AppStatus {
return this.status;
}

Expand Down Expand Up @@ -390,9 +389,9 @@ export abstract class DocumentManager {
* Stop the backdrop rotation
*/
public static clearBackdropInterval(): void {
if (this.backdropTimer !== 0) {
if (this.backdropTimer !== null) {
clearInterval(this.backdropTimer);
this.backdropTimer = 0;
this.backdropTimer = null;
}
}

Expand All @@ -416,11 +415,9 @@ export abstract class DocumentManager {
return;
}

this.backdropTimer = <any>(
setInterval(
() => DocumentManager.setRandomUserBackdrop(),
this.backdropPeriodMs
)
this.backdropTimer = setInterval(
() => DocumentManager.setRandomUserBackdrop(),
this.backdropPeriodMs
);

await this.setRandomUserBackdrop();
Expand All @@ -435,7 +432,7 @@ export abstract class DocumentManager {
this.backdropPeriodMs = period;

// If the timer was running, restart it
if (this.backdropTimer !== 0) {
if (this.backdropTimer !== null) {
// startBackdropInterval will also clear the previous one
this.startBackdropInterval();
}
Expand Down Expand Up @@ -605,9 +602,8 @@ export abstract class DocumentManager {
* @returns human readable position
*/
private static formatRunningTime(ticks: number): string {
const ticksPerHour = 36000000000;
const ticksPerMinute = 600000000;
const ticksPerSecond = 10000000;
const ticksPerMinute = TicksPerSecond * 60;
const ticksPerHour = ticksPerMinute * 60;

const parts: string[] = [];

Expand All @@ -629,7 +625,7 @@ export abstract class DocumentManager {
parts.push(minutes.toString());
}

const seconds: number = Math.floor(ticks / ticksPerSecond);
const seconds: number = Math.floor(ticksToSeconds(ticks));

if (seconds < 10) {
parts.push(`0${seconds.toString()}`);
Expand Down
2 changes: 2 additions & 0 deletions src/components/fetchhelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* @param request - Custom request object, mostly modeled after RequestInit.
* @returns response promise
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function getFetchPromise(request: any): Promise<Response> {
const headers = request.headers || {};

Expand Down Expand Up @@ -102,6 +103,7 @@ function paramsToString(params: Record<string, string>): string {
* @param request - RequestInit-like structure but with url/type/timeout parameters as well
* @returns response promise, may be automatically unpacked based on request datatype
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export async function ajax(request: any): Promise<Response | string> {
if (!request) {
throw new Error('Request cannot be null');
Expand Down
Loading