cam.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  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 add_client(c):
  52. if "192.168" not in c or ":" not in c:
  53. print("Invalid client! format is 192.168.Y.Z:XXXX")
  54. return
  55. cur_clients=sink.get_property("clients").split(",")
  56. print(cur_clients)
  57. if c in cur_clients:
  58. print("Client exists!")
  59. return
  60. cur_clients.append(c)
  61. strclients = ",".join(cur_clients)
  62. sink.set_property("clients", strclients)
  63. def control():
  64. FIFO="/tmp/picamfifo"
  65. if os.path.exists(FIFO):
  66. if stat.S_ISFIFO(os.stat(FIFO).st_mode):
  67. pass
  68. else:
  69. os.remove(FIFO)
  70. os.mkfifo(FIFO)
  71. else:
  72. os.mkfifo(FIFO)
  73. while True:
  74. with open(FIFO) as fifo:
  75. line=fifo.read().strip()
  76. print("Got: ", line)
  77. if "=" not in line:
  78. print("Invalid line.")
  79. continue
  80. key = line.split("=")[0]
  81. val = line.split("=")[1]
  82. if key == "preview":
  83. set_preview(int(val))
  84. if key == "zoom":
  85. set_zoom(float(val))
  86. if key == "client" :
  87. add_client(val)
  88. if __name__ == "__main__":
  89. if 'LD_LIBRARY_PATH' not in os.environ:
  90. os.environ['LD_LIBRARY_PATH'] = '/usr/local/lib'
  91. os.execv(sys.argv[0], sys.argv)
  92. # initialization
  93. Gst.init(None)
  94. videocodec = "queue ! video/x-h264, width=%d, height=%d, framerate=25/1, profile=high ! h264parse ! rtph264pay mtu=1360 config-interval=1" % (WIDTH, HEIGHT)
  95. p = "rpicamsrc sensor-mode=4 do-timestamp=true name=src ! "+videocodec+" ! multiudpsink name=out"
  96. pipeline = Gst.parse_launch (p)
  97. if pipeline == None:
  98. print ("Failed to create pipeline")
  99. sys.exit(0)
  100. videosrc = pipeline.get_by_name ("src")
  101. videosrc.set_property("preview", 1)
  102. videosrc.set_property("preview-w", WIDTH)
  103. videosrc.set_property("preview-h", HEIGHT)
  104. videosrc.set_property("fullscreen", False)
  105. videosrc.set_property("bitrate", 16000000)
  106. videosrc.set_property("rotation", 180)
  107. set_preview(0)
  108. sink = pipeline.get_by_name ("out")
  109. # sink.set_property("clients", ",".join(["192.168.2.120:5000", "192.168.2.21:5000", "192.168.2.84:5000"]))
  110. sink.set_property("clients", ",".join(["192.168.2.21:5000"]))
  111. print(sink.get_property("clients"))
  112. # run
  113. pipeline.set_state(Gst.State.PLAYING)
  114. t = threading.Thread(target=control, daemon=True)
  115. t.start()
  116. while True:
  117. time.sleep(10000)
  118. # cleanup
  119. pipeline.set_state(Gst.State.NULL)