cam.py 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. #!/usr/bin/python3
  2. import sys
  3. import gi
  4. gi.require_version('Gst', '1.0')
  5. from gi.repository import Gst
  6. import time
  7. import threading
  8. import os
  9. import stat
  10. WIDTH = 1280
  11. HEIGHT = 720
  12. SCREEN_WIDTH = 800
  13. SCREEN_HEIGHT = 600
  14. def bus_call(bus, msg, *args):
  15. if msg.type == Gst.MessageType.EOS:
  16. print("End-of-stream")
  17. loop.quit()
  18. return
  19. elif msg.type == Gst.MessageType.ERROR:
  20. print("GST ERROR", msg.parse_error())
  21. loop.quit()
  22. return
  23. return True
  24. zoom = 1
  25. def quit():
  26. pipeline.send_event(Gst.Event.new_eos())
  27. def set_preview(val):
  28. if val == 0:
  29. videosrc.set_property("preview-x", SCREEN_WIDTH)
  30. videosrc.set_property("preview-y", SCREEN_HEIGHT)
  31. else:
  32. videosrc.set_property("preview-x", 0)
  33. videosrc.set_property("preview-y", 0)
  34. def set_zoom(target):
  35. global zoom
  36. if target < zoom:
  37. direction = -1
  38. else:
  39. direction = 1
  40. target=min(target, 1)
  41. target=max(target, 0.40)
  42. while abs(target-zoom) > 0.01: #fuck IEEE floats
  43. zoom = zoom + direction*0.015
  44. zoom = min(zoom, 1)
  45. zoom = max(zoom, 0.4)
  46. videosrc.set_property("roi-x", (1-zoom)/2)
  47. videosrc.set_property("roi-y", (1-zoom)/2)
  48. videosrc.set_property("roi-w", zoom)
  49. videosrc.set_property("roi-h", zoom)
  50. time.sleep(0.03)
  51. def control():
  52. FIFO="/tmp/picamfifo"
  53. if os.path.exists(FIFO):
  54. if stat.S_ISFIFO(os.stat(FIFO).st_mode):
  55. pass
  56. else:
  57. os.remove(FIFO)
  58. os.mkfifo(FIFO)
  59. else:
  60. os.mkfifo(FIFO)
  61. while True:
  62. with open(FIFO) as fifo:
  63. line=fifo.read().strip()
  64. print("Got: ", line)
  65. if "=" not in line:
  66. print("Invalid line.")
  67. continue
  68. key = line.split("=")[0]
  69. val = line.split("=")[1]
  70. if key == "preview":
  71. set_preview(int(val))
  72. if key == "zoom":
  73. set_zoom(float(val))
  74. if __name__ == "__main__":
  75. if 'LD_LIBRARY_PATH' not in os.environ:
  76. os.environ['LD_LIBRARY_PATH'] = '/usr/local/lib'
  77. os.execv(sys.argv[0], sys.argv)
  78. # initialization
  79. Gst.init(None)
  80. videocodec = "video/x-h264, width=%d, height=%d, framerate=25/1, profile=high ! h264parse" % (WIDTH, HEIGHT)
  81. p = "rpicamsrc sensor-mode=4 do-timestamp=true name=src ! "+videocodec+" ! matroskamux ! tcpserversink host=0.0.0.0 port=5000 sync-method=burst-keyframe"
  82. print(p)
  83. pipeline = Gst.parse_launch (p)
  84. if pipeline == None:
  85. print ("Failed to create pipeline")
  86. sys.exit(0)
  87. videosrc = pipeline.get_by_name ("src")
  88. videosrc.set_property("preview", 1)
  89. videosrc.set_property("preview-w", WIDTH)
  90. videosrc.set_property("preview-h", HEIGHT)
  91. videosrc.set_property("fullscreen", False)
  92. # videosrc.set_property("bitrate", 16000000)
  93. videosrc.set_property("bitrate", 25000000)
  94. videosrc.set_property("rotation", 180)
  95. set_preview(0)
  96. # run
  97. pipeline.set_state(Gst.State.PLAYING)
  98. t = threading.Thread(target=control, daemon=True)
  99. t.start()
  100. while True:
  101. time.sleep(10000)
  102. # cleanup
  103. pipeline.set_state(Gst.State.NULL)