github.com/amitbet/vnc2video@v0.0.0-20190616012314-9d50b9dab1d9/example/client/main.go (about)

     1  package main
     2  
     3  import (
     4  	"context"
     5  	"log"
     6  	"net"
     7  	"os"
     8  	"os/signal"
     9  	"runtime"
    10  	"runtime/pprof"
    11  	"syscall"
    12  	"time"
    13  	vnc "github.com/amitbet/vnc2video"
    14  	"github.com/amitbet/vnc2video/encoders"
    15  	"github.com/amitbet/vnc2video/logger"
    16  )
    17  
    18  func main() {
    19  	runtime.GOMAXPROCS(4)
    20  	framerate := 12
    21  	runWithProfiler := false
    22  
    23  	// Establish TCP connection to VNC server.
    24  	nc, err := net.DialTimeout("tcp", os.Args[1], 5*time.Second)
    25  	if err != nil {
    26  		logger.Fatalf("Error connecting to VNC host. %v", err)
    27  	}
    28  
    29  	logger.Tracef("starting up the client, connecting to: %s", os.Args[1])
    30  	// Negotiate connection with the server.
    31  	cchServer := make(chan vnc.ServerMessage)
    32  	cchClient := make(chan vnc.ClientMessage)
    33  	errorCh := make(chan error)
    34  
    35  	ccfg := &vnc.ClientConfig{
    36  		SecurityHandlers: []vnc.SecurityHandler{
    37  			//&vnc.ClientAuthATEN{Username: []byte(os.Args[2]), Password: []byte(os.Args[3])}
    38  			&vnc.ClientAuthVNC{Password: []byte("12345")},
    39  			&vnc.ClientAuthNone{},
    40  		},
    41  		DrawCursor:      true,
    42  		PixelFormat:     vnc.PixelFormat32bit,
    43  		ClientMessageCh: cchClient,
    44  		ServerMessageCh: cchServer,
    45  		Messages:        vnc.DefaultServerMessages,
    46  		Encodings: []vnc.Encoding{
    47  			&vnc.RawEncoding{},
    48  			&vnc.TightEncoding{},
    49  			&vnc.HextileEncoding{},
    50  			&vnc.ZRLEEncoding{},
    51  			&vnc.CopyRectEncoding{},
    52  			&vnc.CursorPseudoEncoding{},
    53  			&vnc.CursorPosPseudoEncoding{},
    54  			&vnc.ZLibEncoding{},
    55  			&vnc.RREEncoding{},
    56  		},
    57  		ErrorCh: errorCh,
    58  	}
    59  
    60  	cc, err := vnc.Connect(context.Background(), nc, ccfg)
    61  	screenImage := cc.Canvas
    62  	if err != nil {
    63  		logger.Fatalf("Error negotiating connection to VNC host. %v", err)
    64  	}
    65  	// out, err := os.Create("./output" + strconv.Itoa(counter) + ".jpg")
    66  	// if err != nil {
    67  	// 	fmt.Println(err)p
    68  	// 	os.Exit(1)
    69  	// }
    70  	//vcodec := &encoders.MJPegImageEncoder{Quality: 60 , Framerate: framerate}
    71  	//vcodec := &encoders.X264ImageEncoder{FFMpegBinPath: "./ffmpeg", Framerate: framerate}
    72  	//vcodec := &encoders.HuffYuvImageEncoder{FFMpegBinPath: "./ffmpeg", Framerate: framerate}
    73  	vcodec := &encoders.QTRLEImageEncoder{FFMpegBinPath: "./ffmpeg", Framerate: framerate}
    74  	//vcodec := &encoders.VP8ImageEncoder{FFMpegBinPath:"./ffmpeg", Framerate: framerate}
    75  	//vcodec := &encoders.DV9ImageEncoder{FFMpegBinPath:"./ffmpeg", Framerate: framerate}
    76  
    77  	//counter := 0
    78  	//vcodec.Init("./output" + strconv.Itoa(counter))
    79  
    80  	go vcodec.Run("./output.mp4")
    81  	//windows
    82  	///go vcodec.Run("/Users/amitbet/Dropbox/go/src/vnc2webm/example/file-reader/ffmpeg", "./output.mp4")
    83  
    84  	//go vcodec.Run("C:\\Users\\betzalel\\Dropbox\\go\\src\\vnc2video\\example\\client\\ffmpeg.exe", "output.mp4")
    85  	//vcodec.Run("./output")
    86  
    87  	//screenImage := vnc.NewVncCanvas(int(cc.Width()), int(cc.Height()))
    88  
    89  	for _, enc := range ccfg.Encodings {
    90  		myRenderer, ok := enc.(vnc.Renderer)
    91  
    92  		if ok {
    93  			myRenderer.SetTargetImage(screenImage)
    94  		}
    95  	}
    96  	// var out *os.File
    97  
    98  	logger.Tracef("connected to: %s", os.Args[1])
    99  	defer cc.Close()
   100  
   101  	cc.SetEncodings([]vnc.EncodingType{
   102  		vnc.EncCursorPseudo,
   103  		vnc.EncPointerPosPseudo,
   104  		vnc.EncCopyRect,
   105  		vnc.EncTight,
   106  		vnc.EncZRLE,
   107  		//vnc.EncHextile,
   108  		//vnc.EncZlib,
   109  		//vnc.EncRRE,
   110  	})
   111  	//rect := image.Rect(0, 0, int(cc.Width()), int(cc.Height()))
   112  	//screenImage := image.NewRGBA64(rect)
   113  	// Process messages coming in on the ServerMessage channel.
   114  
   115  	go func() {
   116  		for {
   117  			timeStart := time.Now()
   118  
   119  			vcodec.Encode(screenImage.Image)
   120  
   121  			timeTarget := timeStart.Add((1000 / time.Duration(framerate)) * time.Millisecond)
   122  			timeLeft := timeTarget.Sub(time.Now())
   123  			if timeLeft > 0 {
   124  				time.Sleep(timeLeft)
   125  			}
   126  		}
   127  	}()
   128  
   129  	sigc := make(chan os.Signal, 1)
   130  	signal.Notify(sigc,
   131  		syscall.SIGHUP,
   132  		syscall.SIGINT,
   133  		syscall.SIGTERM,
   134  		syscall.SIGQUIT)
   135  	frameBufferReq := 0
   136  	timeStart := time.Now()
   137  
   138  	if runWithProfiler {
   139  		profFile := "prof.file"
   140  		f, err := os.Create(profFile)
   141  		if err != nil {
   142  			log.Fatal(err)
   143  		}
   144  		pprof.StartCPUProfile(f)
   145  		defer pprof.StopCPUProfile()
   146  	}
   147  
   148  	for {
   149  		select {
   150  		case err := <-errorCh:
   151  			panic(err)
   152  		case msg := <-cchClient:
   153  			logger.Tracef("Received client message type:%v msg:%v\n", msg.Type(), msg)
   154  		case msg := <-cchServer:
   155  			//logger.Tracef("Received server message type:%v msg:%v\n", msg.Type(), msg)
   156  
   157  			// out, err := os.Create("./output" + strconv.Itoa(counter) + ".jpg")
   158  			// if err != nil {
   159  			// 	fmt.Println(err)
   160  			// 	os.Exit(1)
   161  			// }
   162  
   163  			if msg.Type() == vnc.FramebufferUpdateMsgType {
   164  				secsPassed := time.Now().Sub(timeStart).Seconds()
   165  				frameBufferReq++
   166  				reqPerSec := float64(frameBufferReq) / secsPassed
   167  				//counter++
   168  				//jpeg.Encode(out, screenImage, nil)
   169  				///vcodec.Encode(screenImage)
   170  				logger.Infof("reqs=%d, seconds=%f, Req Per second= %f", frameBufferReq, secsPassed, reqPerSec)
   171  
   172  				reqMsg := vnc.FramebufferUpdateRequest{Inc: 1, X: 0, Y: 0, Width: cc.Width(), Height: cc.Height()}
   173  				//cc.ResetAllEncodings()
   174  				reqMsg.Write(cc)
   175  			}
   176  		case signal := <-sigc:
   177  			if signal != nil {
   178  				vcodec.Close()
   179  				pprof.StopCPUProfile()
   180  				time.Sleep(2 * time.Second)
   181  				os.Exit(1)
   182  			}
   183  		}
   184  	}
   185  	//cc.Wait()
   186  }