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. def bus_call(bus, msg, *args):
  11. if msg.type == Gst.MessageType.EOS:
  12. print("End-of-stream")
  13. loop.quit()
  14. return
  15. elif msg.type == Gst.MessageType.ERROR:
  16. print("GST ERROR", msg.parse_error())
  17. loop.quit()
  18. return
  19. return True
  20. zoom = 1
  21. def quit():
  22. pipeline.send_event(Gst.Event.new_eos())
  23. def set_preview(val):
  24. if val == 0:
  25. videosrc.set_property("preview-x", 800)
  26. videosrc.set_property("preview-y", 600)
  27. else:
  28. videosrc.set_property("preview-x", 0)
  29. videosrc.set_property("preview-y", 0)
  30. def set_zoom(target):
  31. global zoom
  32. if target < zoom:
  33. direction = -1
  34. else:
  35. direction = 1
  36. target=min(target, 1)
  37. target=max(target, 0.50)
  38. while abs(target-zoom) > 0.01: #fuck IEEE floats
  39. zoom = zoom + direction*0.015
  40. zoom = min(zoom, 1)
  41. zoom = max(zoom, 0.4)
  42. videosrc.set_property("roi-x", (1-zoom)/2)
  43. videosrc.set_property("roi-y", (1-zoom)/2)
  44. videosrc.set_property("roi-w", zoom)
  45. videosrc.set_property("roi-h", zoom)
  46. time.sleep(0.03)
  47. def add_client(c):
  48. if "192.168" not in c or ":" not in c:
  49. print("Invalid client! format is 192.168.Y.Z:XXXX")
  50. return
  51. cur_clients=sink.get_property("clients").split(",")
  52. print(cur_clients)
  53. if c in cur_clients:
  54. print("Client exists!")
  55. return
  56. cur_clients.append(c)
  57. strclients = ",".join(cur_clients)
  58. sink.set_property("clients", strclients)
  59. def control():
  60. FIFO="/tmp/picamfifo"
  61. if os.path.exists(FIFO) and stat.S_ISFIFO(os.stat(FIFO).st_mode):
  62. pass
  63. else:
  64. os.mkfifo(FIFO)
  65. while True:
  66. with open(FIFO) as fifo:
  67. line=fifo.read().strip()
  68. print("Got: ", line)
  69. if "=" not in line:
  70. print("Invalid line.")
  71. continue
  72. key = line.split("=")[0]
  73. val = line.split("=")[1]
  74. if key == "preview":
  75. set_preview(val)
  76. if key == "zoom":
  77. set_zoom(float(val))
  78. if key == "client" :
  79. add_client(val)
  80. if __name__ == "__main__":
  81. # initialization
  82. Gst.init(None)
  83. videocodec = "queue ! video/x-h264, width=800, height=600, framerate=24/1, profile=high ! h264parse ! rtph264pay config-interval=1"
  84. p = "rpicamsrc do-timestamp=true name=src ! "+videocodec+" ! multiudpsink name=out"
  85. pipeline = Gst.parse_launch (p)
  86. if pipeline == None:
  87. print ("Failed to create pipeline")
  88. sys.exit(0)
  89. videosrc = pipeline.get_by_name ("src")
  90. videosrc.set_property("preview", 1)
  91. videosrc.set_property("fullscreen", False)
  92. videosrc.set_property("bitrate", 800000)
  93. videosrc.set_property("rotation", 180)
  94. set_preview(0)
  95. sink = pipeline.get_by_name ("out")
  96. sink.set_property("clients", ",".join(["192.168.2.120:5000"]))
  97. print(sink.get_property("clients"))
  98. # run
  99. pipeline.set_state(Gst.State.PLAYING)
  100. t = threading.Thread(target=control, daemon=True)
  101. t.start()
  102. while True:
  103. time.sleep(10000)
  104. # cleanup
  105. pipeline.set_state(Gst.State.NULL)