You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

screencap.go 1.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. package screencap
  2. import "github.com/kbinani/screenshot"
  3. import "image/jpeg"
  4. import "sync"
  5. import "time"
  6. import "log"
  7. type Buffer struct {
  8. Data []byte
  9. Length int
  10. }
  11. func (buf *Buffer) Write(data []byte) (int, error) {
  12. if len(buf.Data) == 0 {
  13. l := len(data)
  14. if l < 1024 {
  15. l = 2024
  16. }
  17. buf.Data = make([]byte, l)
  18. } else if buf.Length + len(data) > len(buf.Data) {
  19. newSize := len(buf.Data) * 2
  20. for buf.Length + len(data) > newSize {
  21. newSize *= 2
  22. }
  23. newBuf := make([]byte, newSize)
  24. copy(newBuf, buf.Data[0:buf.Length])
  25. buf.Data = newBuf
  26. }
  27. copy(buf.Data[buf.Length:], data)
  28. buf.Length += len(data)
  29. return len(data), nil
  30. }
  31. var (
  32. mut = sync.Mutex{}
  33. chans = make([]chan *Buffer, 0)
  34. startChan = make(chan struct{}, 1)
  35. buffers = make([]Buffer, 4)
  36. currentBuffer = 0
  37. )
  38. func Capture() chan *Buffer {
  39. ch := make(chan *Buffer)
  40. mut.Lock()
  41. chans = append(chans, ch)
  42. mut.Unlock()
  43. select {
  44. case startChan <- struct{}{}:
  45. default:
  46. }
  47. return ch
  48. }
  49. func Run() {
  50. targetDelta := 200 * time.Millisecond
  51. for {
  52. <-startChan
  53. startTime := time.Now()
  54. img, err := screenshot.CaptureDisplay(0)
  55. if err != nil {
  56. log.Printf("Failed to capture screenshot: %v", err)
  57. time.Sleep(2 * time.Second)
  58. continue
  59. }
  60. buf := &buffers[currentBuffer]
  61. currentBuffer = (currentBuffer + 1) % len(buffers)
  62. buf.Length = 0
  63. err = jpeg.Encode(buf, img, &jpeg.Options{Quality: 40})
  64. if err != nil {
  65. log.Printf("Failed to encode jpeg: %v", err)
  66. time.Sleep(2 * time.Second)
  67. continue
  68. }
  69. mut.Lock()
  70. for _, ch := range chans {
  71. ch <- buf
  72. }
  73. chans = make([]chan *Buffer, 0)
  74. mut.Unlock()
  75. delta := time.Now().Sub(startTime)
  76. if delta < targetDelta {
  77. time.Sleep(targetDelta - delta)
  78. }
  79. }
  80. }