cam.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  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):
  62. if stat.S_ISFIFO(os.stat(FIFO).st_mode):
  63. pass
  64. else:
  65. os.remove(FIFO)
  66. os.mkfifo(FIFO)
  67. else:
  68. os.mkfifo(FIFO)
  69. while True:
  70. with open(FIFO) as fifo:
  71. line=fifo.read().strip()
  72. print("Got: ", line)
  73. if "=" not in line:
  74. print("Invalid line.")
  75. continue
  76. key = line.split("=")[0]
  77. val = line.split("=")[1]
  78. if key == "preview":
  79. set_preview(int(val))
  80. if key == "zoom":
  81. set_zoom(float(val))
  82. if key == "client" :
  83. add_client(val)
  84. if __name__ == "__main__":
  85. # initialization
  86. Gst.init(None)
  87. videocodec = "queue ! video/x-h264, width=800, height=600, framerate=24/1, profile=high ! h264parse ! rtph264pay config-interval=1"
  88. p = "rpicamsrc do-timestamp=true name=src ! "+videocodec+" ! multiudpsink name=out"
  89. pipeline = Gst.parse_launch (p)
  90. if pipeline == None:
  91. print ("Failed to create pipeline")
  92. sys.exit(0)
  93. videosrc = pipeline.get_by_name ("src")
  94. videosrc.set_property("preview", 1)
  95. videosrc.set_property("preview-w", 800)
  96. videosrc.set_property("preview-h", 600)
  97. videosrc.set_property("fullscreen", False)
  98. videosrc.set_property("bitrate", 900000)
  99. videosrc.set_property("rotation", 180)
  100. set_preview(0)
  101. sink = pipeline.get_by_name ("out")
  102. sink.set_property("clients", ",".join(["192.168.2.120:5000"]))
  103. print(sink.get_property("clients"))
  104. # run
  105. pipeline.set_state(Gst.State.PLAYING)
  106. t = threading.Thread(target=control, daemon=True)
  107. t.start()
  108. while True:
  109. time.sleep(10000)
  110. # cleanup
  111. pipeline.set_state(Gst.State.NULL)