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 }