Adjust video position (#583)

This commit is contained in:
redphx
2024-12-06 21:42:18 +07:00
parent 4777f90a53
commit fe98a1165f
11 changed files with 160 additions and 43 deletions

View File

@@ -47,7 +47,39 @@ body[data-media-type=tv] .bx-stream-home-button {
}
div[data-testid=media-container] {
display: flex;
&[data-position=center] {
display: flex;
}
&[data-position=top] {
video, canvas {
top: 0;
}
}
&[data-position=bottom] {
video, canvas {
bottom: 0;
}
}
}
#game-stream {
video {
margin: auto;
align-self: center;
background: #000;
position: absolute;
}
canvas {
position: absolute;
align-self: center;
margin: auto;
left: 0;
right: 0;
}
&.bx-taking-screenshot:before {
animation: bx-anim-taking-screenshot 0.5s ease;
@@ -59,21 +91,6 @@ div[data-testid=media-container] {
}
}
#game-stream video {
margin: auto;
align-self: center;
background: #000;
}
#game-stream canvas {
position: absolute;
align-self: center;
margin: auto;
left: 0;
right: 0;
}
#gamepass-dialog-root div[class^=Guide-module__guide] {
.bx-button {
overflow: visible;

View File

@@ -93,6 +93,7 @@ export const enum PrefKey {
VIDEO_BRIGHTNESS = 'video.brightness',
VIDEO_CONTRAST = 'video.contrast',
VIDEO_SATURATION = 'video.saturation',
VIDEO_POSITION = 'video.position',
AUDIO_MIC_ON_PLAYING = 'audio.mic.onPlaying',
AUDIO_VOLUME_CONTROL_ENABLED = 'audio.volume.booster.enabled',

View File

@@ -93,6 +93,14 @@ export const enum VideoRatio {
FILL = 'fill',
}
export const enum VideoPosition {
CENTER = 'center',
TOP = 'top',
TOP_HALF = 'top-half',
BOTTOM = 'bottom',
BOTTOM_HALF = 'bottom-half',
}
export const enum StreamPlayerType {
VIDEO = 'default',
WEBGL2 = 'webgl2',

View File

@@ -7,7 +7,7 @@ import { STATES } from "@/utils/global";
import { PrefKey } from "@/enums/pref-keys";
import { getPref } from "@/utils/settings-storages/global-settings-storage";
import { BX_FLAGS } from "@/utils/bx-flags";
import { StreamPlayerType, StreamVideoProcessing, VideoRatio } from "@/enums/pref-values";
import { StreamPlayerType, StreamVideoProcessing, VideoPosition, VideoRatio } from "@/enums/pref-values";
export type StreamPlayerOptions = Partial<{
processing: string,
@@ -39,13 +39,12 @@ export class StreamPlayer {
private setupVideoElements() {
this.$videoCss = document.getElementById('bx-video-css') as HTMLStyleElement;
if (this.$videoCss) {
this.$usmMatrix = this.$videoCss.querySelector('#bx-filter-usm-matrix') as any;
return;
}
const $fragment = document.createDocumentFragment();
this.$videoCss = CE<HTMLStyleElement>('style', {id: 'bx-video-css'});
this.$videoCss = CE<HTMLStyleElement>('style', { id: 'bx-video-css' });
$fragment.appendChild(this.$videoCss);
// Setup SVG filters
@@ -141,6 +140,23 @@ export class StreamPlayer {
$video.dataset.width = width.toString();
$video.dataset.height = height.toString();
// Set position
const $parent = $video.parentElement!;
const position = getPref<VideoPosition>(PrefKey.VIDEO_POSITION);
$parent.style.removeProperty('padding-top');
$parent.dataset.position = position;
if (position === VideoPosition.TOP_HALF || position === VideoPosition.BOTTOM_HALF) {
let padding = Math.floor((window.innerHeight - height) / 4);
if (padding > 0) {
if (position === VideoPosition.BOTTOM_HALF) {
padding *= 3;
}
$parent.style.paddingTop = padding + 'px';
}
}
// Update size
targetWidth = `${width}px`;
targetHeight = `${height}px`;

View File

@@ -71,7 +71,6 @@ export function updateVideoPlayer() {
streamPlayer.setPlayerType(getPref(PrefKey.VIDEO_PLAYER_TYPE));
streamPlayer.updateOptions(options);
streamPlayer.refreshPlayer();
}
window.addEventListener('resize', updateVideoPlayer);

View File

@@ -475,6 +475,9 @@ export class SettingsDialog extends NavigationDialog {
}, {
pref: PrefKey.VIDEO_RATIO,
onChange: updateVideoPlayer,
}, {
pref: PrefKey.VIDEO_POSITION,
onChange: updateVideoPlayer,
}, {
pref: PrefKey.VIDEO_SHARPNESS,
onChange: updateVideoPlayer,

View File

@@ -59,8 +59,11 @@ export class ScreenshotManager {
return;
}
$player.parentElement!.addEventListener('animationend', this.onAnimationEnd, { once: true });
$player.parentElement!.classList.add('bx-taking-screenshot');
const $gameStream = $player.closest('#game-stream');
if ($gameStream) {
$gameStream.addEventListener('animationend', this.onAnimationEnd, { once: true });
$gameStream.classList.add('bx-taking-screenshot');
}
const canvasContext = this.canvasContext;

View File

@@ -8,7 +8,7 @@ import { CE } from "../html";
import { t, SUPPORTED_LANGUAGES } from "../translation";
import { UserAgent } from "../user-agent";
import { BaseSettingsStore as BaseSettingsStorage } from "./base-settings-storage";
import { CodecProfile, StreamResolution, TouchControllerMode, TouchControllerStyleStandard, TouchControllerStyleCustom, GameBarPosition, DeviceVibrationMode, NativeMkbMode, UiLayout, UiSection, StreamPlayerType, StreamVideoProcessing, VideoRatio, StreamStat } from "@/enums/pref-values";
import { CodecProfile, StreamResolution, TouchControllerMode, TouchControllerStyleStandard, TouchControllerStyleCustom, GameBarPosition, DeviceVibrationMode, NativeMkbMode, UiLayout, UiSection, StreamPlayerType, StreamVideoProcessing, VideoRatio, StreamStat, VideoPosition } from "@/enums/pref-values";
import { MkbMappingDefaultPresetId } from "../local-db/mkb-mapping-presets-table";
import { KeyboardShortcutDefaultId } from "../local-db/keyboard-shortcuts-table";
import { GhPagesUtils } from "../gh-pages";
@@ -681,10 +681,10 @@ export class GlobalSettingsStorage extends BaseSettingsStorage {
},
[PrefKey.VIDEO_RATIO]: {
label: t('aspect-ratio'),
note: t('aspect-ratio-note'),
note: STATES.browser.capabilities.touch ? t('aspect-ratio-note') : undefined,
default: VideoRatio['16:9'],
options: {
[VideoRatio['16:9']]: '16:9',
[VideoRatio['16:9']]: `16:9 (${t('default')})`,
[VideoRatio['18:9']]: '18:9',
[VideoRatio['21:9']]: '21:9',
[VideoRatio['16:10']]: '16:10',
@@ -694,6 +694,19 @@ export class GlobalSettingsStorage extends BaseSettingsStorage {
//'cover': 'Cover',
},
},
[PrefKey.VIDEO_POSITION]: {
label: t('position'),
note: STATES.browser.capabilities.touch ? t('aspect-ratio-note') : undefined,
default: VideoPosition.CENTER,
options: {
[VideoPosition.TOP]: t('top'),
[VideoPosition.TOP_HALF]: t('top-half'),
[VideoPosition.CENTER]: `${t('center')} (${t('default')})`,
[VideoPosition.BOTTOM_HALF]: t('bottom-half'),
[VideoPosition.BOTTOM]: t('bottom'),
},
},
[PrefKey.VIDEO_SATURATION]: {
label: t('saturation'),
default: 100,
@@ -746,7 +759,6 @@ export class GlobalSettingsStorage extends BaseSettingsStorage {
},
},
[PrefKey.STATS_ITEMS]: {
label: t('stats'),
default: [StreamStat.PING, StreamStat.FPS, StreamStat.BITRATE, StreamStat.DECODE_TIME, StreamStat.PACKETS_LOST, StreamStat.FRAMES_LOST],

View File

@@ -27,6 +27,11 @@ export const SUPPORTED_LANGUAGES = {
};
const Texts = {
"top": "Top",
"top-half": "Top half",
"center": "Center",
"bottom": "Bottom",
"bottom-half": "Bottom half",
"activate": "Activate",
"activated": "Activated",
"active": "Active",