import sys import gi gi.require_version('Gst', '1.0') gi.require_version('GstNet', '1.0') from gi.repository import Gst, GstNet, GObject, GLib Gst.init([]) mainloop = GLib.MainLoop() # audiotestsrc to aes67 pipelineString = """ audiotestsrc freq=480 volume=0.1 ! audioconvert ! audio/x-raw, format=S24BE, channels=2, rate=48000 ! rtpL24pay name=rtppay min-ptime=1000000 max-ptime=1000000 ! application/x-rtp, clock-rate=48000, channels=2, payload=98 ! udpsink host=239.69.0.121 port=5004 qos=true qos-dscp=34 multicast-iface=eth0 """ if GstNet.ptp_init(GstNet.PTP_CLOCK_ID_NONE, ['eth0']): print('PTP initialized') else: print('PTP failed to initialize') sys.exit() ptpClock = GstNet.PtpClock.new('PTP-Master', 0) if ptpClock != None: print('PTP clock obtained') else: print('PTP failed to obtain clock') sys.exit() def ptpstats(domain, stats, userdata): t = stats.get_name() if t == GstNet.PTP_STATISTICS_NEW_DOMAIN_FOUND: print('PTP new domain found') elif t == GstNet.PTP_STATISTICS_BEST_MASTER_CLOCK_SELECTED: print("PTP master clock selected") elif t == GstNet.PTP_STATISTICS_PATH_DELAY_MEASURED: print('PTP path delay measured') elif t == GstNet.PTP_STATISTICS_TIME_UPDATED: print('PTP time updated') if ptpClock.is_synced(): calcOffset = (round((ptpClock.get_time()) * (48 / 1000000)) & 0xffffffff) currentOffset = pipeline.get_by_name('rtppay').get_property("timestamp") diff = (currentOffset - calcOffset) print("Difference of", diff, "samples") if diff < 0: pipeline.set_state(Gst.State.PAUSED) pipeline.set_state(Gst.State.READY) calcOffset = (round((ptpClock.get_time()) * (48 / 1000000)) & 0xffffffff) - diff + 96 pipeline.get_by_name('rtppay').set_property("timestamp-offset", calcOffset) pipeline.set_state(Gst.State.PLAYING) return True GstNet.ptp_statistics_callback_add(ptpstats, None) print('PTP Syncing to Master') ptpClock.wait_for_sync(Gst.CLOCK_TIME_NONE) print('PTP successfully synced to Master') pipeline = Gst.parse_launch(pipelineString) pipeline.use_clock(ptpClock) # calculate intial offset (gstreamer uses random offset as default) ptpOffset = (round((ptpClock.get_time()) * (48000 / 1000000000)) & 0xffffffff) # convert ptp nanosecond timestamp to mediaclock add 72 (1.5ms) as offset for time alignment # ptpOffset = (round((ptpClock.get_time()) * (48000 / 1000000000)) & 0xffffffff) + round(20*48) # convert ptp nanosecond timestamp to mediaclock add 72 (1.5ms) as offset for time alignment pipeline.get_by_name('rtppay').set_property("timestamp-offset", ptpOffset) pipeline.set_state(Gst.State.PLAYING) print('starting mainloop') mainloop.run()