|
@@ -15,6 +15,7 @@ import { DelayQueue, RxQueue, ThrottleQueue, DebounceQueue } from 'rx-queue';
|
|
import { MoveService } from 'src/move/move.service';
|
|
import { MoveService } from 'src/move/move.service';
|
|
import { GetRouterService } from 'src/get-router/get-router.service';
|
|
import { GetRouterService } from 'src/get-router/get-router.service';
|
|
import { ConfigService } from '@nestjs/config';
|
|
import { ConfigService } from '@nestjs/config';
|
|
|
|
+import { join } from 'path';
|
|
|
|
|
|
@Injectable()
|
|
@Injectable()
|
|
export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
@@ -58,13 +59,15 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
private clickQueueSub: any;
|
|
private clickQueueSub: any;
|
|
|
|
|
|
private streamServiceSub: any;
|
|
private streamServiceSub: any;
|
|
- private roQueue: RxQueue = new DelayQueue(30);
|
|
|
|
|
|
+ private roRequestQueue: RxQueue = new RxQueue(5);
|
|
|
|
+ private roQueue: RxQueue = new DelayQueue(20);
|
|
private clickQueue: RxQueue = new DebounceQueue(500);
|
|
private clickQueue: RxQueue = new DebounceQueue(500);
|
|
private moveQueue: RxQueue = new DelayQueue(30);
|
|
private moveQueue: RxQueue = new DelayQueue(30);
|
|
private joystickQueue: RxQueue = new DebounceQueue(500);
|
|
private joystickQueue: RxQueue = new DebounceQueue(500);
|
|
private requestIFrameQueue: RxQueue = new DebounceQueue(2000);
|
|
private requestIFrameQueue: RxQueue = new DebounceQueue(2000);
|
|
|
|
|
|
private requestIFrameQueueSub: any;
|
|
private requestIFrameQueueSub: any;
|
|
|
|
+ private roRequestQueueSub: any;
|
|
private rotateTimeStamp: number;
|
|
private rotateTimeStamp: number;
|
|
private lastMoveCnt = -1;
|
|
private lastMoveCnt = -1;
|
|
|
|
|
|
@@ -216,87 +219,101 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
}
|
|
}
|
|
|
|
|
|
async rotate(request: RotateRequest) {
|
|
async rotate(request: RotateRequest) {
|
|
- try {
|
|
|
|
- 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 = metaData.breakPointId;
|
|
|
|
- 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);
|
|
|
|
- }
|
|
|
|
|
|
+ this.roRequestQueue.next(request);
|
|
|
|
+ if (!this.roRequestQueueSub) {
|
|
|
|
+ this.handleRotate();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ /**
|
|
|
|
+ * rotate请求队列
|
|
|
|
+ */
|
|
|
|
|
|
- if (redisMeta && 'mediaSrc' in redisMeta) {
|
|
|
|
- const mediaSrc: string = redisMeta.mediaSrc || '';
|
|
|
|
- if (mediaSrc.length > 0) {
|
|
|
|
- const src = mediaSrc.split('?')[0];
|
|
|
|
- // 临时本地替换路经
|
|
|
|
- // src = src.replace('/10086/', '');
|
|
|
|
- // 判断不是同一条源时才推出
|
|
|
|
- if (src.length > 0) {
|
|
|
|
- // console.log('不同源');
|
|
|
|
- // this.frameCnt += 1;
|
|
|
|
- this.holdSteam();
|
|
|
|
- this.lastRenderMedia = src;
|
|
|
|
- // const clipPath = join(__dirname, `../ws/${src}`);
|
|
|
|
- const clipPath = this.configService.get('app.prefix') + 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);
|
|
|
|
|
|
+ handleRotate() {
|
|
|
|
+ this.roRequestQueueSub = this.roRequestQueue.subscribe(
|
|
|
|
+ async (request: RotateRequest) => {
|
|
|
|
+ try {
|
|
|
|
+ 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 = metaData.breakPointId;
|
|
|
|
+ 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 {
|
|
} else {
|
|
- // this.onRotating.next(false);
|
|
|
|
|
|
+ redisMeta = await this.rotateService.rotate(request);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (redisMeta && 'mediaSrc' in redisMeta) {
|
|
|
|
+ const mediaSrc: string = redisMeta.mediaSrc || '';
|
|
|
|
+ if (mediaSrc.length > 0) {
|
|
|
|
+ const src = mediaSrc.split('?')[0];
|
|
|
|
+
|
|
|
|
+ if (src.length > 0) {
|
|
|
|
+ // console.log('不同源');
|
|
|
|
+ this.holdSteam();
|
|
|
|
+ this.lastRenderMedia = src;
|
|
|
|
+ const clipPath = this.configService.get('app.prefix') + src;
|
|
|
|
+ delete redisMeta.mediaSrc;
|
|
|
|
+
|
|
|
|
+ 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,
|
|
|
|
+ };
|
|
|
|
+ console.log('rotate', stream, Date.now());
|
|
|
|
+ clearTimeout(this._rotateTimeout);
|
|
|
|
+ this.roQueue.next(stream);
|
|
|
|
+ } else {
|
|
|
|
+ // this.onRotating.next(false);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ } catch (error) {
|
|
|
|
+ this.logger.error('rotate', error);
|
|
|
|
+ console.log('error', error);
|
|
}
|
|
}
|
|
- }
|
|
|
|
- } catch (error) {
|
|
|
|
- this.logger.error('rotate', error);
|
|
|
|
- console.log('error', error);
|
|
|
|
- }
|
|
|
|
|
|
+ },
|
|
|
|
+ );
|
|
}
|
|
}
|
|
|
|
|
|
async walking(req) {
|
|
async walking(req) {
|
|
@@ -315,10 +332,11 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
user.breakPointId,
|
|
user.breakPointId,
|
|
req.clicking_action.clicking_point,
|
|
req.clicking_action.clicking_point,
|
|
);
|
|
);
|
|
|
|
+ // debugger;
|
|
const walkingRes = await this.moveService.move(path, request);
|
|
const walkingRes = await this.moveService.move(path, request);
|
|
|
|
|
|
- console.log('walkingRes-length', Array.from(walkingRes).flat().length);
|
|
|
|
-
|
|
|
|
|
|
+ console.log('walking', walkingRes);
|
|
|
|
+ debugger;
|
|
if (walkingRes && !this.onMoving.value) {
|
|
if (walkingRes && !this.onMoving.value) {
|
|
// console.log('walkingRes-front', walkingRes);
|
|
// console.log('walkingRes-front', walkingRes);
|
|
// shift出前第一个镜头数据
|
|
// shift出前第一个镜头数据
|
|
@@ -338,18 +356,20 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
walkingRes,
|
|
walkingRes,
|
|
).flat() as any as StreamReplyType[];
|
|
).flat() as any as StreamReplyType[];
|
|
|
|
|
|
- if (seqs?.length) {
|
|
|
|
|
|
+ if (rotateCamData?.length || seqs?.length) {
|
|
const lastSeq = rotateCamData?.length
|
|
const lastSeq = rotateCamData?.length
|
|
? (Array.from(rotateCamData).concat(
|
|
? (Array.from(rotateCamData).concat(
|
|
seqs,
|
|
seqs,
|
|
) as any as StreamReplyType[])
|
|
) as any as StreamReplyType[])
|
|
: seqs;
|
|
: seqs;
|
|
- console.log('walking --总序列--seqs', seqs.length);
|
|
|
|
|
|
+
|
|
|
|
+ console.log('walking --总序列--seqs-2', seqs.length);
|
|
this.handleSeqMoving(lastSeq);
|
|
this.handleSeqMoving(lastSeq);
|
|
} else {
|
|
} else {
|
|
console.error('walking-move无数据');
|
|
console.error('walking-move无数据');
|
|
this.cleanMoveSteam();
|
|
this.cleanMoveSteam();
|
|
}
|
|
}
|
|
|
|
+ debugger;
|
|
// this.lastMoveCnt = this.frameCnt.value + seqs.length;
|
|
// this.lastMoveCnt = this.frameCnt.value + seqs.length;
|
|
}
|
|
}
|
|
});
|
|
});
|
|
@@ -527,9 +547,6 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
handleDataChanelOpen(channel: DataChannel): void {
|
|
handleDataChanelOpen(channel: DataChannel): void {
|
|
this.channel = channel;
|
|
this.channel = channel;
|
|
this.streamService.setChannel(channel);
|
|
this.streamService.setChannel(channel);
|
|
- // this.startSteaming.next(true);
|
|
|
|
- // this.startStream();
|
|
|
|
- // this.handleStream();
|
|
|
|
}
|
|
}
|
|
|
|
|
|
handleDataChanelClose(): void {
|
|
handleDataChanelClose(): void {
|
|
@@ -593,14 +610,12 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
|
|
|
|
async handleIframeRequest() {
|
|
async handleIframeRequest() {
|
|
//TODO Iframe 最终传什么?
|
|
//TODO Iframe 最终传什么?
|
|
-
|
|
|
|
this.requestIFrameQueue.next(this.streamService.lastStreamFrame.getValue());
|
|
this.requestIFrameQueue.next(this.streamService.lastStreamFrame.getValue());
|
|
-
|
|
|
|
if (!this.requestIFrameQueueSub) {
|
|
if (!this.requestIFrameQueueSub) {
|
|
this.requestIFrameQueueSub = this.requestIFrameQueue.subscribe(
|
|
this.requestIFrameQueueSub = this.requestIFrameQueue.subscribe(
|
|
(frameData: StreamFrameType) => {
|
|
(frameData: StreamFrameType) => {
|
|
const nextFrame = this.frameCnt.getValue() + 1;
|
|
const nextFrame = this.frameCnt.getValue() + 1;
|
|
- this.logger.warn('lostIframe', nextFrame,);
|
|
|
|
|
|
+ this.logger.warn('lostIframe', nextFrame);
|
|
frameData.frame = nextFrame;
|
|
frameData.frame = nextFrame;
|
|
this.streamService.pushFrameToSteam(frameData);
|
|
this.streamService.pushFrameToSteam(frameData);
|
|
this.frameCnt.next(nextFrame);
|
|
this.frameCnt.next(nextFrame);
|
|
@@ -608,28 +623,11 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
},
|
|
},
|
|
);
|
|
);
|
|
}
|
|
}
|
|
-
|
|
|
|
- // const lastStreamFrame = this.streamService.lastStreamFrame.getValue();
|
|
|
|
- // lastStreamFrame.DIR = 1;
|
|
|
|
- // console.log('lastStreamFrame', lastStreamFrame);
|
|
|
|
- // const nextFrame = this.frameCnt.getValue() + 1;
|
|
|
|
- // lastStreamFrame.frame = nextFrame;
|
|
|
|
- // this.frameCnt.next(nextFrame);
|
|
|
|
- // this.streamService.pushFrameToSteam(lastStreamFrame);
|
|
|
|
- // const redisDataAuto = await this.rotateService.echo(this.user_id);
|
|
|
|
- // if (redisDataAuto) {
|
|
|
|
- // 'mediaSrc' in redisDataAuto && delete redisDataAuto.mediaSrc;
|
|
|
|
- // const streamMeta: StreamMetaType = {
|
|
|
|
- // frame: nextFrame,
|
|
|
|
- // metaData: JSON.stringify(redisDataAuto),
|
|
|
|
- // };
|
|
|
|
- // this.streamService.pushMetaDataToSteam(streamMeta);
|
|
|
|
- // }
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- async handleBreath(request) {
|
|
|
|
- const npsRes = await this.moveService.getBreakPoints(request);
|
|
|
|
- // console.log('npsRes', npsRes);
|
|
|
|
|
|
+ handleBreath(request) {
|
|
|
|
+ const npsRes = this.moveService.getBreakPoints(request);
|
|
|
|
+ console.log('npsRes', npsRes);
|
|
this.streamService.pushNormalDataToStream(npsRes);
|
|
this.streamService.pushNormalDataToStream(npsRes);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -745,6 +743,9 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
});
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ /**
|
|
|
|
+ * rotate 推送队列
|
|
|
|
+ */
|
|
handleRotateStream() {
|
|
handleRotateStream() {
|
|
if (!this.roQueueSubscription) {
|
|
if (!this.roQueueSubscription) {
|
|
this.roQueueSubscription = this.roQueue.subscribe(
|
|
this.roQueueSubscription = this.roQueue.subscribe(
|
|
@@ -771,8 +772,7 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
if (res.done) {
|
|
if (res.done) {
|
|
clearTimeout(this._rotateTimeout);
|
|
clearTimeout(this._rotateTimeout);
|
|
this._rotateTimeout = setTimeout(() => {
|
|
this._rotateTimeout = setTimeout(() => {
|
|
- console.log('rotate 1秒', Date.now());
|
|
|
|
- console.log('rotate end');
|
|
|
|
|
|
+ console.log('rotate end', Date.now());
|
|
// const next = res.frame + 1;
|
|
// const next = res.frame + 1;
|
|
this.frameCnt.next(res.frame);
|
|
this.frameCnt.next(res.frame);
|
|
this.resumeStream();
|
|
this.resumeStream();
|