From 13e92243e585c903c13ca6a17fdbc2409c6fe25f Mon Sep 17 00:00:00 2001 From: 4gray Date: Sun, 4 May 2025 23:03:53 +0200 Subject: [PATCH] refactor(xtream): streamline player service integration and improve dialog handling --- src/app/services/player.service.ts | 2 +- .../live-stream-layout.component.ts | 28 +++-------------- .../serial-details.component.ts | 31 ++++--------------- .../vod-details/vod-details.component.ts | 25 ++------------- 4 files changed, 14 insertions(+), 72 deletions(-) diff --git a/src/app/services/player.service.ts b/src/app/services/player.service.ts index fb8774f76..6fc8d9be5 100644 --- a/src/app/services/player.service.ts +++ b/src/app/services/player.service.ts @@ -22,7 +22,7 @@ export class PlayerService { streamUrl: string, title: string, thumbnail?: string, - hideExternalInfoDialog = false, + hideExternalInfoDialog = true, isLiveContent = false ) { const player = this.settingsStore.player() ?? VideoPlayer.VideoJs; diff --git a/src/app/xtream-tauri/live-stream-layout/live-stream-layout.component.ts b/src/app/xtream-tauri/live-stream-layout/live-stream-layout.component.ts index 4874c30b1..7db58c866 100644 --- a/src/app/xtream-tauri/live-stream-layout/live-stream-layout.component.ts +++ b/src/app/xtream-tauri/live-stream-layout/live-stream-layout.component.ts @@ -15,7 +15,6 @@ import { TranslatePipe } from '@ngx-translate/core'; import { XtreamCategory } from '../../../../shared/xtream-category.interface'; import { EpgViewComponent } from '../../portals/epg-view/epg-view.component'; import { WebPlayerViewComponent } from '../../portals/web-player-view/web-player-view.component'; -import { PlayerService } from '../../services/player.service'; import { SettingsStore } from '../../services/settings-store.service'; import { CategoryViewComponent } from '../category-view/category-view.component'; import { PortalChannelsListComponent } from '../portal-channels-list/portal-channels-list.component'; @@ -42,20 +41,16 @@ import { XtreamStore } from '../xtream.store'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class LiveStreamLayoutComponent implements OnInit { - private favoritesService = inject(FavoritesService); - private playerService = inject(PlayerService); + private readonly favoritesService = inject(FavoritesService); private readonly xtreamStore = inject(XtreamStore); private readonly settingsStore = inject(SettingsStore); readonly categories = this.xtreamStore.getCategoriesBySelectedType; readonly epgItems = this.xtreamStore.epgItems; readonly selectedCategoryId = this.xtreamStore.selectedCategoryId; - private readonly hideExternalInfoDialog = - this.xtreamStore.hideExternalInfoDialog; - private readonly selectedContentType = this.xtreamStore.selectedContentType; private readonly route = inject(ActivatedRoute); - player = this.settingsStore.player; + readonly player = this.settingsStore.player; streamUrl: string; favorites = new Map(); @@ -78,24 +73,9 @@ export class LiveStreamLayoutComponent implements OnInit { } playLive(item: any) { - const { serverUrl, username, password } = - this.xtreamStore.currentPlaylist(); - const streamFormat = this.settingsStore.streamFormat(); - const streamUrl = `${serverUrl}/live/${username}/${password}/${item.xtream_id}.${streamFormat}`; - this.openPlayer(streamUrl, item.title, item.poster_url); - this.xtreamStore.setSelectedItem(item); - this.xtreamStore.loadEpg(); - } - - openPlayer(streamUrl: string, title: string, thumbnail: string) { + const streamUrl = this.xtreamStore.constructStreamUrl(item); this.streamUrl = streamUrl; - this.playerService.openPlayer( - streamUrl, - title, - thumbnail, - this.hideExternalInfoDialog(), - this.selectedContentType() === 'live' - ); + this.xtreamStore.openPlayer(streamUrl, item.title, item.poster_url); } selectCategory(category: XtreamCategory) { diff --git a/src/app/xtream-tauri/serial-details/serial-details.component.ts b/src/app/xtream-tauri/serial-details/serial-details.component.ts index aacba7d20..2eb4a73a1 100644 --- a/src/app/xtream-tauri/serial-details/serial-details.component.ts +++ b/src/app/xtream-tauri/serial-details/serial-details.component.ts @@ -2,12 +2,8 @@ import { Component, inject } from '@angular/core'; import { MatButton } from '@angular/material/button'; import { MatIcon } from '@angular/material/icon'; import { ActivatedRoute } from '@angular/router'; -import { Store } from '@ngrx/store'; -import { TranslateModule } from '@ngx-translate/core'; +import { TranslatePipe } from '@ngx-translate/core'; import { XtreamSerieEpisode } from '../../../../shared/xtream-serie-details.interface'; -import { PlayerService } from '../../services/player.service'; -import { SettingsStore } from '../../services/settings-store.service'; -import { selectActivePlaylist } from '../../state/selectors'; import { SeasonContainerComponent } from '../season-container/season-container.component'; import { XtreamStore } from '../xtream.store'; @@ -15,23 +11,16 @@ import { XtreamStore } from '../xtream.store'; selector: 'app-serial-details', templateUrl: './serial-details.component.html', styleUrls: ['../detail-view.scss'], - imports: [MatButton, MatIcon, SeasonContainerComponent, TranslateModule] + imports: [MatButton, MatIcon, SeasonContainerComponent, TranslatePipe], }) export class SerialDetailsComponent { - private readonly store = inject(Store); private readonly route = inject(ActivatedRoute); private readonly xtreamStore = inject(XtreamStore); - private readonly settingsStore = inject(SettingsStore); - private readonly playerService = inject(PlayerService); readonly selectedItem = this.xtreamStore.selectedItem; - readonly settings = this.settingsStore.getSettings(); readonly selectedContentType = this.xtreamStore.selectedContentType; readonly isFavorite = this.xtreamStore.isFavorite; - private readonly hideExternalInfoDialog = - this.xtreamStore.hideExternalInfoDialog; - ngOnInit(): void { const { categoryId, serialId } = this.route.snapshot.params; this.xtreamStore.fetchSerialDetailsWithMetadata({ @@ -46,20 +35,12 @@ export class SerialDetailsComponent { playEpisode(episode: XtreamSerieEpisode) { this.addToRecentlyViewed(this.route.snapshot.params.serialId); - const currentPlaylist = this.store.selectSignal(selectActivePlaylist); - const { serverUrl, username, password } = currentPlaylist(); - const streamUrl = `${serverUrl}/series/${username}/${password}/${episode.id}.${episode.container_extension}`; - this.openPlayer(streamUrl, episode.title); - } - - openPlayer(streamUrl: string, title: string) { - this.playerService.openPlayer( + const streamUrl = this.xtreamStore.constructEpisodeStreamUrl(episode); + this.xtreamStore.openPlayer( streamUrl, - title, - this.xtreamStore.selectedItem().info.cover, - this.hideExternalInfoDialog(), - this.selectedContentType() === 'live' + episode.title, + this.selectedItem().info.cover ); } diff --git a/src/app/xtream-tauri/vod-details/vod-details.component.ts b/src/app/xtream-tauri/vod-details/vod-details.component.ts index bba594e37..005b64b8c 100644 --- a/src/app/xtream-tauri/vod-details/vod-details.component.ts +++ b/src/app/xtream-tauri/vod-details/vod-details.component.ts @@ -3,12 +3,9 @@ import { MatButton } from '@angular/material/button'; import { MatIcon } from '@angular/material/icon'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { ActivatedRoute } from '@angular/router'; -import { Store } from '@ngrx/store'; import { TranslateModule } from '@ngx-translate/core'; import { XtreamVodDetails } from '../../../../shared/xtream-vod-details.interface'; -import { PlayerService } from '../../services/player.service'; import { SettingsStore } from '../../services/settings-store.service'; -import { selectActivePlaylist } from '../../state/selectors'; import { XtreamStore } from '../xtream.store'; import { SafePipe } from './safe.pipe'; @@ -21,19 +18,15 @@ import { SafePipe } from './safe.pipe'; SafePipe, TranslateModule, MatProgressSpinnerModule, - ] + ], }) export class VodDetailsComponent implements OnInit, OnDestroy { private settingsStore = inject(SettingsStore); private route = inject(ActivatedRoute); - private store = inject(Store); private readonly xtreamStore = inject(XtreamStore); - private playerService = inject(PlayerService); readonly theme = this.settingsStore.theme; private readonly selectedContentType = this.xtreamStore.selectedContentType; - private readonly hideExternalInfoDialog = - this.xtreamStore.hideExternalInfoDialog; readonly isFavorite = this.xtreamStore.isFavorite; readonly selectedItem = this.xtreamStore.selectedItem; @@ -53,27 +46,15 @@ export class VodDetailsComponent implements OnInit, OnDestroy { playVod(vodItem: XtreamVodDetails) { this.addToRecentlyViewed(); - const currentPlaylist = this.store.selectSignal(selectActivePlaylist); - const { serverUrl, username, password } = currentPlaylist(); - const streamUrl = `${serverUrl}/movie/${username}/${password}/${vodItem.movie_data.stream_id}.${vodItem.movie_data.container_extension}`; + const streamUrl = this.xtreamStore.constructVodStreamUrl(vodItem); - this.openPlayer( + this.xtreamStore.openPlayer( streamUrl, vodItem.info.name ?? vodItem?.movie_data?.name, vodItem.info.movie_image ); } - openPlayer(streamUrl: string, title: string, thumbnail: string) { - this.playerService.openPlayer( - streamUrl, - title, - thumbnail, - this.hideExternalInfoDialog(), - this.selectedContentType() === 'live' - ); - } - toggleFavorite() { this.xtreamStore.toggleFavorite( this.route.snapshot.params.vodId,