|
@@ -25,19 +25,21 @@ 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,
|
|
|
- ) {}
|
|
|
+ ) { }
|
|
|
@Client(grpcClientOptions) private readonly client: ClientGrpc;
|
|
|
|
|
|
public _frameInteval: NodeJS.Timeout;
|
|
|
public _frameTimeout: NodeJS.Timeout;
|
|
|
public _rotateTimeout: NodeJS.Timeout;
|
|
|
public _moveTimeout: NodeJS.Timeout;
|
|
|
+ public _JoyStickingTimeout: NodeJS.Timeout;
|
|
|
public startSteaming = new BehaviorSubject<boolean>(false);
|
|
|
public onRotating = new BehaviorSubject<boolean>(false);
|
|
|
public onMoving = new BehaviorSubject<boolean>(false);
|
|
|
public frameCnt = new BehaviorSubject<number>(-1);
|
|
|
private rotateframeCnt = -1;
|
|
|
private moveframeCnt = -1;
|
|
|
+ private joystickFrameCnt = -1;
|
|
|
private moveKeyFrame = -1;
|
|
|
|
|
|
private sceneGrpcService: SceneGrpcService;
|
|
@@ -308,15 +310,12 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
|
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,
|
|
|
+ DIR: 3,
|
|
|
};
|
|
|
// console.log('rotate', stream, Date.now());
|
|
|
clearTimeout(this._rotateTimeout);
|
|
@@ -502,7 +501,11 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
|
* joystick main core
|
|
|
*/
|
|
|
async joystick(request: JoystickRequest) {
|
|
|
- this.handlejoystick(request);
|
|
|
+ // TODO hasJoystickMoveRequest中断
|
|
|
+ console.log('this.hasJoystickMoveRequest', this.hasJoystickMoveRequest);
|
|
|
+ if (!this.hasJoystickMoveRequest) {
|
|
|
+ this.handlejoystick(request);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/***
|
|
@@ -546,13 +549,13 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
|
metaData: item,
|
|
|
});
|
|
|
}
|
|
|
- console.log(
|
|
|
- 'joystick:' +
|
|
|
- JSON.stringify(
|
|
|
- joystickRes[i][index]['newUserStates'][0].playerState
|
|
|
- .camera.position,
|
|
|
- ),
|
|
|
- );
|
|
|
+ // console.log(
|
|
|
+ // 'joystick:' +
|
|
|
+ // JSON.stringify(
|
|
|
+ // joystickRes[i][index]['newUserStates'][0].playerState
|
|
|
+ // .camera.position,
|
|
|
+ // ),
|
|
|
+ // );
|
|
|
},
|
|
|
);
|
|
|
}
|
|
@@ -560,26 +563,41 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
|
const seqs = Array.from(joystickRes).flat() as any as StreamReplyType[];
|
|
|
|
|
|
if (seqs?.length > 1) {
|
|
|
+ console.log('joystick:-seqs', seqs.length);
|
|
|
//TODO joystick中断逻辑
|
|
|
- console.log('joystickRes-seqs', seqs.length);
|
|
|
- // hasJoystickMoveRequest是待数组move完成后接收新的数组
|
|
|
- if (!this.hasJoystickMoveRequest) {
|
|
|
- this.hasJoystickMoveRequest = true;
|
|
|
- this.handleSeqMoving(seqs);
|
|
|
- }
|
|
|
+ this.hasJoystickMoveRequest = true;
|
|
|
+ this.handleSeqMoving(seqs);
|
|
|
} else {
|
|
|
console.warn('joystick-move无数据');
|
|
|
}
|
|
|
} else {
|
|
|
- console.log(
|
|
|
- 'joystick:' +
|
|
|
- '->' +
|
|
|
- JSON.stringify(
|
|
|
- joystickRes['newUserStates'][0].playerState.camera.position,
|
|
|
- ),
|
|
|
- );
|
|
|
- // console.warn('joystick-接收人物数据', JSON.stringify(joystickRes));
|
|
|
- // this.streamService.pushNormalDataToStream(joystickRes);
|
|
|
+ console.warn('joystick-接收人物数据', this.onMoving);
|
|
|
+ if (!this.onMoving.value) {
|
|
|
+ this.holdSteam();
|
|
|
+ if (this.joystickFrameCnt === -1) {
|
|
|
+ this.joystickFrameCnt = this.frameCnt.getValue();
|
|
|
+ }
|
|
|
+ this.joystickFrameCnt += 1;
|
|
|
+ const stream: StreamMetaType = {
|
|
|
+ frame: this.joystickFrameCnt,
|
|
|
+ metaData: JSON.stringify(joystickRes),
|
|
|
+ };
|
|
|
+ // console.log('rotate', stream, Date.now());
|
|
|
+ clearTimeout(this._JoyStickingTimeout);
|
|
|
+ const res = await this.streamService.pushMetaDataToSteam(stream);
|
|
|
+ if (res.done) {
|
|
|
+ console.log('joystick-frame', res.frame);
|
|
|
+ this.frameCnt.next(res.frame);
|
|
|
+ this._JoyStickingTimeout = setTimeout(() => {
|
|
|
+ console.log('joystick opt done');
|
|
|
+ console.log('joystick 交权给空流,当前pts', res.frame);
|
|
|
+ const next = res.frame + 1;
|
|
|
+ this.frameCnt.next(next);
|
|
|
+ this.resumeStream();
|
|
|
+ this.joystickFrameCnt = -1;
|
|
|
+ }, 300);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
} catch (error) {
|
|
|
console.error('joystick错误', error);
|
|
@@ -597,6 +615,8 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
|
console.log('moving-seqs', seqs.length);
|
|
|
this.onMoving.next(true);
|
|
|
this.holdSteam();
|
|
|
+ //TODO Remove
|
|
|
+ clearTimeout(this._JoyStickingTimeout);
|
|
|
|
|
|
seqs.forEach((frame: StreamReplyType) => {
|
|
|
const mediaSrc = frame.mediaSrc;
|
|
@@ -613,7 +633,6 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
|
DIR: frame.DIR,
|
|
|
mType: type,
|
|
|
};
|
|
|
- console.log('this.lastMovingPointArray', this.lastMovingPointArray);
|
|
|
this.moveQueue.next(stream);
|
|
|
});
|
|
|
}
|
|
@@ -638,7 +657,7 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
|
const metaData: StreamReplyType = JSON.parse(stream.metaData);
|
|
|
|
|
|
if (this.moveframeCnt === -1) {
|
|
|
- this.moveframeCnt = this.frameCnt.value;
|
|
|
+ this.moveframeCnt = this.frameCnt.getValue();
|
|
|
}
|
|
|
this.moveframeCnt += 1;
|
|
|
this.latestBreakPointId = metaData.endBreakPointId;
|
|
@@ -650,19 +669,22 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
|
serverTime: this.mockserverTime,
|
|
|
DIR: stream.DIR,
|
|
|
};
|
|
|
- this.logger.log(
|
|
|
- '[media-rotate]: ' +
|
|
|
- ', moveframeCnt: ' +
|
|
|
- this.rotateframeCnt +
|
|
|
- ', clipPath: ' +
|
|
|
- stream.clipPath +
|
|
|
- ', mType: ' +
|
|
|
- stream.mType +
|
|
|
- ', DIR: ' +
|
|
|
- stream.DIR,
|
|
|
+ console.log(
|
|
|
+ '[media-move]: ' +
|
|
|
+ ', moveframeCnt: ' +
|
|
|
+ this.moveframeCnt +
|
|
|
+ ', clipPath: ' +
|
|
|
+ stream.clipPath +
|
|
|
+ ', mType: ' +
|
|
|
+ stream.mType +
|
|
|
+ ', DIR: ' +
|
|
|
+ stream.DIR,
|
|
|
// stream.metaData,
|
|
|
);
|
|
|
-
|
|
|
+ console.log(
|
|
|
+ '[media-move-lastMovingPointArray]',
|
|
|
+ this.lastMovingPointArray,
|
|
|
+ );
|
|
|
this.lastMoveStreamFrame.next(streamData);
|
|
|
const res = await this.streamService.pushFrameToSteam(streamData);
|
|
|
|
|
@@ -732,7 +754,7 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
|
? String(message).replace('wasm:', '')
|
|
|
: `{"MstType":1}`;
|
|
|
const msg: RTCMessageRequest = JSON.parse(parseData);
|
|
|
- this.logger.warn('lostIframe-message', msg);
|
|
|
+ this.logger.error('lostIframe-message', JSON.stringify(msg));
|
|
|
if (msg.MstType === 0) {
|
|
|
this.handleIframeRequest();
|
|
|
}
|
|
@@ -807,6 +829,13 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
|
);
|
|
|
if (redisMeta) {
|
|
|
redisMeta.actionType = 1024;
|
|
|
+ // console.log(
|
|
|
+ // 'joystick:->updateUserStatus' +
|
|
|
+ // 'playerPosition:' +
|
|
|
+ // JSON.stringify(
|
|
|
+ // redisMeta['newUserStates'][0].playerState.player.position,
|
|
|
+ // ),
|
|
|
+ // );
|
|
|
this.streamService.pushNormalDataToStream(redisMeta);
|
|
|
} else {
|
|
|
this.logger.error('updateUserStatus::function-empty');
|
|
@@ -815,6 +844,56 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
|
this.logger.error('updateUserStatus::function', error.message);
|
|
|
}
|
|
|
}
|
|
|
+ /**
|
|
|
+ * rotate 推送队列
|
|
|
+ */
|
|
|
+ handleRotateStream() {
|
|
|
+ if (!this.roQueueSubscription) {
|
|
|
+ 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;
|
|
|
+ this.logger.log(
|
|
|
+ '[media-rotate]: ' +
|
|
|
+ ', frame: ' +
|
|
|
+ stream.frame +
|
|
|
+ ', rotateframeCnt: ' +
|
|
|
+ this.rotateframeCnt +
|
|
|
+ ', clipPath: ' +
|
|
|
+ stream.clipPath,
|
|
|
+ // stream.metaData,
|
|
|
+ );
|
|
|
+ // 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 end', Date.now());
|
|
|
+ this.frameCnt.next(res.frame);
|
|
|
+ this.resumeStream();
|
|
|
+ this.rotateframeCnt = -1;
|
|
|
+ this.onMoving.next(false);
|
|
|
+ this.onRotating.next(false);
|
|
|
+ //TODO rotate完后清除request队列
|
|
|
+ if (this.roRequestQueueSub) {
|
|
|
+ this.roRequestQueueSub.unsubscribe();
|
|
|
+ this.roRequestQueueSub = null;
|
|
|
+ }
|
|
|
+ }, 300);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ );
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
pushFirstRender(clipPath: string, metaData: string): Promise<boolean> {
|
|
|
return new Promise<boolean>(async (resolve, reject) => {
|
|
@@ -833,7 +912,6 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
-
|
|
|
handleStream() {
|
|
|
this.logger.log('this.frameCntSubscription', this.frameCntSubscription);
|
|
|
if (!this.frameCntSubscription) {
|
|
@@ -856,7 +934,7 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
|
delete redisData.mediaSrc;
|
|
|
this.logger.log(
|
|
|
`user:${this.user_id}:first render stream` +
|
|
|
- JSON.stringify({ path: clipPath, meta: redisData }),
|
|
|
+ JSON.stringify({ path: clipPath, meta: redisData }),
|
|
|
);
|
|
|
const status = await this.pushFirstRender(
|
|
|
clipPath,
|
|
@@ -905,54 +983,4 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
- /**
|
|
|
- * rotate 推送队列
|
|
|
- */
|
|
|
- handleRotateStream() {
|
|
|
- if (!this.roQueueSubscription) {
|
|
|
- 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;
|
|
|
- this.logger.log(
|
|
|
- '[media-rotate]: ' +
|
|
|
- ', frame: ' +
|
|
|
- stream.frame +
|
|
|
- ', rotateframeCnt: ' +
|
|
|
- this.rotateframeCnt +
|
|
|
- ', clipPath: ' +
|
|
|
- stream.clipPath,
|
|
|
- // stream.metaData,
|
|
|
- );
|
|
|
- // 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 end', Date.now());
|
|
|
- this.frameCnt.next(res.frame);
|
|
|
- this.resumeStream();
|
|
|
- this.rotateframeCnt = -1;
|
|
|
- this.onMoving.next(false);
|
|
|
- this.onRotating.next(false);
|
|
|
- //TODO rotate完后清除request队列
|
|
|
- if (this.roRequestQueueSub) {
|
|
|
- this.roRequestQueueSub.unsubscribe();
|
|
|
- this.roRequestQueueSub = null;
|
|
|
- }
|
|
|
- }, 300);
|
|
|
- }
|
|
|
- },
|
|
|
- );
|
|
|
- }
|
|
|
- }
|
|
|
}
|