fix: remove frontend session management
This commit is contained in:
@@ -10,8 +10,6 @@ import apiService from './services/ApiService';
|
||||
import SettingsModal from './components/SettingsModal';
|
||||
import { ToastProvider } from './components/notifications/ToastContext';
|
||||
import ToastContainer from './components/notifications/ToastContainer';
|
||||
import SessionFactory from './services/session/SessionFactory';
|
||||
import { SessionHandler } from './services/session/SessionHandler';
|
||||
|
||||
function App() {
|
||||
const [channels, setChannels] = useState<Channel[]>([]);
|
||||
@@ -25,9 +23,6 @@ function App() {
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
const [editChannel, setEditChannel] = useState<Channel | null>(null);
|
||||
|
||||
const [sessionProvider, setSessionProvider] = useState<SessionHandler | null>(null);
|
||||
const [sessionQuery, setSessionQuery] = useState<string | undefined>(undefined);
|
||||
|
||||
|
||||
const [selectedPlaylist, setSelectedPlaylist] = useState<string>('All Channels');
|
||||
const [selectedGroup, setSelectedGroup] = useState<string>('Category');
|
||||
@@ -84,7 +79,6 @@ function App() {
|
||||
};
|
||||
|
||||
const channelSelectedListener = (nextChannel: Channel) => {
|
||||
checkSession(nextChannel, selectedChannel?.url != nextChannel.url);
|
||||
setSelectedChannel(nextChannel);
|
||||
};
|
||||
|
||||
@@ -126,24 +120,6 @@ function App() {
|
||||
|
||||
socketService.connect();
|
||||
|
||||
const checkSession = (channel : Channel, urlHasChanged : boolean | undefined) => {
|
||||
const newProvider = SessionFactory.getSessionProvider(channel.url, setSessionQuery);
|
||||
|
||||
if(!newProvider || channel.mode === 'restream') {
|
||||
sessionProvider?.destroySession();
|
||||
setSessionProvider(null);
|
||||
return;
|
||||
}
|
||||
|
||||
if(newProvider?.type() != sessionProvider?.type() || urlHasChanged) {
|
||||
sessionProvider?.destroySession();
|
||||
setSessionProvider(null);
|
||||
|
||||
setSessionProvider(newProvider);
|
||||
sessionProvider?.createSession();
|
||||
}
|
||||
};
|
||||
|
||||
return () => {
|
||||
socketService.unsubscribeFromEvent('channel-added', channelAddedListener);
|
||||
socketService.unsubscribeFromEvent('channel-selected', channelSelectedListener);
|
||||
@@ -305,7 +281,7 @@ function App() {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<VideoPlayer channel={selectedChannel} sessionQuery={sessionQuery} syncEnabled={syncEnabled} />
|
||||
<VideoPlayer channel={selectedChannel} syncEnabled={syncEnabled} />
|
||||
</div>
|
||||
|
||||
<div className="col-span-12 lg:col-span-4">
|
||||
|
||||
@@ -5,11 +5,10 @@ import { ToastContext } from './notifications/ToastContext';
|
||||
|
||||
interface VideoPlayerProps {
|
||||
channel: Channel | null;
|
||||
sessionQuery: string | undefined;
|
||||
syncEnabled: boolean;
|
||||
}
|
||||
|
||||
function VideoPlayer({ channel, sessionQuery, syncEnabled }: VideoPlayerProps) {
|
||||
function VideoPlayer({ channel, syncEnabled }: VideoPlayerProps) {
|
||||
const videoRef = useRef<HTMLVideoElement>(null);
|
||||
const hlsRef = useRef<Hls | null>(null);
|
||||
const { addToast, removeToast, clearToasts, editToast } = useContext(ToastContext);
|
||||
@@ -51,11 +50,10 @@ function VideoPlayer({ channel, sessionQuery, syncEnabled }: VideoPlayerProps) {
|
||||
},
|
||||
});
|
||||
|
||||
const querySeparator = channel.url.includes('?') ? '&' : '?';
|
||||
const sourceLinks: Record<ChannelMode, string> = {
|
||||
direct: sessionQuery ? channel.url + querySeparator + sessionQuery : channel.url,
|
||||
direct: channel.url,
|
||||
//TODO: needs update for multi-channel streaming
|
||||
proxy: sessionQuery ? import.meta.env.VITE_BACKEND_URL + '/proxy/channel?' + sessionQuery : import.meta.env.VITE_BACKEND_URL + '/proxy/channel',
|
||||
proxy: import.meta.env.VITE_BACKEND_URL + '/proxy/channel',
|
||||
restream: import.meta.env.VITE_BACKEND_URL + '/streams/' + channel.id + "/" + channel.id + ".m3u8", //e.g. http://backend:3000/streams/1/1.m3u8
|
||||
};
|
||||
|
||||
@@ -218,7 +216,7 @@ function VideoPlayer({ channel, sessionQuery, syncEnabled }: VideoPlayerProps) {
|
||||
}
|
||||
};
|
||||
|
||||
}, [channel?.url, channel?.mode, syncEnabled, sessionQuery]);
|
||||
}, [channel?.url, channel?.mode, syncEnabled]);
|
||||
|
||||
const handleVideoClick = (event: React.MouseEvent<HTMLVideoElement>) => {
|
||||
if (videoRef.current?.muted) {
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
import { SessionHandler } from "./SessionHandler";
|
||||
import { StreamedSuSession } from "./StreamedSuSession";
|
||||
|
||||
class SessionFactory {
|
||||
static getSessionProvider(channelUrl: string, setSessionQuery: React.Dispatch<React.SetStateAction<string | undefined>>): SessionHandler | null {
|
||||
switch (true) {
|
||||
case channelUrl.includes('vipstreams.in'): //StreamedSU
|
||||
return new StreamedSuSession(channelUrl, 'https://secure.embedme.top', setSessionQuery);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default SessionFactory;
|
||||
@@ -1,9 +0,0 @@
|
||||
//Implement this interface for your specific session provider
|
||||
interface SessionHandler {
|
||||
createSession(interval?: number): Promise<void>;
|
||||
destroySession(): boolean;
|
||||
//getSessionQuery(): string;
|
||||
type(): string;
|
||||
}
|
||||
|
||||
export type { SessionHandler };
|
||||
@@ -1,110 +0,0 @@
|
||||
import { SessionHandler } from "./SessionHandler";
|
||||
|
||||
class StreamedSuSession implements SessionHandler {
|
||||
private baseUrl: string;
|
||||
private channelUrl: string;
|
||||
private checkInterval: number | null;
|
||||
private sessionId: string | null;
|
||||
private setSessionQuery: React.Dispatch<React.SetStateAction<string | undefined>>;
|
||||
|
||||
constructor(channelUrl: string, baseUrl: string, setSessionQuery: React.Dispatch<React.SetStateAction<string | undefined>>) {
|
||||
this.channelUrl = channelUrl;
|
||||
this.baseUrl = baseUrl;
|
||||
this.checkInterval = null;
|
||||
this.sessionId = null;
|
||||
this.setSessionQuery = setSessionQuery;
|
||||
}
|
||||
|
||||
private async initSession(): Promise<any> {
|
||||
console.log('Creating session:', this.channelUrl);
|
||||
try {
|
||||
const response = await fetch(`${this.baseUrl}/init-session`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
path: new URL(this.channelUrl).pathname,
|
||||
})
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to initialize session');
|
||||
}
|
||||
|
||||
const sessionData = await response.json();
|
||||
this.sessionId = sessionData.id;
|
||||
this.setSessionQuery(`id=${this.sessionId}`);
|
||||
return sessionData.id;
|
||||
} catch (error) {
|
||||
console.error('Session initialization failed:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
private async checkSession(): Promise<boolean> {
|
||||
if (!this.sessionId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
console.log('Checking session:', this.sessionId);
|
||||
try {
|
||||
const response = await fetch(`${this.baseUrl}/check/${this.sessionId}`);
|
||||
return response.status === 200;
|
||||
} catch (error) {
|
||||
console.error('Session check failed:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private startAutoCheck(interval: number = 15000): void {
|
||||
if (this.checkInterval) {
|
||||
this.stopAutoCheck();
|
||||
}
|
||||
|
||||
this.checkInterval = window.setInterval(async () => {
|
||||
const isValid = await this.checkSession();
|
||||
if (!isValid) {
|
||||
console.log('Session aborted');
|
||||
this.initSession();
|
||||
}
|
||||
}, interval);
|
||||
}
|
||||
|
||||
private stopAutoCheck(): void {
|
||||
if (this.checkInterval) {
|
||||
window.clearInterval(this.checkInterval);
|
||||
this.checkInterval = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Public Methods
|
||||
async createSession(interval: number = 15000): Promise<void> {
|
||||
if (!this.sessionId) {
|
||||
await this.initSession();
|
||||
this.startAutoCheck(interval);
|
||||
}
|
||||
}
|
||||
|
||||
destroySession(): boolean {
|
||||
console.log('Destroying session:', this.sessionId);
|
||||
this.stopAutoCheck();
|
||||
this.sessionId = null;
|
||||
this.setSessionQuery(undefined);
|
||||
return true;
|
||||
}
|
||||
|
||||
// getSessionQuery(): string {
|
||||
// console.log('Session ID:', this.sessionId);
|
||||
// if (!this.sessionId) {
|
||||
// return '';
|
||||
// }
|
||||
// return `id=${this.sessionId}`;
|
||||
// }
|
||||
|
||||
type(): string {
|
||||
return 'streamed-su';
|
||||
}
|
||||
}
|
||||
|
||||
export { StreamedSuSession };
|
||||
Reference in New Issue
Block a user