|
@@ -15,7 +15,6 @@ import { DelayQueue, RxQueue, ThrottleQueue, DebounceQueue } from 'rx-queue';
|
|
|
import { MoveService } from 'src/move/move.service';
|
|
|
import { GetRouterService } from 'src/get-router/get-router.service';
|
|
|
import { ConfigService } from '@nestjs/config';
|
|
|
-import { join } from 'path';
|
|
|
|
|
|
@Injectable()
|
|
|
export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
@@ -39,6 +38,7 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
|
public frameCnt = new BehaviorSubject<number>(-1);
|
|
|
private rotateframeCnt = -1;
|
|
|
private moveframeCnt = -1;
|
|
|
+ private moveKeyFrame = -1;
|
|
|
|
|
|
private sceneGrpcService: SceneGrpcService;
|
|
|
private channel: DataChannel;
|
|
@@ -59,8 +59,8 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
|
private clickQueueSub: any;
|
|
|
|
|
|
private streamServiceSub: any;
|
|
|
- private roRequestQueue: RxQueue = new DelayQueue(25);
|
|
|
- private roQueue: RxQueue = new DelayQueue(6);
|
|
|
+ // private roRequestQueue: RxQueue = new DelayQueue(25);
|
|
|
+ private roQueue: RxQueue = new DelayQueue(25);
|
|
|
private clickQueue: RxQueue = new DebounceQueue(500);
|
|
|
private moveQueue: RxQueue = new DelayQueue(20);
|
|
|
private joystickQueue: RxQueue = new DebounceQueue(500);
|
|
@@ -132,6 +132,14 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
|
};
|
|
|
}
|
|
|
|
|
|
+ public isHeaderOrLast(index: number, length: number): boolean {
|
|
|
+ if (index === 0 || index === length) {
|
|
|
+ return true;
|
|
|
+ } else {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
public getConfig() {
|
|
|
return {
|
|
|
userId: this.user_id,
|
|
@@ -220,102 +228,97 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
|
}
|
|
|
|
|
|
async rotate(request: RotateRequest) {
|
|
|
- this.roRequestQueue.next(request);
|
|
|
- if (!this.roRequestQueueSub) {
|
|
|
- this.handleRotate();
|
|
|
- }
|
|
|
+ this.handleRotate(request);
|
|
|
+ // console.log('request', request)
|
|
|
+ // this.roRequestQueue.next(request);
|
|
|
+ // if (!this.roRequestQueueSub) {
|
|
|
+ // this.handleRotate();
|
|
|
+ // }
|
|
|
}
|
|
|
/**
|
|
|
* rotate请求队列
|
|
|
*/
|
|
|
|
|
|
- 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 {
|
|
|
- redisMeta = await this.rotateService.rotate(request);
|
|
|
- }
|
|
|
+ async handleRotate(request) {
|
|
|
+ // this.roRequestQueueSub = this.roRequestQueue.subscribe(
|
|
|
+ // async (request: RotateRequest) => {
|
|
|
|
|
|
- if (redisMeta && 'mediaSrc' in redisMeta) {
|
|
|
- const mediaSrc: string = redisMeta.mediaSrc || '';
|
|
|
- if (mediaSrc.length > 0) {
|
|
|
- const src = mediaSrc.split('?')[0];
|
|
|
+ try {
|
|
|
+ if (this.firstRender) {
|
|
|
+ if (!this.roQueueSubscription) {
|
|
|
+ this.handleRotateStream();
|
|
|
+ }
|
|
|
+ let redisMeta: StreamReplyType;
|
|
|
+ this.onRotating.next(true);
|
|
|
+ // 当move时处理
|
|
|
+ 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 {
|
|
|
+ // 正常rotate
|
|
|
+ redisMeta = await this.rotateService.seqExeRotate(request);
|
|
|
+ // console.log(redisMeta);
|
|
|
+ //debugger;
|
|
|
+ }
|
|
|
|
|
|
- if (src.length > 0) {
|
|
|
- // console.log('不同源');
|
|
|
- this.holdSteam();
|
|
|
- this.lastRenderMedia = src;
|
|
|
- const clipPath = this.configService.get('app.prefix') + src;
|
|
|
- //TODO 临时开出
|
|
|
- // 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);
|
|
|
- }
|
|
|
- }
|
|
|
+ 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;
|
|
|
+ //TODO 临时开出
|
|
|
+ // 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) {
|
|
@@ -335,6 +338,7 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
|
user.breakPointId,
|
|
|
req.clicking_action.clicking_point,
|
|
|
);
|
|
|
+ console.log('walking-path', path);
|
|
|
if (!path) {
|
|
|
console.log('不存在--path', path);
|
|
|
this.resumeStream();
|
|
@@ -348,43 +352,49 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
|
if (walkingRes && !this.onMoving.value) {
|
|
|
// console.log('walkingRes-front', walkingRes);
|
|
|
// shift出前第一个镜头数据
|
|
|
- const rotateCamData = walkingRes.shift();
|
|
|
-
|
|
|
+ const rotateCamData = walkingRes[0];
|
|
|
console.log('rotateCamData', rotateCamData.length);
|
|
|
-
|
|
|
if (rotateCamData?.length) {
|
|
|
- rotateCamData.forEach((item: StreamReplyType) => {
|
|
|
- item.type = 'rotate';
|
|
|
+ // 头数组[0] rotate 序列, 头是关键key
|
|
|
+ walkingRes[0].forEach((item: StreamReplyType, index: number) => {
|
|
|
+ item.mType = 'rotate';
|
|
|
+ item.DIR = index === 0 ? 1 : 3;
|
|
|
});
|
|
|
} else {
|
|
|
console.log('rotateCamData无数据');
|
|
|
}
|
|
|
+
|
|
|
+ // 二维数组 做move 序列, move类型
|
|
|
+ for (let i = 1; i < walkingRes.length; i++) {
|
|
|
+ console.log('walkingRes', walkingRes[i]);
|
|
|
+ Array.from(walkingRes[i]).forEach(
|
|
|
+ (item: StreamReplyType, index: number) => {
|
|
|
+ const dir = this.isHeaderOrLast(index, walkingRes[i].length - 1);
|
|
|
+ item.DIR = dir ? 1 : 3;
|
|
|
+ },
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
// walkingRes marker to everybody
|
|
|
const seqs = Array.from(
|
|
|
walkingRes,
|
|
|
).flat() as any as StreamReplyType[];
|
|
|
|
|
|
- if (rotateCamData?.length || seqs?.length) {
|
|
|
- const lastSeq = rotateCamData?.length
|
|
|
- ? (Array.from(rotateCamData).concat(
|
|
|
- seqs,
|
|
|
- ) as any as StreamReplyType[])
|
|
|
- : seqs;
|
|
|
-
|
|
|
+ if (seqs?.length) {
|
|
|
console.log('walking --总序列--seqs-2', seqs.length);
|
|
|
- this.handleSeqMoving(lastSeq);
|
|
|
+ this.handleSeqMoving(seqs);
|
|
|
} else {
|
|
|
console.error('walking-move无数据');
|
|
|
this.cleanMoveSteam();
|
|
|
+ this.resumeStream();
|
|
|
}
|
|
|
- // debugger;
|
|
|
- // this.lastMoveCnt = this.frameCnt.value + seqs.length;
|
|
|
}
|
|
|
});
|
|
|
// }
|
|
|
} catch (error) {
|
|
|
this.logger.error('walking', error);
|
|
|
this.cleanMoveSteam();
|
|
|
+ this.resumeStream();
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -405,23 +415,36 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
|
const rotateCamData = joystickRes.shift();
|
|
|
console.log('rotateCamData', rotateCamData.length);
|
|
|
if (rotateCamData?.length) {
|
|
|
- rotateCamData.forEach((item: StreamReplyType) => {
|
|
|
- item.type = 'rotate';
|
|
|
- });
|
|
|
+ // 头数组[0] rotate 序列, 头是关键key
|
|
|
+ joystickRes[0].forEach(
|
|
|
+ (item: StreamReplyType, index: number) => {
|
|
|
+ item.mType = 'rotate';
|
|
|
+ item.DIR = index === 0 ? 1 : 3;
|
|
|
+ },
|
|
|
+ );
|
|
|
+ } else {
|
|
|
+ console.log('rotateCamData无数据');
|
|
|
+ }
|
|
|
+ // 二维数组 做move 序列, move类型
|
|
|
+ for (let i = 1; i < joystickRes.length; i++) {
|
|
|
+ console.log('walkingRes', joystickRes[i]);
|
|
|
+ Array.from(joystickRes[i]).forEach(
|
|
|
+ (item: StreamReplyType, index: number) => {
|
|
|
+ const dir = this.isHeaderOrLast(
|
|
|
+ index,
|
|
|
+ joystickRes[i].length - 1,
|
|
|
+ );
|
|
|
+ item.DIR = dir ? 1 : 3;
|
|
|
+ },
|
|
|
+ );
|
|
|
}
|
|
|
-
|
|
|
const seqs = Array.from(
|
|
|
joystickRes,
|
|
|
).flat() as any as StreamReplyType[];
|
|
|
|
|
|
- if (seqs?.length || rotateCamData?.length) {
|
|
|
+ if (seqs?.length) {
|
|
|
console.log('joystickRes-seqs', seqs.length);
|
|
|
- const lastSeq = rotateCamData?.length
|
|
|
- ? (Array.from(rotateCamData).concat(
|
|
|
- seqs,
|
|
|
- ) as any as StreamReplyType[])
|
|
|
- : seqs;
|
|
|
- this.handleSeqMoving(lastSeq);
|
|
|
+ this.handleSeqMoving(seqs);
|
|
|
} else {
|
|
|
console.warn('joystick-move无数据');
|
|
|
}
|
|
@@ -448,28 +471,20 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
|
this.onMoving.next(true);
|
|
|
this.holdSteam();
|
|
|
|
|
|
- seqs.forEach((frame: StreamReplyType, index: number) => {
|
|
|
+ seqs.forEach((frame: StreamReplyType) => {
|
|
|
const mediaSrc = frame.mediaSrc;
|
|
|
const src = mediaSrc.split('?')[0];
|
|
|
- // 临时本地替换路经
|
|
|
- // const clipPath = join(__dirname, `../ws/${src}`);
|
|
|
- // const clipPath = src;
|
|
|
+
|
|
|
const clipPath = this.configService.get('app.prefix') + src;
|
|
|
- const type = frame.type?.length ? frame.type.slice() : 'move';
|
|
|
-
|
|
|
- console.log('type', frame.type);
|
|
|
- // delete frame.mediaSrc;
|
|
|
- delete frame.type;
|
|
|
- //TODO IDR
|
|
|
- const random_index = index === 0 ? 1 : 3;
|
|
|
- console.log('move frame DIR %s', random_index);
|
|
|
+ const type = frame.mType?.length ? frame.mType.slice() : 'move';
|
|
|
+
|
|
|
const stream: StreamFrameType = {
|
|
|
frame: -1,
|
|
|
clipPath: clipPath,
|
|
|
metaData: JSON.stringify(frame),
|
|
|
serverTime: this.mockserverTime,
|
|
|
- DIR: random_index,
|
|
|
- type: type,
|
|
|
+ DIR: frame.DIR,
|
|
|
+ mType: type,
|
|
|
};
|
|
|
this.moveQueue.next(stream);
|
|
|
});
|
|
@@ -500,30 +515,20 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
|
}
|
|
|
this.moveframeCnt += 1;
|
|
|
this.latestBreakPointId = metaData.breakPointId;
|
|
|
- // if (this.onMoving) {
|
|
|
- // this.frameCnt.next(this.moveframeCnt);
|
|
|
- // } else {
|
|
|
- // console.log(
|
|
|
- // 'handleMoveSteam stop',
|
|
|
- // this.moveframeCnt,
|
|
|
- // this.currentMoveMaker,
|
|
|
- // );
|
|
|
- // this.cleanMoveSteam();
|
|
|
- // this.resumeStream();
|
|
|
- // return;
|
|
|
- // }
|
|
|
+
|
|
|
const streamData: StreamFrameType = {
|
|
|
frame: this.moveframeCnt,
|
|
|
clipPath: stream.clipPath,
|
|
|
metaData: stream.metaData,
|
|
|
serverTime: this.mockserverTime,
|
|
|
- DIR: 3,
|
|
|
+ DIR: stream.DIR,
|
|
|
};
|
|
|
console.log(
|
|
|
'[media-move]',
|
|
|
this.moveframeCnt,
|
|
|
stream.clipPath,
|
|
|
- stream.type,
|
|
|
+ stream.mType,
|
|
|
+ stream.DIR,
|
|
|
);
|
|
|
|
|
|
this.lastMoveStreamFrame.next(streamData);
|