gemercheung 3 years ago
parent
commit
29d62538f8
5 changed files with 227 additions and 134 deletions
  1. 1 1
      config.yaml
  2. 46 0
      src/move/move.service.ts
  3. 11 0
      src/rotate/rotate.service.ts
  4. 122 94
      src/scene/scene.service.ts
  5. 47 39
      src/scene/stream/stream.service.ts

+ 1 - 1
config.yaml

@@ -2,7 +2,7 @@ app:
   prefix: /mnt/metaverse/scene
 
 queueConfig:
-  move: 10
+  move: 15
   rotate: 5
 
 http:

+ 46 - 0
src/move/move.service.ts

@@ -648,10 +648,22 @@ export class MoveService implements OnModuleInit {
           },
           playerPosition,
         );
+        console.log(
+          'joystick:->' +
+            'playerPosition:' +
+            JSON.stringify(
+              this.reply['newUserStates'][0].playerState.player.position,
+            ) +
+            ',cameraPosition:' +
+            JSON.stringify(
+              this.reply['newUserStates'][0].playerState.camera.position,
+            ),
+        );
         if (_angle > -90 && _angle < 90) {
           return this.reply;
         } else {
           //投影
+          console.error('补充!');
           return this.reply;
         }
       }
@@ -708,6 +720,17 @@ export class MoveService implements OnModuleInit {
           JSON.stringify(playerPosition),
         );
       } else {
+        console.log(
+          'joystick:->' +
+            'playerPosition:' +
+            JSON.stringify(
+              this.reply['newUserStates'][0].playerState.player.position,
+            ) +
+            ',cameraPosition:' +
+            JSON.stringify(
+              this.reply['newUserStates'][0].playerState.camera.position,
+            ),
+        );
         return this.reply;
       }
 
@@ -729,12 +752,34 @@ export class MoveService implements OnModuleInit {
       }
 
       if (chooseBreakPointId == null) {
+        console.log(
+          'joystick:->' +
+            'playerPosition:' +
+            JSON.stringify(
+              this.reply['newUserStates'][0].playerState.player.position,
+            ) +
+            ',cameraPosition:' +
+            JSON.stringify(
+              this.reply['newUserStates'][0].playerState.camera.position,
+            ),
+        );
         return this.reply;
       }
       //判断人物离该邻接点的距离是否在最小路径内,如果是,跳到这个邻接点里
       //相机纠正加过渡
       else {
         if (chooseBreakPointId == user.breakPointId) {
+          console.log(
+            'joystick:->' +
+              'playerPosition:' +
+              JSON.stringify(
+                this.reply['newUserStates'][0].playerState.player.position,
+              ) +
+              ',cameraPosition:' +
+              JSON.stringify(
+                this.reply['newUserStates'][0].playerState.camera.position,
+              ),
+          );
           return this.reply;
         }
         angle = user.camera.angle.yaw % 45; //纠正需要
@@ -745,6 +790,7 @@ export class MoveService implements OnModuleInit {
           traceId,
           actionType,
         );
+        console.log('joystick:过渡');
         replys.push(checkReplys);
 
         //读redis里的数据,按照frame_index的大小排序

+ 11 - 0
src/rotate/rotate.service.ts

@@ -479,6 +479,17 @@ export class RotateService {
           '?m=' +
           new Date().getTime();
         reply.breakPointId = user.breakPointId;
+        // console.log(
+        //   'joystick:->echo' +
+        //     'playerPosition:' +
+        //     JSON.stringify(
+        //       reply['newUserStates'][0].playerState.player.position,
+        //     ) +
+        //     ',cameraPosition:' +
+        //     JSON.stringify(
+        //       reply['newUserStates'][0].playerState.camera.position,
+        //     ),
+        // );
         return reply;
       } else {
         this.logger.error('echo返回null', key);

+ 122 - 94
src/scene/scene.service.ts

@@ -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);
-          }
-        },
-      );
-    }
-  }
 }

+ 47 - 39
src/scene/stream/stream.service.ts

@@ -44,46 +44,54 @@ export class StreamService {
    * stream core push with block meta stream
    * @param data meta Json
    */
-  pushMetaDataToSteam(stream: StreamMetaType) {
-    try {
-      const metaData = stream.metaData;
-      const frame = stream.frame;
-      const metaDataBin = metaData.replace(/\s/g, '');
-      const buff = Buffer.from(metaDataBin, 'utf-8');
-
-      // const block = 36;
-      const blockBuff = Buffer.alloc(this.block);
-      const packBuffer = Buffer.concat([blockBuff, buff]);
-
-      const statusPack = new DataView(
-        packBuffer.buffer.slice(
-          packBuffer.byteOffset,
-          packBuffer.byteOffset + packBuffer.byteLength,
-        ),
-      );
-
-      statusPack.setUint32(0, 1437227610);
-      // 16 bit slot
-      statusPack.setUint16(6, this.block);
-      statusPack.setUint16(8, frame);
-      statusPack.setUint16(10, 255);
-      statusPack.setUint16(24, 0);
-      statusPack.setUint16(26, 0);
-
-      // 32 bit slot
-      statusPack.setUint32(12, buff.byteLength);
-      statusPack.setUint32(16, 0);
-      // statusPack.setUint32(20, 0);
-      statusPack.setUint32(24, 0);
-      statusPack.setUint32(28, 0);
-      statusPack.setUint32(32, 0);
-
-      if (this.channel && this.channel.isOpen()) {
-        this.channel.sendMessageBinary(Buffer.from(statusPack.buffer));
+  pushMetaDataToSteam(stream: StreamMetaType): Promise<StreamPushResponse> {
+    return new Promise((resolve, reject) => {
+      try {
+        const metaData = stream.metaData;
+        const frame = stream.frame;
+        const metaDataBin = metaData.replace(/\s/g, '');
+        const buff = Buffer.from(metaDataBin, 'utf-8');
+
+        // const block = 36;
+        const blockBuff = Buffer.alloc(this.block);
+        const packBuffer = Buffer.concat([blockBuff, buff]);
+
+        const statusPack = new DataView(
+          packBuffer.buffer.slice(
+            packBuffer.byteOffset,
+            packBuffer.byteOffset + packBuffer.byteLength,
+          ),
+        );
+
+        statusPack.setUint32(0, 1437227610);
+        // 16 bit slot
+        statusPack.setUint16(6, this.block);
+        statusPack.setUint16(8, frame);
+        statusPack.setUint16(10, 255);
+        statusPack.setUint16(24, 0);
+        statusPack.setUint16(26, 0);
+
+        // 32 bit slot
+        statusPack.setUint32(12, buff.byteLength);
+        statusPack.setUint32(16, 0);
+        // statusPack.setUint32(20, 0);
+        statusPack.setUint32(24, 0);
+        statusPack.setUint32(28, 0);
+        statusPack.setUint32(32, 0);
+
+        if (this.channel && this.channel.isOpen()) {
+          const done = this.channel.sendMessageBinary(
+            Buffer.from(statusPack.buffer),
+          );
+          return resolve({ frame: stream.frame, done: done });
+        } else {
+          return resolve({ frame: stream.frame, done: false });
+        }
+      } catch (error) {
+        this.logger.error(error);
+        return reject({ frame: stream.frame, done: false });
       }
-    } catch (error) {
-      this.logger.error(error);
-    }
+    });
   }
 
   /**