cam.py 3.7 KB

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