Skip to content

Commit

Permalink
Player options became deprecated because Flash player is not supporte…
Browse files Browse the repository at this point in the history
…d anymore
  • Loading branch information
ProFiLeR4100 committed Dec 16, 2023
1 parent d26a107 commit 019bd9e
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 51 deletions.
32 changes: 17 additions & 15 deletions src/modules/stream/stream.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { GetPlayerOptions, GetMetadata, GetLastMessages } from '../../services/rest.service';
import { GetMetadata, GetLastMessages } from '../../services/rest.service';
import { timeout } from '../../utils/async.utils';
import { from, Subscription } from '@reactivex/rxjs/dist/package';
import { Metadata } from '../../types/metadata.types';
import { PlayerOptions } from '../../types/playeroptions.types';
import { ChatResponse } from '../../types/chat.types';
import { OpenWebsocketConnection } from '../../services/websocket.service';

export class StreamManager {
private readonly username: string = '';
private serviceStarted: boolean = false;
private metadata?: Metadata = undefined; // https://api.vkplay.live/v1/blog/<username>/public_video_stream?from=layer
private playerOptions?: PlayerOptions = undefined; // https://ok.ru/videoembed/<videoId>?sig=<vid>&uid=<user_id>&t=<timestamp>&cip=<client_ip>&ua=<user_agent>>&promo=boosty
// todo: looks like it is deprecated, need to check
// private playerOptions?: PlayerOptions = undefined; // https://ok.ru/videoembed/<videoId>?sig=<vid>&uid=<user_id>&t=<timestamp>&cip=<client_ip>&ua=<user_agent>>&promo=boosty
private subscription: Subscription;

public constructor(username: string, immediateStart: boolean = true) {
Expand All @@ -25,7 +25,8 @@ export class StreamManager {
public async start() {
this.serviceStarted = true;
this.metadata = await GetMetadata(this.username, this.metadata);
this.playerOptions = await GetPlayerOptions(this.username, this.metadata?.data?.[0]?.url);
// todo: looks like it is deprecated, need to check
// this.playerOptions = await GetPlayerOptions(this.username, this.metadata?.data?.[0]?.url);
}

public stop() {
Expand All @@ -48,17 +49,18 @@ export class StreamManager {
return null;
}

public async GetPlayerOptions(failCount: number = 10): Promise<PlayerOptions | null> {
for (let fails = 0; fails < failCount; fails++) {
if (this.playerOptions) {
return this.playerOptions;
}

await timeout(200);
}

return null;
}
// todo: looks like it is deprecated, need to check
// public async GetPlayerOptions(failCount: number = 10): Promise<PlayerOptions | null> {
// for (let fails = 0; fails < failCount; fails++) {
// if (this.playerOptions) {
// return this.playerOptions;
// }
//
// await timeout(200);
// }
//
// return null;
// }

public async GetLastMessages(limit: number = 20): Promise<ChatResponse> {
return GetLastMessages(this.username, limit);
Expand Down
55 changes: 28 additions & 27 deletions src/services/rest.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,33 +20,34 @@ export const GetMetadata = async (username: string, metadata?: Metadata): Promis
);
};

export const GetPlayerOptions = async (
username?: string,
url?: string
): Promise<PlayerOptions | undefined> => {
if (!url || !username) {
console.error(new Error('url for getting player options is incorrect'));
return;
}

return axios
.get<string>(url, {
headers: {
...GetAdditionalHeaders(username)
}
})
.then(response => {
const regexp = /data-options="([^"]+)"/gm;
const result: any = JSON.parse(decode(regexp.exec(response.data)?.[1] ?? '{}'));

// hack for stringified vars
if (result?.flashvars?.metadata) {
result.flashvars.metadata = JSON.parse(result.flashvars.metadata);
}

return result;
});
};
// todo: looks like it is deprecated, need to check
// export const GetPlayerOptions = async (
// username?: string,
// url?: string
// ): Promise<PlayerOptions | undefined> => {
// if (!url || !username) {
// console.error(new Error('url for getting player options is incorrect'));
// return;
// }
//
// return axios
// .get<string>(url, {
// headers: {
// ...GetAdditionalHeaders(username)
// }
// })
// .then(response => {
// const regexp = /data-options="([^"]+)"/gm;
// const result: any = JSON.parse(decode(regexp.exec(response.data)?.[1] ?? '{}'));
//
// // hack for stringified vars
// if (result?.flashvars?.metadata) {
// result.flashvars.metadata = JSON.parse(result.flashvars.metadata);
// }
//
// return result;
// });
// };

export const GetAppConfig = (username: string): Promise<AppConfig> => {
return axios
Expand Down
4 changes: 2 additions & 2 deletions src/unofficial-vk-play-live-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import { StreamManager } from './modules/stream/stream';

export default class VKPLAPI {
public static GetStreamManager(username: string) {
return new StreamManager(username);
public static GetStreamManager(username: string, immediateStart: boolean = true) {
return new StreamManager(username, immediateStart);
}
}
15 changes: 8 additions & 7 deletions test/unofficial-vk-play-live-api.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import VKPLAPI from '../src/unofficial-vk-play-live-api';
* Dummy test
*/
describe('Dummy test', () => {
const streamManager = VKPLAPI.GetStreamManager('terablade');
const streamManager = VKPLAPI.GetStreamManager('bezzdar');

it('Root class is instantiable', () => {
expect(new VKPLAPI()).toBeInstanceOf(VKPLAPI);
Expand All @@ -27,12 +27,13 @@ describe('Dummy test', () => {
// expect(fieldsAreMatchingWithType(metadata, keyof<Metadata>)).toBeTruthy();
});

it('PlayerOptions must come from server', async () => {
const playerOptions = await streamManager.GetPlayerOptions();
expect(playerOptions).not.toBeNull();
// todo: fix and enable check
// expect(fieldsAreMatchingWithType(playerOptions, PlayerOptions)).toBeTruthy();
});
// todo: looks like it is deprecated, need to check
// it('PlayerOptions must come from server', async () => {
// const playerOptions = await streamManager.GetPlayerOptions();
// expect(playerOptions).not.toBeNull();
// // todo: fix and enable check
// // expect(fieldsAreMatchingWithType(playerOptions, PlayerOptions)).toBeTruthy();
// });

it('Chat messages must come from server', async () => {
const playerOptions = await streamManager.GetLastMessages();
Expand Down

0 comments on commit 019bd9e

Please sign in to comment.