github.com/amitbet/vnc2video@v0.0.0-20190616012314-9d50b9dab1d9/fbs-connection.go (about)

     1  package vnc2video
     2  
     3  import (
     4  	"encoding/binary"
     5  	"net"
     6  	"github.com/amitbet/vnc2video/logger"
     7  
     8  	"io"
     9  	"time"
    10  )
    11  
    12  // Conn represents vnc conection
    13  type FbsConn struct {
    14  	FbsReader
    15  
    16  	protocol string
    17  	//c      net.IServerConn
    18  	//config *ClientConfig
    19  	colorMap ColorMap
    20  
    21  	// Encodings supported by the client. This should not be modified
    22  	// directly. Instead, SetEncodings should be used.
    23  	encodings []Encoding
    24  
    25  	// Height of the frame buffer in pixels, sent from the server.
    26  	fbHeight uint16
    27  
    28  	// Width of the frame buffer in pixels, sent from the server.
    29  	fbWidth     uint16
    30  	desktopName string
    31  	// The pixel format associated with the connection. This shouldn't
    32  	// be modified. If you wish to set a new pixel format, use the
    33  	// SetPixelFormat method.
    34  	pixelFormat PixelFormat
    35  }
    36  
    37  // func (c *FbsConn) Close() error {
    38  // 	return c.fbs.Close()
    39  // }
    40  
    41  // // Read reads data from conn
    42  // func (c *FbsConn) Read(buf []byte) (int, error) {
    43  // 	return c.fbs.Read(buf)
    44  // }
    45  
    46  //dummy, no writing to this conn...
    47  func (c *FbsConn) Write(buf []byte) (int, error) {
    48  	return len(buf), nil
    49  }
    50  
    51  func (c *FbsConn) Conn() net.Conn {
    52  	return nil
    53  }
    54  
    55  func (c *FbsConn) Config() interface{} {
    56  	return nil
    57  }
    58  
    59  func (c *FbsConn) Protocol() string {
    60  	return "RFB 003.008"
    61  }
    62  func (c *FbsConn) PixelFormat() PixelFormat {
    63  	return c.pixelFormat
    64  }
    65  
    66  func (c *FbsConn) SetPixelFormat(pf PixelFormat) error {
    67  	c.pixelFormat = pf
    68  	return nil
    69  }
    70  
    71  func (c *FbsConn) ColorMap() ColorMap                       { return c.colorMap }
    72  func (c *FbsConn) SetColorMap(cm ColorMap)                  { c.colorMap = cm }
    73  func (c *FbsConn) Encodings() []Encoding                    { return c.encodings }
    74  func (c *FbsConn) SetEncodings([]EncodingType) error        { return nil }
    75  func (c *FbsConn) Width() uint16                            { return c.fbWidth }
    76  func (c *FbsConn) Height() uint16                           { return c.fbHeight }
    77  func (c *FbsConn) SetWidth(w uint16)                        { c.fbWidth = w }
    78  func (c *FbsConn) SetHeight(h uint16)                       { c.fbHeight = h }
    79  func (c *FbsConn) DesktopName() []byte                      { return []byte(c.desktopName) }
    80  func (c *FbsConn) SetDesktopName(d []byte)                  { c.desktopName = string(d) }
    81  func (c *FbsConn) Flush() error                             { return nil }
    82  func (c *FbsConn) Wait()                                    {}
    83  func (c *FbsConn) SetProtoVersion(string)                   {}
    84  func (c *FbsConn) SetSecurityHandler(SecurityHandler) error { return nil }
    85  func (c *FbsConn) SecurityHandler() SecurityHandler         { return nil }
    86  func (c *FbsConn) GetEncInstance(typ EncodingType) Encoding {
    87  	for _, enc := range c.encodings {
    88  		if enc.Type() == typ {
    89  			return enc
    90  		}
    91  	}
    92  	return nil
    93  }
    94  
    95  type VncStreamFileReader interface {
    96  	io.Reader
    97  	CurrentTimestamp() int
    98  	ReadStartSession() (*ServerInit, error)
    99  	CurrentPixelFormat() *PixelFormat
   100  	Encodings() []Encoding
   101  }
   102  
   103  type FBSPlayHelper struct {
   104  	Conn *FbsConn
   105  	//Fbs              VncStreamFileReader
   106  	serverMessageMap map[uint8]ServerMessage
   107  	firstSegDone     bool
   108  	startTime        int
   109  }
   110  
   111  func NewFbsConn(filename string, encs []Encoding) (*FbsConn, error) {
   112  
   113  	fbs, err := NewFbsReader(filename)
   114  	if err != nil {
   115  		logger.Error("failed to open fbs reader:", err)
   116  		return nil, err
   117  	}
   118  
   119  	//NewFbsReader("/Users/amitbet/vncRec/recording.rbs")
   120  	initMsg, err := fbs.ReadStartSession()
   121  	if err != nil {
   122  		logger.Error("failed to open read fbs start session:", err)
   123  		return nil, err
   124  	}
   125  	fbsConn := &FbsConn{FbsReader: *fbs}
   126  	fbsConn.encodings = encs
   127  	fbsConn.SetPixelFormat(initMsg.PixelFormat)
   128  	fbsConn.SetHeight(initMsg.FBHeight)
   129  	fbsConn.SetWidth(initMsg.FBWidth)
   130  	fbsConn.SetDesktopName([]byte(initMsg.NameText))
   131  
   132  	return fbsConn, nil
   133  }
   134  
   135  func NewFBSPlayHelper(r *FbsConn) *FBSPlayHelper {
   136  	h := &FBSPlayHelper{Conn: r}
   137  	h.startTime = int(time.Now().UnixNano() / int64(time.Millisecond))
   138  
   139  	h.serverMessageMap = make(map[uint8]ServerMessage)
   140  	h.serverMessageMap[0] = &FramebufferUpdate{}
   141  	h.serverMessageMap[1] = &SetColorMapEntries{}
   142  	h.serverMessageMap[2] = &Bell{}
   143  	h.serverMessageMap[3] = &ServerCutText{}
   144  
   145  	return h
   146  }
   147  
   148  // func (handler *FBSPlayHelper) Consume(seg *RfbSegment) error {
   149  
   150  // 	switch seg.SegmentType {
   151  // 	case SegmentFullyParsedClientMessage:
   152  // 		clientMsg := seg.Message.(ClientMessage)
   153  // 		logger.Tracef("ClientUpdater.Consume:(vnc-server-bound) got ClientMessage type=%s", clientMsg.Type())
   154  // 		switch clientMsg.Type() {
   155  
   156  // 		case FramebufferUpdateRequestMsgType:
   157  // 			if !handler.firstSegDone {
   158  // 				handler.firstSegDone = true
   159  // 				handler.startTime = int(time.Now().UnixNano() / int64(time.Millisecond))
   160  // 			}
   161  // 			handler.sendFbsMessage()
   162  // 		}
   163  // 		// server.MsgFramebufferUpdateRequest:
   164  // 	}
   165  // 	return nil
   166  // }
   167  
   168  func (h *FBSPlayHelper) ReadFbsMessage(SyncWithTimestamps bool, SpeedFactor float64) (ServerMessage, error) {
   169  	var messageType uint8
   170  	//messages := make(map[uint8]ServerMessage)
   171  	fbs := h.Conn
   172  	//conn := h.Conn
   173  	err := binary.Read(fbs, binary.BigEndian, &messageType)
   174  	if err != nil {
   175  		logger.Error("FBSConn.NewConnHandler: Error in reading FBS: ", err)
   176  		return nil, err
   177  	}
   178  	startTimeMsgHandling := time.Now()
   179  	//IClientConn{}
   180  	//binary.Write(h.Conn, binary.BigEndian, messageType)
   181  	msg := h.serverMessageMap[messageType]
   182  	if msg == nil {
   183  		logger.Error("FBSConn.NewConnHandler: Error unknown message type: ", messageType)
   184  		return nil, err
   185  	}
   186  	//read the actual message data
   187  	//err = binary.Read(fbs, binary.BigEndian, &msg)
   188  	parsedMsg, err := msg.Read(fbs)
   189  	if err != nil {
   190  		logger.Error("FBSConn.NewConnHandler: Error in reading FBS message: ", err)
   191  		return nil, err
   192  	}
   193  
   194  	millisSinceStart := int(startTimeMsgHandling.UnixNano()/int64(time.Millisecond)) - h.startTime
   195  	adjestedTimeStamp := float64(fbs.CurrentTimestamp()) / SpeedFactor
   196  	millisToSleep := adjestedTimeStamp - float64(millisSinceStart)
   197  
   198  	if millisToSleep > 0 && SyncWithTimestamps {
   199  
   200  		time.Sleep(time.Duration(millisToSleep) * time.Millisecond)
   201  	} else if millisToSleep < -400 {
   202  		logger.Errorf("rendering time is noticeably off, change speedup factor: videoTimeLine: %f, currentTime:%d, offset: %f", adjestedTimeStamp, millisSinceStart, millisToSleep)
   203  	}
   204  
   205  	return parsedMsg, nil
   206  }