2012-10-28 100 views
1

我想將計算機與外部攝像機錄製同步,以便我可以準確地(毫秒)知道計算機記錄的其他傳感器發生某些記錄事件時的情況。一個想法是從攝像機上的麥克風拾取的計算機每秒播放短的聲音脈衝或啁啾聲。但是播放聲音剪輯的簡單cron作業的準確性還不夠精確。我正在考慮使用類似gstreamer的東西,但是如何根據系統時鐘在某個特定時間播放剪輯呢?絕對音頻同步

回答

0

如果您知道攝像機的開始時間,則可以從捕獲的視頻流中隨時獲取視頻的時間。你不需要這樣做。每個框架都有一個時間戳與容器相關聯,確切的時間可以被知道。所有你需要的是注意開始的牆壁時間。

編輯:另一種方法做到這一點如下:如果你有一個你信任的時鐘,你可以把它放在攝像機的路徑?所以你總是對視頻本身有一個衡量標準。

+0

我試圖解決的問題是如何準確地同步攝像機的時鐘與計算機上的時鐘。我懷疑時鐘也會因爲使用不同的晶體而相對於彼此漂移。我正在計劃播放聲音以在已知時間播放計算機(或時間),然後我可以將錄製的聲音與傳輸的時間相對應,並映射攝像機時間戳相對於計算機的時鐘偏移和偏移。 – mike80553

+0

除非您正在尋找絕對ns和微秒精度,否則漂移應該非常小,並且建立時間非常長。你如何確保你的電腦時鐘沒有錯誤地漂移?我認爲你已經完成了它的設計。如果我有一個視頻,我知道從視頻的起點到精確到毫秒的每個視頻幀的確切時間戳偏移量。那麼,爲什麼不應該只測量開始時間就夠了?如果你不相信我在原始答案中提出了另一種機制。 – av501

+0

但是如何建議測量攝像機未直接連接到計算機時的開始時間?我想你的視頻放置時鐘的想法與我的想法是在錄音機的聽力範圍內放置一個鬧鐘的想法相似;-) – mike80553

0

這是我在解決這個問題的嘗試。我從http://pygstdocs.berlios.de/pygst-tutorial/playbin.html修改了一個gstreamer python tutorial命令行playbin(例2.3),以與系統時鐘同步的定義間隔重複播放聲音文件。

我已經確認管道使用系統時鐘而不是來自接收器的默認時鐘,並且禁止管道設置元素的基準時間。 然後在文件完成播放後,它會回到起點,並且手動設置基準時間,以便接收器將等待在下一個時期播放緩衝區。

#!/usr/bin/env python 

import sys, os 
#import time, thread 
import glib,gobject 
import pygst 
pygst.require("0.10") 
import gst 

class CLI_Main: 

    def __init__(self): 
    self.player = gst.element_factory_make("playbin2", "player") 
    fakesink = gst.element_factory_make("fakesink", "fakesink") 
    self.player.set_property("video-sink", fakesink) 
    bus = self.player.get_bus() 
    bus.add_signal_watch() 
    bus.connect("message", self.on_message) 

    # use the system clock instead of the sink's clock 
    self.sysclock = gst.system_clock_obtain() 
    self.player.use_clock(self.sysclock) 

    # disable the pipeline from setting element base times 
    self.player.set_start_time(gst.CLOCK_TIME_NONE) 
    # default tick interval 
    self.tick_interval = 1; 

    self.tick_interval = float(sys.argv[1]) 
    filepath = sys.argv[2] 
    if os.path.isfile(filepath): 
     self.playmode = True 
     self.player.set_property("uri", "file://" + filepath) 
     current_time = self.sysclock.get_time() 
     print current_time 
     play_time = (current_time/long(self.tick_interval*gst.SECOND) + 1) * long(self.tick_interval*gst.SECOND) 
     print play_time 
     self.player.set_base_time(play_time) 
     self.player.set_state(gst.STATE_PLAYING) 
     print "starting" 

    def on_message(self, bus, message): 
    t = message.type 
    if t == gst.MESSAGE_EOS: 
     # compute the next time the sound should be played 
     current_time = self.sysclock.get_time() 
     play_time = (current_time/int(self.tick_interval*gst.SECOND) + 1)*int(self.tick_interval*gst.SECOND) 

     # setup the next time to play the sound and seek it to the beginning 
     self.player.set_base_time(play_time) 
     # seek the player so that the sound plays from the beginning 
     self.player.seek(1.0, gst.FORMAT_TIME, gst.SEEK_FLAG_FLUSH, gst.SEEK_TYPE_SET, 0L, gst.SEEK_TYPE_NONE, 0L) 
     # make sure that the player will play 
     self.player.set_state(gst.STATE_PLAYING) 
     #self.playmode = False 
     print play_time 

    elif t == gst.MESSAGE_ERROR: 
     self.player.set_state(gst.STATE_NULL) 
     err, debug = message.parse_error() 
     print "Error: %s" % err, debug 
     self.playmode = False 


mainclass = CLI_Main() 
loop = glib.MainLoop() 
loop.run() 

對不起,如果代碼被黑屏和雜亂;我對Python仍然很陌生。