Minicap数据解析(PHP-MiniStream)

2017-01-18  本文已影响0人  PreFU

<?php

namespace console\controllers;


/**
 * PostController implements the CRUD actions for Post model.
 */


class MiniStream{    

    private $readBannerBytes = 0;
    private $bannerLength = 2;
    private $readFrameBytes = 0;
    private $frameBodyLength = 0;
    private $frameBody = array();
    private $banner;
    private $js_client;

    const BINARY_TYPE_BLOB = "\x81";


    function __construct($client) {
        $this->js_client=$client;
    }




    public function socket(){
        set_time_limit(0); 
        $host = "127.0.0.1";
        $port = 1313;  
        $this->banner = new Banner();
        $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
        socket_connect($socket,$host,$port);    //  连接  


        while ($len=socket_recv($socket,$buff,4096,0)) {  
            for ($index = 0; $index < $len;) {
                $byte10 = ord($buff[$index]);    


                if ($this->readBannerBytes < $this->bannerLength) {                    
                        $index = $this->parserBanner($index, $byte10);        
                }else if ($this->readFrameBytes < 4) {
                        $this->frameBodyLength += ($byte10<< ($this->readFrameBytes * 8)) >> 0;
                        $index+= 1;
                        $this->readFrameBytes += 1;
//                        echo '<br />'. $this->readFrameBytes.'(val='. $this->frameBodyLength.')';    
                        $picLength = $this->frameBodyLength;
                }else{                                                            
                    if ($len - $index >= $this->frameBodyLength) {
//                            echo "<br />frameBodyLength = ".$this->frameBodyLength.'<br />';
                            $bytes = substr($buff, $index, $index+$this->frameBodyLength);
                            array_push($this->frameBody, $bytes);
                            if(bin2hex($this->frameBody[0][0]) !=='ff' || bin2hex($this->frameBody[0][1]) !=='d8'){
                                echo 'JPG header Error';
                                return;
                            }
//                                header("Content-type: image/JPEG",true);
                                $final_data = null;
                                foreach ($this->frameBody as $value) {
                                     $final_data .= $value;
                                }
                                $bas = base64_encode($final_data);

                                $this->send($this->js_client,$bas);
//                                $this->send($this->js_client,'end');
//                                return;


                            $index += $this->frameBodyLength;
                            $this->frameBodyLength = $this->readFrameBytes = 0;
                            $this->frameBody = array();

                    } else {
                            $bytes = substr($buff, $index, $len);
                            array_push($this->frameBody, $bytes);
                            $this->frameBodyLength -= ($len - $index);
                            $this->readFrameBytes += ($len - $index);
                            $index = $len;
                    }
                }
            }

        }  
        socket_close($socket);  
    }

    public function parserBanner($cursor,$byte10){
        $banner = $this->banner;
        switch ($this->readBannerBytes){
            case 0:
                $banner->setVersion($byte10);
                break;
            case 1:
                // length                
                $this->bannerLength = $byte10;
                $banner->setLength($byte10);
                break;
            case 2:
            case 3:
            case 4:
            case 5:
                // pid
                $pid = $banner->getPid();
                $pid += ($byte10 << (($this->readBannerBytes - 2) * 8)) >> 0;
                $banner->setPid($pid);
                break;
            case 6:
            case 7:
            case 8:
            case 9:
                // real width
                $realWidth = $banner->getReadWidth();
                $realWidth += ($byte10 << (($this->readBannerBytes - 6) * 8)) >> 0;
                $banner->setReadWidth($realWidth);
                break;
            case 10:
            case 11:
            case 12:
            case 13:
                // real height
                $realHeight = $banner->getReadHeight();
                $realHeight += ($byte10 << (($this->readBannerBytes - 10) * 8)) >> 0;
                $banner->setReadHeight($realHeight);
                break;
            case 14:
            case 15:
            case 16:
            case 17:
                // virtual width
                $virtualWidth = $banner->getVirtualWidth();
                $virtualWidth += ($byte10 << (($this->readBannerBytes - 14) * 8)) >> 0;
                $banner->setVirtualWidth($virtualWidth);

                break;
            case 18:
            case 19:
            case 20:
            case 21:
                // virtual height
                $virtualHeight = $banner->getVirtualHeight();
                $virtualHeight += ($byte10 << (($this->readBannerBytes - 18) * 8)) >> 0;
                $banner->setVirtualHeight($virtualHeight);
                break;
            case 22:
                // orientation
                $banner->setOrientation($byte10 * 90);
                break;
            case 23:
                // quirks
                $banner->setQuirks($byte10);
                break;
            }

        $cursor += 1;
        $this->readBannerBytes += 1;
        if ($this->readBannerBytes == $this->bannerLength) {
//            echo $banner->toString();
            null;
        }
        return $cursor;
    }

    public function frame($buffer)
      {
        $len = strlen($buffer);

          $first_byte = self::BINARY_TYPE_BLOB;

           if ($len <= 125) {
               $encode_buffer = $first_byte . chr($len) . $buffer;
           } else {
             if ($len <= 65535) {
                   $encode_buffer = $first_byte . chr(126) . pack("n", $len) . $buffer;
               } else {
                 //pack("xxxN", $len)pack函数只处理2的32次方大小的文件,实际上2的32次方已经4G了。 
                  $encode_buffer = $first_byte . chr(127) . pack("xxxxN", $len) . $buffer;
              }
           }

          return $encode_buffer;
       }

    // 返回数据
    function send($client, $msg)
    {
        $msg = $this->frame($msg);
        socket_write($client, $msg, strlen($msg));     
    }

}

class Banner{
    private $version;
    private $length;
    private $pid;
    private $readWidth;
    private $readHeight;
    private $virtualWidth;
    private $virtualHeight;
    private $orientation;
    private $quirks;

    public function toString() {
//            echo $this->getLength();
            return "Banner [version=".$this->version.", length=".$this->length.", pid="
                           .$this->pid.", readWidth=".$this->readWidth.", readHeight="
                           .$this->readHeight.", virtualWidth=".$this->virtualWidth
                           .", virtualHeight=".$this->virtualHeight.", orientation="
                           .$this->orientation.", quirks=".$this->quirks."]";
    }
    public function getVersion() {
            return $this->version;
    }
    public function setVersion($version) {
            $this->version = $version;            
    }
    public function getLength() {
            return $this->length;
    }
    public function setLength($length) {
            $this->length = $length;
    }
    public function getPid() {
            return $this->pid;
    }
    public function setPid($pid) {
            $this->pid = $pid;
    }
    public function getReadWidth() {
            return $this->readWidth;
    }
    public function setReadWidth($readWidth) {
            $this->readWidth = $readWidth;
    }
    public function getReadHeight() {
            return $this->readHeight;
    }
    public function setReadHeight($readHeight) {
            $this->readHeight = $readHeight;
    }
    public function getVirtualWidth() {
            return $this->virtualWidth;
    }
    public function setVirtualWidth($virtualWidth) {
            $this->virtualWidth = $virtualWidth;
    }
    public function getVirtualHeight() {
            return $this->virtualHeight;
    }
    public function setVirtualHeight($virtualHeight) {
            $this->virtualHeight = $virtualHeight;
    }
    public function getOrientation() {
            return $this->orientation;
    }
    public function setOrientation($orientation) {
            $this->orientation = $orientation;
    }
    public function getQuirks() {
            return $this->quirks;
    }
    public function setQuirks($quirks) {
            $this->quirks = $quirks;
    }

    }
上一篇下一篇

猜你喜欢

热点阅读