|
@@ -8,8 +8,8 @@ import { BehaviorSubject, filter, ignoreElements, take } from 'rxjs';
|
|
|
import { ActionType } from './actionType';
|
|
|
import { CacheService } from 'src/cache/cache.service';
|
|
|
import { StreamService } from './stream/stream.service';
|
|
|
-import { InjectQueue } from '@nestjs/bull';
|
|
|
-import { Queue } from 'bull';
|
|
|
+// import { InjectQueue } from '@nestjs/bull';
|
|
|
+// import { Queue } from 'bull';
|
|
|
import { RotateService } from 'src/rotate/rotate.service';
|
|
|
import { DelayQueue, RxQueue, ThrottleQueue, DebounceQueue } from 'rx-queue';
|
|
|
import { MoveService } from 'src/move/move.service';
|
|
@@ -24,13 +24,14 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
|
private rotateService: RotateService,
|
|
|
private moveService: MoveService,
|
|
|
private getRouterService: GetRouterService,
|
|
|
- @InjectQueue('rotate') private rotateQueue: Queue,
|
|
|
- @InjectQueue('walking') private walkingQueue: Queue,
|
|
|
+ // @InjectQueue('rotate') private rotateQueue: Queue,
|
|
|
+ // @InjectQueue('walking') private walkingQueue: Queue,
|
|
|
) { }
|
|
|
@Client(grpcClientOptions) private readonly client: ClientGrpc;
|
|
|
|
|
|
public _frameInteval: NodeJS.Timeout;
|
|
|
public _frameTimeout: NodeJS.Timeout;
|
|
|
+ public _rotateTimeout: NodeJS.Timeout;
|
|
|
public startSteaming = new BehaviorSubject<boolean>(false);
|
|
|
public onRotating = new BehaviorSubject<boolean>(false);
|
|
|
public onMoving = new BehaviorSubject<boolean>(false);
|
|
@@ -55,8 +56,9 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
|
private walkingSub: any;
|
|
|
|
|
|
private streamServiceSub: any;
|
|
|
- private roQueue: RxQueue = new DelayQueue(100);
|
|
|
+ private roQueue: RxQueue = new RxQueue(0);
|
|
|
private clickQueue: RxQueue = new DebounceQueue(500);
|
|
|
+
|
|
|
private moveQueue: RxQueue = new DelayQueue(600);
|
|
|
private rotateTimeStamp: number;
|
|
|
private lastMoveCnt = -1;
|
|
@@ -199,8 +201,6 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
|
// this.moveService.init(request.app_id, request.user_id);
|
|
|
|
|
|
// this.initUsers(request.app_id, request.user_id);
|
|
|
- this.rotateQueue.empty();
|
|
|
- this.walkingQueue.empty();
|
|
|
} catch (error) {
|
|
|
console.log('error', error);
|
|
|
}
|
|
@@ -215,79 +215,83 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
|
|
|
|
async rotate(request: RotateRequest) {
|
|
|
try {
|
|
|
- // if (!this.onSteaming) {
|
|
|
- let redisMeta: StreamReplyType;
|
|
|
- this.onRotating.next(true);
|
|
|
- if (this.onMoving.value) {
|
|
|
- this.onMoving.next(false);
|
|
|
- const lastStreamFrame = this.lastMoveStreamFrame.getValue();
|
|
|
- const metaData: StreamReplyType = JSON.parse(
|
|
|
- lastStreamFrame.metaData,
|
|
|
- ) as any as StreamReplyType;
|
|
|
- const newUserStates: NewUserStatesType = metaData.newUserStates.find(
|
|
|
- (item) => item.userId === this.user_id,
|
|
|
- );
|
|
|
- const trace_id = metaData.traceIds[0];
|
|
|
- const userId = newUserStates.userId;
|
|
|
- const breakPointId = lastStreamFrame.marker
|
|
|
- .replace('P', '')
|
|
|
- .replace('T', '-');
|
|
|
- const cameraAngle = newUserStates.playerState.camera.angle;
|
|
|
- const playerAngle = newUserStates.playerState.player.angle;
|
|
|
- console.log('stop-data', trace_id, userId, cameraAngle, cameraAngle);
|
|
|
- redisMeta = await this.moveService.stop(
|
|
|
- trace_id,
|
|
|
- userId,
|
|
|
- breakPointId,
|
|
|
- cameraAngle,
|
|
|
- playerAngle,
|
|
|
- );
|
|
|
- console.log('stop-redisMeta', redisMeta);
|
|
|
- // redisMeta = await this.rotateService.rotate(request);
|
|
|
- } else {
|
|
|
- redisMeta = await this.rotateService.rotate(request);
|
|
|
- }
|
|
|
+ if (this.firstRender) {
|
|
|
+ if (!this.roQueueSubscription) {
|
|
|
+ this.handleRotateStream();
|
|
|
+ }
|
|
|
+ let redisMeta: StreamReplyType;
|
|
|
+ this.onRotating.next(true);
|
|
|
+ if (this.onMoving.value) {
|
|
|
+ this.onMoving.next(false);
|
|
|
+ const lastStreamFrame = this.lastMoveStreamFrame.getValue();
|
|
|
+ const metaData: StreamReplyType = JSON.parse(
|
|
|
+ lastStreamFrame.metaData,
|
|
|
+ ) as any as StreamReplyType;
|
|
|
+ const newUserStates: NewUserStatesType = metaData.newUserStates.find(
|
|
|
+ (item) => item.userId === this.user_id,
|
|
|
+ );
|
|
|
+ const trace_id = metaData.traceIds[0];
|
|
|
+ const userId = newUserStates.userId;
|
|
|
+ const breakPointId = lastStreamFrame.marker
|
|
|
+ .replace('P', '')
|
|
|
+ .replace('T', '-');
|
|
|
+ const cameraAngle = newUserStates.playerState.camera.angle;
|
|
|
+ const playerAngle = newUserStates.playerState.player.angle;
|
|
|
+ console.log('stop-data', trace_id, userId, cameraAngle, cameraAngle);
|
|
|
+ redisMeta = await this.moveService.stop(
|
|
|
+ trace_id,
|
|
|
+ userId,
|
|
|
+ breakPointId,
|
|
|
+ cameraAngle,
|
|
|
+ playerAngle,
|
|
|
+ );
|
|
|
+ console.log('stop-redisMeta', redisMeta);
|
|
|
+ // redisMeta = await this.rotateService.rotate(request);
|
|
|
+ } else {
|
|
|
+ redisMeta = await this.rotateService.rotate(request);
|
|
|
+ }
|
|
|
|
|
|
- if (redisMeta && 'mediaSrc' in redisMeta) {
|
|
|
- const mediaSrc: string = redisMeta.mediaSrc || '';
|
|
|
- if (mediaSrc.length > 0) {
|
|
|
- let src = mediaSrc.split('?')[0];
|
|
|
- // 临时本地替换路经
|
|
|
- src = src.replace('/0000000001/', '');
|
|
|
- // 判断不是同一条源时才推出
|
|
|
- if (src.length > 0) {
|
|
|
- // console.log('不同源');
|
|
|
- // this.frameCnt += 1;
|
|
|
- this.holdSteam();
|
|
|
- this.lastRenderMedia = src;
|
|
|
- const clipPath = join(__dirname, `../ws/video/${src}`);
|
|
|
- // console.log('src-clipPath', src, clipPath);
|
|
|
- delete redisMeta.mediaSrc;
|
|
|
- // if (this.rotateframeCnt === -1) {
|
|
|
- // this.rotateframeCnt = this.frameCnt.value;
|
|
|
- // }
|
|
|
- const nextFrame = this.frameCnt.getValue() + 1;
|
|
|
- this.frameCnt.next(nextFrame);
|
|
|
- const random_boolean = Math.random() < 0.3;
|
|
|
-
|
|
|
- const stream: StreamFrameType = {
|
|
|
- frame: this.frameCnt.getValue(),
|
|
|
- clipPath: clipPath,
|
|
|
- metaData: JSON.stringify(redisMeta),
|
|
|
- serverTime: this.mockserverTime,
|
|
|
- DIR: random_boolean ? 1 : 3,
|
|
|
- };
|
|
|
- this.rotateQueue.add(stream, {
|
|
|
- delay: 5,
|
|
|
- jobId: `rotate:${this.user_id}:${this.frameCnt.getValue()}`,
|
|
|
- removeOnComplete: true,
|
|
|
- });
|
|
|
- } else {
|
|
|
- this.onRotating.next(false);
|
|
|
+ if (redisMeta && 'mediaSrc' in redisMeta) {
|
|
|
+ const mediaSrc: string = redisMeta.mediaSrc || '';
|
|
|
+ if (mediaSrc.length > 0) {
|
|
|
+ let src = mediaSrc.split('?')[0];
|
|
|
+ // 临时本地替换路经
|
|
|
+ src = src.replace('/0000000001/', '');
|
|
|
+ // 判断不是同一条源时才推出
|
|
|
+ if (src.length > 0) {
|
|
|
+ // console.log('不同源');
|
|
|
+ // this.frameCnt += 1;
|
|
|
+ this.holdSteam();
|
|
|
+ this.lastRenderMedia = src;
|
|
|
+ const clipPath = join(__dirname, `../ws/video/${src}`);
|
|
|
+ // console.log('src-clipPath', src, clipPath);
|
|
|
+ delete redisMeta.mediaSrc;
|
|
|
+
|
|
|
+ // const nextFrame = this.frameCnt.getValue() + 1;
|
|
|
+ // console.log('nextFrame', nextFrame);
|
|
|
+ // this.frameCnt.next(nextFrame);
|
|
|
+ const random_boolean = Math.random() < 0.3;
|
|
|
+
|
|
|
+ const stream: StreamFrameType = {
|
|
|
+ frame: -1,
|
|
|
+ clipPath: clipPath,
|
|
|
+ metaData: JSON.stringify(redisMeta),
|
|
|
+ serverTime: this.mockserverTime,
|
|
|
+ DIR: this.frameCnt.getValue() < 10 ? 3 : random_boolean ? 1 : 3,
|
|
|
+ };
|
|
|
+ // this.rotateQueue.add(stream, {
|
|
|
+ // delay: 5,
|
|
|
+ // jobId: `rotate:${this.user_id}:${this.frameCnt.getValue()}`,
|
|
|
+ // removeOnComplete: true,
|
|
|
+ // });
|
|
|
+ clearTimeout(this._rotateTimeout);
|
|
|
+ this.roQueue.next(stream);
|
|
|
+ } else {
|
|
|
+ // this.onRotating.next(false);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- // }
|
|
|
} catch (error) {
|
|
|
this.logger.error('rotate', error);
|
|
|
console.log('error', error);
|
|
@@ -404,7 +408,6 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
|
// debugger;
|
|
|
|
|
|
if (walkingRes && !this.onMoving.value) {
|
|
|
-
|
|
|
// walkingRes marker to everybody
|
|
|
const res: ArrayLike<unknown> = Object.keys(walkingRes).map(
|
|
|
(item) => {
|
|
@@ -545,14 +548,13 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
|
}
|
|
|
if (
|
|
|
frame > 1 &&
|
|
|
- !this.onSteaming &&
|
|
|
!this.onMoving.value &&
|
|
|
!this.onRotating.value &&
|
|
|
this.firstRender
|
|
|
) {
|
|
|
- console.log(`空白流::${frame}`);
|
|
|
const redisDataAuto = await this.rotateService.echo(this.user_id);
|
|
|
if (redisDataAuto) {
|
|
|
+ console.log(`空白流::有数据:${frame}`);
|
|
|
'mediaSrc' in redisDataAuto && delete redisDataAuto.mediaSrc;
|
|
|
const streamMeta: StreamMetaType = {
|
|
|
frame: frame,
|
|
@@ -570,25 +572,32 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
|
this.roQueueSubscription = this.roQueue.subscribe(
|
|
|
async (stream: StreamFrameType) => {
|
|
|
this.rotateTimeStamp = Date.now();
|
|
|
+ if (this.rotateframeCnt === -1) {
|
|
|
+ this.rotateframeCnt = this.frameCnt.value;
|
|
|
+ }
|
|
|
+ this.rotateframeCnt += 1;
|
|
|
|
|
|
stream.frame = this.rotateframeCnt;
|
|
|
- console.log('[media]', stream.clipPath);
|
|
|
- this.logger.log(
|
|
|
- `roQueueSubscription:frame:${this.rotateframeCnt} ` +
|
|
|
- JSON.stringify(stream.metaData),
|
|
|
- );
|
|
|
- // await this.streamService.pushFrameToSteam(stream);
|
|
|
- setTimeout(() => {
|
|
|
- const now = Date.now();
|
|
|
- if (now - this.rotateTimeStamp > this.rotatePeriod) {
|
|
|
+ console.log('[media-rotate]', stream.frame, stream.clipPath);
|
|
|
+ // this.logger.log(
|
|
|
+ // `roQueueSubscription:frame:${this.rotateframeCnt} ` +
|
|
|
+ // JSON.stringify(stream.metaData),
|
|
|
+ // );
|
|
|
+
|
|
|
+ const res = await this.streamService.pushFrameToSteam(stream);
|
|
|
+ if (res.done) {
|
|
|
+ clearTimeout(this._rotateTimeout);
|
|
|
+ this._rotateTimeout = setTimeout(() => {
|
|
|
+ console.log('rotate 1秒', Date.now());
|
|
|
console.log('rotate end');
|
|
|
- // const next = this.rotateframeCnt + 1;
|
|
|
- // this.resumeStream(next);
|
|
|
- // this.rotateframeCnt = -1;
|
|
|
- // this.onMoving = false;
|
|
|
- // this.onRotating = false;
|
|
|
- }
|
|
|
- }, 300);
|
|
|
+ // const next = res.frame + 1;
|
|
|
+ this.frameCnt.next(res.frame);
|
|
|
+ this.resumeStream();
|
|
|
+ this.rotateframeCnt = -1;
|
|
|
+ this.onMoving.next(false);
|
|
|
+ this.onRotating.next(false);
|
|
|
+ }, 300);
|
|
|
+ }
|
|
|
},
|
|
|
);
|
|
|
}
|