|
@@ -14,65 +14,6 @@ import { Queue } from 'bull';
|
|
|
import { RotateService } from 'src/rotate/rotate.service';
|
|
|
import { DelayQueue, RxQueue, ThrottleQueue, DebounceQueue } from 'rx-queue';
|
|
|
|
|
|
-const frameMetaReply = {
|
|
|
- traceIds: [''],
|
|
|
- vehicle: null,
|
|
|
- newUserStates: [
|
|
|
- {
|
|
|
- userId: 'a2aaaed1fffe6',
|
|
|
- playerState: {
|
|
|
- roomTypeId: '',
|
|
|
- person: 0,
|
|
|
- avatarId: '',
|
|
|
- skinId: '',
|
|
|
- roomId: '',
|
|
|
- isHost: false,
|
|
|
- isFollowHost: false,
|
|
|
- skinDataVersion: '',
|
|
|
- avatarComponents: '',
|
|
|
- nickName: '',
|
|
|
- movingMode: 0,
|
|
|
- attitude: '',
|
|
|
- areaName: '',
|
|
|
- pathName: '',
|
|
|
- pathId: '',
|
|
|
- avatarSize: 1,
|
|
|
- extra: '',
|
|
|
- prioritySync: false,
|
|
|
- player: {
|
|
|
- position: { x: -755, y: -1450, z: -34 },
|
|
|
- angle: { pitch: 0, yaw: 0, roll: 0 },
|
|
|
- },
|
|
|
- camera: {
|
|
|
- position: { x: -1075, y: -1450, z: 86 },
|
|
|
- angle: { pitch: 0, yaw: 0, roll: 0 },
|
|
|
- },
|
|
|
- cameraCenter: { x: -755, y: -1450, z: -34 },
|
|
|
- },
|
|
|
- renderInfo: {
|
|
|
- renderType: 0,
|
|
|
- videoFrame: null,
|
|
|
- cameraStateType: 0,
|
|
|
- isMoving: 0,
|
|
|
- needIfr: 0,
|
|
|
- isVideo: 0,
|
|
|
- stillFrame: 0,
|
|
|
- isRotating: 0,
|
|
|
- isFollowing: 0,
|
|
|
- clientPanoTitlesBitmap: [],
|
|
|
- clientPanoTreceId: '',
|
|
|
- prefetchVideoId: '',
|
|
|
- noMedia: false,
|
|
|
- },
|
|
|
- event: null,
|
|
|
- relation: 1,
|
|
|
- },
|
|
|
- ],
|
|
|
- actionResponses: [],
|
|
|
- getStateType: 0,
|
|
|
- code: 0,
|
|
|
- msg: 'OK',
|
|
|
-};
|
|
|
@Injectable()
|
|
|
export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
|
constructor(
|
|
@@ -100,14 +41,15 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
|
private frameCnt = new BehaviorSubject<number>(-1);
|
|
|
private frameCntSubscription: any;
|
|
|
private roQueueSubscription: any;
|
|
|
+ private streamServiceSub: any;
|
|
|
private roQueue: RxQueue = new ThrottleQueue(50);
|
|
|
private rotateTimeStamp: number;
|
|
|
|
|
|
- onModuleInit() {
|
|
|
+ onModuleInit(): void {
|
|
|
this.sceneGrpcService =
|
|
|
this.client.getService<SceneGrpcService>('SceneGrpcService');
|
|
|
this.logger.log('init SceneGrpcService');
|
|
|
- this.streamService.onSteaming.subscribe((val) => {
|
|
|
+ this.streamServiceSub = this.streamService.onSteaming.subscribe((val) => {
|
|
|
this.onSteaming = val;
|
|
|
});
|
|
|
Number.prototype.padLeft = function (n, str) {
|
|
@@ -115,7 +57,7 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
|
};
|
|
|
}
|
|
|
|
|
|
- startStream() {
|
|
|
+ startStream(): void {
|
|
|
clearInterval(this._frameInteval);
|
|
|
if (this.frameCnt.value === -1) {
|
|
|
this._frameInteval = setInterval(async () => {
|
|
@@ -125,7 +67,7 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- holdSteam() {
|
|
|
+ holdSteam(): void {
|
|
|
clearInterval(this._frameInteval);
|
|
|
}
|
|
|
|
|
@@ -141,7 +83,7 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
|
}, 1000);
|
|
|
}
|
|
|
|
|
|
- stopStream() {
|
|
|
+ stopStream(): void {
|
|
|
if (this.frameCntSubscription) {
|
|
|
this.frameCntSubscription.unsubscribe();
|
|
|
}
|
|
@@ -159,7 +101,9 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
|
}
|
|
|
|
|
|
onModuleDestroy() {
|
|
|
- this.streamService.onSteaming.unsubscribe();
|
|
|
+ if ('unsubscribe' in this.streamServiceSub) {
|
|
|
+ this.streamService.onSteaming.unsubscribe();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
getRoute(request: RouteRequest) {
|
|
@@ -194,26 +138,13 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
|
|
|
|
async rotate(request: RotateRequest) {
|
|
|
try {
|
|
|
- // const reply = this.sceneGrpcService.rotate(request);
|
|
|
+ this.rotateQueue.add(request, {
|
|
|
+ jobId: request.trace_id,
|
|
|
+ });
|
|
|
if (!this.onSteaming) {
|
|
|
- // const redisMeta = await this.cacheService.get(
|
|
|
- // `updateFrameMetadata:${this.user_id}`,
|
|
|
- // );
|
|
|
- // console.log('rotate信息', this.user_id, request.sampleRate);
|
|
|
-
|
|
|
const redisMeta = await this.rotateService.rotate(request);
|
|
|
- // console.log('rotate信息', redisMeta);
|
|
|
- // await this.rotateQueue.add('processFrame', request, {
|
|
|
- // jobId: request.trace_id,
|
|
|
- // });
|
|
|
- // console.log('rotate.user_id', this.user_id, redisMeta);
|
|
|
if (redisMeta && 'mediaSrc' in redisMeta) {
|
|
|
- // const meta = JSON.parse(redisMeta);
|
|
|
const mediaSrc: string = redisMeta.mediaSrc || '';
|
|
|
-
|
|
|
- // console.log('meta', meta);
|
|
|
- // console.log('mediaSrc', mediaSrc);
|
|
|
-
|
|
|
if (mediaSrc.length > 0) {
|
|
|
let src = mediaSrc.split('?')[0];
|
|
|
// 临时本地替换路经
|
|
@@ -246,52 +177,6 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // async rotate1(request: RotateRequest) {
|
|
|
- // try {
|
|
|
- // // const reply = this.sceneGrpcService.rotate(request);
|
|
|
- // // const res = await this.cacheService.publish(
|
|
|
- // // 'test',
|
|
|
- // // JSON.stringify(request),
|
|
|
- // // );
|
|
|
-
|
|
|
- // // console.log('res', res);
|
|
|
-
|
|
|
- // if (!this.onSteaming) {
|
|
|
- // this.frameCnt += 1;
|
|
|
- // this.RotateframeCnt = this.frameCnt;
|
|
|
- // // this.cacheService
|
|
|
- // this.testFrame += 3;
|
|
|
- // this.mockserverTime += 1;
|
|
|
- // this.onSteaming = true;
|
|
|
- // if (this.testFrame > 358) this.testFrame = 0;
|
|
|
- // const stream: StreamFrameType = {
|
|
|
- // frame: this.frameCnt,
|
|
|
- // clipPath: path.join(
|
|
|
- // __dirname,
|
|
|
- // `../ws/video/100/100.${this.testFrame.padLeft(4, '0')}.h264`,
|
|
|
- // ),
|
|
|
- // metaData: JSON.stringify(frameMetaReply),
|
|
|
- // serverTime: this.mockserverTime,
|
|
|
- // DIR: 3,
|
|
|
- // };
|
|
|
- // console.log('stream', this.frameCnt, stream.clipPath);
|
|
|
- // this.streamService.pushFrameToSteam(stream);
|
|
|
- // // const redisMeta = await this.cacheService.rpop(
|
|
|
- // // `updateFrameMetadata:${this.user_id}`,
|
|
|
- // // );
|
|
|
- // }
|
|
|
- // // reply.subscribe((res: NormalReply) => {
|
|
|
- // // if (res.code === 200) {
|
|
|
- // // }
|
|
|
- // // });
|
|
|
- // } catch (error) {
|
|
|
- // this.logger.error(
|
|
|
- // `rotate-${this.frameCnt},src:${this.testFrame}`,
|
|
|
- // JSON.stringify(error),
|
|
|
- // );
|
|
|
- // }
|
|
|
- // }
|
|
|
-
|
|
|
joystick(request: JoystickRequest) {
|
|
|
return this.sceneGrpcService.joystick(request);
|
|
|
}
|
|
@@ -299,14 +184,12 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
|
handleDataChanelOpen(channel: DataChannel): void {
|
|
|
this.channel = channel;
|
|
|
this.streamService.setChannel(channel);
|
|
|
- // this.handleStartCountingFrame();
|
|
|
this.startSteaming.next(true);
|
|
|
this.startStream();
|
|
|
this.handleStream();
|
|
|
}
|
|
|
|
|
|
handleDataChanelClose(): void {
|
|
|
- // this.stopCountingFrame();
|
|
|
this.stopStream();
|
|
|
this.startSteaming.next(false);
|
|
|
this.streamService.closeChannel();
|
|
@@ -598,120 +481,84 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
|
};
|
|
|
this.streamService.pushNormalDataToStream(reply);
|
|
|
}
|
|
|
-
|
|
|
async updateUserStatus(request) {
|
|
|
- // console.log('1024', request);
|
|
|
- const reply = {
|
|
|
- actionType: 1024,
|
|
|
- pointType: 100,
|
|
|
- extra: '',
|
|
|
- traceId: request.trace_id,
|
|
|
- packetId: '',
|
|
|
- nps: [],
|
|
|
- peopleNum: 0,
|
|
|
- zoneId: '',
|
|
|
- echoMsg: '',
|
|
|
- reserveDetail: null,
|
|
|
- userWithAvatarList: [],
|
|
|
- newUserStates: [
|
|
|
- {
|
|
|
- userId: 'e497b92704f5a',
|
|
|
- playerState: {
|
|
|
- roomTypeId: '',
|
|
|
- person: 0,
|
|
|
- avatarId: 'KGe_Boy',
|
|
|
- skinId: '10089',
|
|
|
- roomId: 'e629ef3e-022d-4e64-8654-703bb96410eb',
|
|
|
- isHost: false,
|
|
|
- isFollowHost: false,
|
|
|
- skinDataVersion: '1008900008',
|
|
|
- avatarComponents: '',
|
|
|
- nickName: 'e497b92704f5a',
|
|
|
- movingMode: 0,
|
|
|
- attitude: 'walk',
|
|
|
- areaName: '',
|
|
|
- pathName: 'thirdwalk',
|
|
|
- pathId: 'thirdwalk',
|
|
|
- avatarSize: 1,
|
|
|
- extra: '{"removeWhenDisconnected":true}',
|
|
|
- prioritySync: false,
|
|
|
- avatarURL: '',
|
|
|
- micStatus: 0,
|
|
|
- player: {
|
|
|
- position: { x: -755, y: -1450, z: -34 },
|
|
|
- angle: { pitch: 0, yaw: 0, roll: 0 },
|
|
|
- },
|
|
|
- camera: null,
|
|
|
- cameraCenter: null,
|
|
|
- },
|
|
|
- renderInfo: {
|
|
|
- renderType: 0,
|
|
|
- videoFrame: null,
|
|
|
- cameraStateType: 0,
|
|
|
- isMoving: 0,
|
|
|
- needIfr: 0,
|
|
|
- isVideo: 0,
|
|
|
- stillFrame: 0,
|
|
|
- isRotating: 0,
|
|
|
- isFollowing: 0,
|
|
|
- clientPanoTitlesBitmap: [],
|
|
|
- clientPanoTreceId: '',
|
|
|
- prefetchVideoId: '',
|
|
|
- noMedia: false,
|
|
|
- },
|
|
|
- event: {
|
|
|
- id: '',
|
|
|
- type: 0,
|
|
|
- points: [],
|
|
|
- rotateEvent: null,
|
|
|
- removeVisitorEvent: null,
|
|
|
- },
|
|
|
- relation: 0,
|
|
|
- },
|
|
|
- ],
|
|
|
- code: 0,
|
|
|
- msg: '',
|
|
|
- };
|
|
|
- const redisMeta = await this.cacheService.get(
|
|
|
- `updateFrameMetadata:${this.user_id}`,
|
|
|
- );
|
|
|
- //TODO 接入redis数据
|
|
|
- console.log(
|
|
|
- 'redisMeta',
|
|
|
- redisMeta && redisMeta.length,
|
|
|
- `updateFrameMetadata:${this.user_id}`,
|
|
|
- );
|
|
|
-
|
|
|
- if (redisMeta && redisMeta.length > 0) {
|
|
|
- console.log('updateUserStatus-真数据', redisMeta && redisMeta.length);
|
|
|
- const meta = JSON.parse(redisMeta);
|
|
|
- 'mediaSrc' in meta && delete meta.mediaSrc;
|
|
|
- meta.action_type = 1024;
|
|
|
- this.streamService.pushNormalDataToStream(redisMeta);
|
|
|
- } else {
|
|
|
- this.streamService.pushNormalDataToStream(reply);
|
|
|
+ try {
|
|
|
+ //TODO 接入redis数据
|
|
|
+ const redisMeta = await this.rotateService.getNewUserStateRequest(
|
|
|
+ request,
|
|
|
+ );
|
|
|
+ if (redisMeta) {
|
|
|
+ redisMeta.actionType = 1024;
|
|
|
+ this.streamService.pushNormalDataToStream(redisMeta);
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ this.logger.error('updateUserStatus::function', error);
|
|
|
}
|
|
|
- // this.streamService.pushNormalDataToStream(reply);
|
|
|
}
|
|
|
|
|
|
- handleStream() {
|
|
|
- this.frameCntSubscription = this.frameCnt.subscribe((frame) => {
|
|
|
- console.log('frame', frame);
|
|
|
- if (frame === 1) {
|
|
|
- const stream: StreamFrameType = {
|
|
|
+ pushFirstRender(clipPath: string, metaData: string): Promise<boolean> {
|
|
|
+ return new Promise<boolean>(async (resolve, reject) => {
|
|
|
+ try {
|
|
|
+ const streamData: StreamFrameType = {
|
|
|
frame: 1,
|
|
|
- clipPath: path.join(__dirname, '../ws/video/100/100.0000.h264'),
|
|
|
- metaData: JSON.stringify(frameMetaReply),
|
|
|
+ clipPath: clipPath,
|
|
|
+ metaData: metaData,
|
|
|
serverTime: this.mockserverTime,
|
|
|
};
|
|
|
- this.streamService.pushFrameToSteam(stream);
|
|
|
+ const hasPush = await this.streamService.pushFrameToSteam(streamData);
|
|
|
+ return resolve(hasPush);
|
|
|
+ } catch (error) {
|
|
|
+ return reject(false);
|
|
|
}
|
|
|
- if (frame > 1 && !this.onSteaming) {
|
|
|
- const streamMeta: StreamMetaType = {
|
|
|
- frame: frame,
|
|
|
- metaData: JSON.stringify(frameMetaReply),
|
|
|
- };
|
|
|
- this.streamService.pushMetaDataToSteam(streamMeta);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ handleStream() {
|
|
|
+ this.frameCntSubscription = this.frameCnt.subscribe(async (frame) => {
|
|
|
+ try {
|
|
|
+ console.log('frame', frame);
|
|
|
+ if (frame === 1) {
|
|
|
+ const redisData = await this.rotateService.echo(this.user_id);
|
|
|
+ if (redisData && 'mediaSrc' in redisData) {
|
|
|
+ const mediaSrc: string = redisData.mediaSrc || '';
|
|
|
+ if (mediaSrc.length > 0) {
|
|
|
+ let src = mediaSrc.split('?')[0];
|
|
|
+ // 临时本地替换路经
|
|
|
+ src = src.replace('/0000000001/100/', '');
|
|
|
+ const clipPath = path.join(__dirname, `../ws/video/${src}`);
|
|
|
+ delete redisData.mediaSrc;
|
|
|
+
|
|
|
+ this.logger.log(
|
|
|
+ `${this.user_id}:first render stream`,
|
|
|
+ JSON.stringify({ path: clipPath, meta: redisData }),
|
|
|
+ );
|
|
|
+
|
|
|
+ this.holdSteam();
|
|
|
+ const status = await this.pushFirstRender(
|
|
|
+ clipPath,
|
|
|
+ JSON.stringify(redisData),
|
|
|
+ );
|
|
|
+ if (status) {
|
|
|
+ this.resumeStream(2);
|
|
|
+ } else {
|
|
|
+ this.logger.error('first render problem', status);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (frame > 1 && !this.onSteaming) {
|
|
|
+ const redisDataAuto = await this.rotateService.echo(this.user_id);
|
|
|
+ if (redisDataAuto) {
|
|
|
+ const streamMeta: StreamMetaType = {
|
|
|
+ frame: frame,
|
|
|
+ metaData: JSON.stringify(redisDataAuto),
|
|
|
+ };
|
|
|
+ this.streamService.pushMetaDataToSteam(streamMeta);
|
|
|
+ } else {
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ this.logger.error('handleStream', error);
|
|
|
}
|
|
|
});
|
|
|
|
|
@@ -724,7 +571,11 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
|
}
|
|
|
this.rotateframeCnt += 1;
|
|
|
stream.frame = this.rotateframeCnt;
|
|
|
- console.log('this.rotateframeCnt', this.rotateframeCnt);
|
|
|
+ console.log(
|
|
|
+ 'roQueueSubscription \n',
|
|
|
+ this.rotateframeCnt,
|
|
|
+ stream.metaData,
|
|
|
+ );
|
|
|
await this.streamService.pushFrameToSteam(stream);
|
|
|
setTimeout(() => {
|
|
|
const now = Date.now();
|
|
@@ -737,37 +588,4 @@ export class SceneService implements OnModuleInit, OnModuleDestroy {
|
|
|
},
|
|
|
);
|
|
|
}
|
|
|
-
|
|
|
- // handleStartCountingFrame() {
|
|
|
- // this._frameInteval = setInterval(async () => {
|
|
|
- // this.frameCnt += 1;
|
|
|
- // try {
|
|
|
- // if (this.frameCnt === 1) {
|
|
|
- // // this.pushTheFirstFrame();
|
|
|
- // const stream: StreamFrameType = {
|
|
|
- // frame: 1,
|
|
|
- // clipPath: path.join(__dirname, '../ws/video/100/100.0000.h264'),
|
|
|
- // metaData: JSON.stringify(frameMetaReply),
|
|
|
- // serverTime: this.mockserverTime,
|
|
|
- // };
|
|
|
- // this.streamService.pushFrameToSteam(stream);
|
|
|
- // }
|
|
|
-
|
|
|
- // if (this.frameCnt > 1 && !this.onSteaming) {
|
|
|
- // const streamMeta: StreamMetaType = {
|
|
|
- // frame: this.frameCnt,
|
|
|
- // metaData: JSON.stringify(frameMetaReply),
|
|
|
- // };
|
|
|
- // this.streamService.pushMetaDataToSteam(streamMeta);
|
|
|
- // }
|
|
|
- // } catch (error) {
|
|
|
- // console.log('error', error);
|
|
|
- // }
|
|
|
- // }, this.frameCntInterval);
|
|
|
- // }
|
|
|
-
|
|
|
- // stopCountingFrame(): void {
|
|
|
- // clearInterval(this._frameInteval);
|
|
|
- // this.frameCnt = -1;
|
|
|
- // }
|
|
|
}
|