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. /*
  58. log.Println("Starting in Configure Chip mode...")
  59. time.Sleep(2 * time.Second) // Wait for the controller to initialize
  60. _, err = usbKVM.WriteChipProperties()
  61. if err != nil {
  62. log.Fatalf("Failed to write chip properties: %v", err)
  63. return
  64. }
  65. */
  66. time.Sleep(1 * time.Second) // Wait for the controller to initialize
  67. log.Println("Updating chip baudrate to 115200...")
  68. //Configure the HID controller
  69. err = usbKVM.ConfigureChipTo115200()
  70. if err != nil {
  71. log.Fatalf("Failed to configure chip baudrate: %v", err)
  72. return
  73. }
  74. time.Sleep(1 * time.Second)
  75. log.Println("Configuration command sent. Unplug the device and plug it back in to apply the changes.")
  76. case "usbkvm":
  77. log.Println("Starting in USB KVM mode...")
  78. //Start the HID controller
  79. err := usbKVM.Connect()
  80. if err != nil {
  81. log.Fatal(err)
  82. }
  83. // Initiate the video capture device
  84. videoCapture, err = usbcapture.NewInstance(&usbcapture.Config{
  85. DeviceName: *captureDeviceName,
  86. AudioConfig: usbcapture.GetDefaultAudioConfig(),
  87. })
  88. if err != nil {
  89. log.Fatalf("Failed to create video capture instance: %v", err)
  90. }
  91. //Get device information for debug
  92. usbcapture.PrintV4L2FormatInfo(*captureDeviceName)
  93. //Start the video capture device
  94. err = videoCapture.StartVideoCapture(&usbcapture.CaptureResolution{
  95. Width: 1920,
  96. Height: 1080,
  97. FPS: 10,
  98. })
  99. if err != nil {
  100. log.Fatal(err)
  101. }
  102. // Handle program exit to close the HID controller
  103. c := make(chan os.Signal, 1)
  104. signal.Notify(c, os.Interrupt, syscall.SIGTERM)
  105. go func() {
  106. <-c
  107. log.Println("Shutting down usbKVM...")
  108. //usbKVM.Close() //To fix close stuck layer
  109. log.Println("Shutting down capture device...")
  110. videoCapture.Close()
  111. os.Exit(0)
  112. }()
  113. // Start the web server
  114. http.Handle("/", http.FileServer(webfs))
  115. http.HandleFunc("/hid", usbKVM.HIDWebSocketHandler)
  116. http.HandleFunc("/audio", videoCapture.AudioStreamingHandler)
  117. http.HandleFunc("/stream", videoCapture.ServeVideoStream)
  118. addr := ":9000"
  119. log.Printf("Serving on http://localhost%s\n", addr)
  120. log.Fatal(http.ListenAndServe(addr, nil))
  121. case "list-audio-devices":
  122. log.Println("Starting in List Audio Devices mode...")
  123. //Get the audio devices
  124. path, err := usbcapture.FindHDMICapturePCMPath()
  125. if err != nil {
  126. log.Fatalf("Failed to find HDMI capture PCM path: %v", err)
  127. }
  128. log.Printf("Found HDMI capture PCM path: %s\n", path)
  129. //List all audio capture devices
  130. captureDevs, err := usbcapture.ListCaptureDevices()
  131. if err != nil {
  132. log.Fatalf("Failed to list capture devices: %v", err)
  133. }
  134. log.Println("Available audio capture devices:")
  135. for _, dev := range captureDevs {
  136. log.Printf(" - %s\n", dev)
  137. }
  138. default:
  139. log.Fatalf("Unknown mode: %s. Supported modes are: usbkvm, capture", *mode)
  140. }
  141. }