1

How do I correctly write a synchronization tag for two videos in a KVA file?

<?xml version="1.0" encoding="utf-8"?>
<KinoveaWorkspace>
  <FormatVersion>1.0</FormatVersion>
  <Name>CompareTwoVideos</Name>
  <Id>00000000-0000-0000-0000-000000000000</Id>

  <ScreenDescriptionPlayback>
    <FullPath>%file1%</FullPath>
    <Autoplay>true</Autoplay>
    <SpeedPercentage>100</SpeedPercentage>
    <Stretch>false</Stretch>
    <IsReplayWatcher>false</IsReplayWatcher>
  </ScreenDescriptionPlayback>

  <ScreenDescriptionPlayback>
    <FullPath>%file2%</FullPath>
    <Autoplay>true</Autoplay>
    <SpeedPercentage>100</SpeedPercentage>
    <Stretch>false</Stretch>
    <IsReplayWatcher>false</IsReplayWatcher>
  </ScreenDescriptionPlayback>

  <Synchronization>
    <SyncPair screenA="0" keyframeIndexA="0" screenB="1" keyframeIndexB="0" />
  </Synchronization>
</KinoveaWorkspace>

That is, so that it can be run as follows —

"C:\Program Files\Kinovea\Kinovea.exe" -workspace "C:\Temp\compare.kva"

And see the following in the program that opens? —

https://s1.hostingkartinok.com/uploads/thumbs/2025/10/87537edf1c6c056974fa2ee8c6811ad9.png

2

Hi,
Synchronization works via the "time origin" annotation and is saved in KVA files. So the way to do this would be to have a KVA file for each video with a time origin set a the timestamp of the sync point.

Please note that this workspace file format will be obsolete in the next version as the multi-window system has been rewritten and better integrated in the program, and furthermore "workspace" means a different thing now.

Are you generating these files from code or are you editing manually? The timestamps are not in seconds or frames they are in a unit that depends on the video file so it's a bit more complicated.

3 (edited by peterverhovensky Yesterday 21:17:53)

Hi!
I generated these files from code—a simple AHK script that opens the selected video pair in the program with the F6 key—

; Kinovea Loader
; Works with selected files in Explorer:
; 1 file  → opens one screen
; 2 files → comparison in two screens
; >2 files → the first two are taken

#NoEnv
#SingleInstance Force
SetWorkingDir %A_ScriptDir%

f6::
{
    files := Explorer_GetSelection()
    files := StrSplit(files, "`n")
    count := files.MaxIndex()
    if (count == "")
        count := 0

    ;MsgBox, %files%`n`n%count%

    if (count < 1) {
        MsgBox, 48, Error, No file selected!
        return
    }

    if (count > 2) {
        MsgBox, 64, Attention, More than two files selected. The first two will be used.
        count := 2
    }

    tempFile := A_Temp "\compare.kva"

    if (count = 1) {
        ; One file — single screen
        file1 := files[1]
        xml =
        (
<?xml version="1.0" encoding="utf-8"?>
<KinoveaWorkspace>
  <FormatVersion>1.0</FormatVersion>
  <Name>SingleVideo</Name>
  <Id>00000000-0000-0000-0000-000000000000</Id>

  <ScreenDescriptionPlayback>
    <FullPath>%file1%</FullPath>
    <Autoplay>true</Autoplay>
    <SpeedPercentage>100</SpeedPercentage>
    <Stretch>false</Stretch>
    <IsReplayWatcher>false</IsReplayWatcher>
  </ScreenDescriptionPlayback>

</KinoveaWorkspace>
        )
    }
    else if (count = 2) {
        ; Two files — comparison
        file1 := files[1]
        file2 := files[2]
        xml =
        (
<?xml version="1.0" encoding="utf-8"?>
<KinoveaWorkspace>
  <FormatVersion>1.0</FormatVersion>
  <Name>CompareTwoVideos</Name>
  <Id>00000000-0000-0000-0000-000000000000</Id>

  <ScreenDescriptionPlayback>
    <FullPath>%file1%</FullPath>
    <Autoplay>true</Autoplay>
    <SpeedPercentage>100</SpeedPercentage>
    <Stretch>false</Stretch>
    <IsReplayWatcher>false</IsReplayWatcher>
  </ScreenDescriptionPlayback>

  <ScreenDescriptionPlayback>
    <FullPath>%file2%</FullPath>
    <Autoplay>true</Autoplay>
    <SpeedPercentage>100</SpeedPercentage>
    <Stretch>false</Stretch>
    <IsReplayWatcher>false</IsReplayWatcher>
  </ScreenDescriptionPlayback>

  <Synchronization>
    <SyncPair screenA="0" keyframeIndexA="0" screenB="1" keyframeIndexB="0" />
  </Synchronization>
</KinoveaWorkspace>
        )
    }

    FileDelete, %tempFile%
    FileAppend, %xml%, %tempFile%, UTF-8

    Run, "C:\Program Files\Kinovea\Kinovea.exe" -workspace "%tempFile%"
}
return

Explorer_GetSelection(hwnd="") { 
    WinGet, process, processName, % "ahk_id" hwnd := hwnd? hwnd:WinExist("A") 
    WinGetClass class, ahk_id %hwnd% 
    if (process = "explorer.exe") 
        if (class ~= "Progman|WorkerW") { 
            ControlGet, files, List, Selected Col1, SysListView321, ahk_class %class% 
            Loop, Parse, files, `n, `r 
                ToReturn .= A_Desktop "\" A_LoopField "`n" 
        } else if (class ~= "(Cabinet|Explore)WClass") { 
            for window in ComObjCreate("Shell.Application").Windows 
                if (window.hwnd==hwnd) 
                    sel := window.Document.SelectedItems 
            for item in sel 
                ToReturn .= item.path "`n" 
        } 
    return Trim(ToReturn,"`n") 
}

Since there is a need to view identical videos, the idea arose to use ffmpeg to create screenshots of each video before opening the video files and synchronize them according to the first non-black images. But since you are planning to make changes, I will think about it later.
Thank you!