main.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. package main
  2. import (
  3. "embed"
  4. "flag"
  5. "io/fs"
  6. "log"
  7. "net/http"
  8. "os"
  9. "os/signal"
  10. "syscall"
  11. "time"
  12. "imuslab.com/remdeskvm/remdeskd/mod/remdeshid"
  13. "imuslab.com/remdeskvm/remdeskd/mod/usbcapture"
  14. )
  15. const defaultDevMode = true
  16. var (
  17. developent = flag.Bool("dev", defaultDevMode, "Enable development mode with local static files")
  18. mode = flag.String("mode", "usbkvm", "Mode of operation: kvm or capture")
  19. usbKVMDeviceName = flag.String("usbkvm", "/dev/ttyUSB0", "USB KVM device file path")
  20. usbKVMBaudRate = flag.Int("baudrate", 115200, "USB KVM baud rate")
  21. captureDeviceName = flag.String("capture", "/dev/video0", "Video capture device file path")
  22. usbKVM *remdeshid.Controller
  23. videoCapture *usbcapture.Instance
  24. )
  25. /* Web Server Static Files */
  26. //go:embed www
  27. var embeddedFiles embed.FS
  28. var webfs http.FileSystem
  29. func init() {
  30. // Initiate the web server static files
  31. if *developent {
  32. webfs = http.Dir("./www")
  33. } else {
  34. // Embed the ./www folder and trim the prefix
  35. subFS, err := fs.Sub(embeddedFiles, "www")
  36. if err != nil {
  37. log.Fatal(err)
  38. }
  39. webfs = http.FS(subFS)
  40. }
  41. }
  42. func main() {
  43. flag.Parse()
  44. // Initiate the HID controller
  45. usbKVM = remdeshid.NewHIDController(&remdeshid.Config{
  46. PortName: *usbKVMDeviceName,
  47. BaudRate: *usbKVMBaudRate,
  48. ScrollSensitivity: 0x01, // Set mouse scroll sensitivity
  49. })
  50. switch *mode {
  51. case "cfgchip":
  52. //Start the HID controller
  53. err := usbKVM.Connect()
  54. if err != nil {
  55. log.Fatal(err)
  56. }
  57. time.Sleep(1 * time.Second) // Wait for the controller to initialize
  58. log.Println("Updating chip baudrate to 115200...")
  59. //Configure the HID controller
  60. err = usbKVM.ConfigureChipTo115200()
  61. if err != nil {
  62. log.Fatalf("Failed to configure chip baudrate: %v", err)
  63. return
  64. }
  65. time.Sleep(1 * time.Second)
  66. log.Println("Setting chip USB device properties...")
  67. time.Sleep(2 * time.Second) // Wait for the controller to initialize
  68. _, err = usbKVM.WriteChipProperties()
  69. if err != nil {
  70. log.Fatalf("Failed to write chip properties: %v", err)
  71. return
  72. }
  73. log.Println("Configuration command sent. Unplug the device and plug it back in to apply the changes.")
  74. case "usbkvm":
  75. log.Println("Starting in USB KVM mode...")
  76. //Start the HID controller
  77. err := usbKVM.Connect()
  78. if err != nil {
  79. log.Fatal(err)
  80. }
  81. // Initiate the video capture device
  82. videoCapture, err = usbcapture.NewInstance(&usbcapture.Config{
  83. DeviceName: *captureDeviceName,
  84. AudioConfig: usbcapture.GetDefaultAudioConfig(),
  85. })
  86. if err != nil {
  87. log.Fatalf("Failed to create video capture instance: %v", err)
  88. }
  89. //Get device information for debug
  90. usbcapture.PrintV4L2FormatInfo(*captureDeviceName)
  91. //Start the video capture device
  92. err = videoCapture.StartVideoCapture(&usbcapture.CaptureResolution{
  93. Width: 1920,
  94. Height: 1080,
  95. FPS: 10,
  96. })
  97. if err != nil {
  98. log.Fatal(err)
  99. }
  100. // Handle program exit to close the HID controller
  101. c := make(chan os.Signal, 1)
  102. signal.Notify(c, os.Interrupt, syscall.SIGTERM)
  103. go func() {
  104. <-c
  105. log.Println("Shutting down usbKVM...")
  106. //usbKVM.Close() //To fix close stuck layer
  107. log.Println("Shutting down capture device...")
  108. videoCapture.Close()
  109. os.Exit(0)
  110. }()
  111. // Start the web server
  112. http.Handle("/", http.FileServer(webfs))
  113. http.HandleFunc("/hid", usbKVM.HIDWebSocketHandler)
  114. http.HandleFunc("/audio", videoCapture.AudioStreamingHandler)
  115. http.HandleFunc("/stream", videoCapture.ServeVideoStream)
  116. addr := ":9000"
  117. log.Printf("Serving on http://localhost%s\n", addr)
  118. log.Fatal(http.ListenAndServe(addr, nil))
  119. case "list-audio-devices":
  120. log.Println("Starting in List Audio Devices mode...")
  121. //Get the audio devices
  122. path, err := usbcapture.FindHDMICapturePCMPath()
  123. if err != nil {
  124. log.Fatalf("Failed to find HDMI capture PCM path: %v", err)
  125. }
  126. log.Printf("Found HDMI capture PCM path: %s\n", path)
  127. //List all audio capture devices
  128. captureDevs, err := usbcapture.ListCaptureDevices()
  129. if err != nil {
  130. log.Fatalf("Failed to list capture devices: %v", err)
  131. }
  132. log.Println("Available audio capture devices:")
  133. for _, dev := range captureDevs {
  134. log.Printf(" - %s\n", dev)
  135. }
  136. default:
  137. log.Fatalf("Unknown mode: %s. Supported modes are: usbkvm, capture", *mode)
  138. }
  139. }