# Sync

This example shows how to synchronize two video streams, each coming from a different camera.

This example requires the DepthAI v3 API, see [installation instructions](https://docs.luxonis.com/software-v3/depthai.md).

## Pipeline

## Source code

#### Python

```python
import depthai as dai

pipeline = dai.Pipeline()
left = pipeline.create(dai.node.Camera).build(dai.CameraBoardSocket.CAM_B)
right = pipeline.create(dai.node.Camera).build(dai.CameraBoardSocket.CAM_C)

sync = pipeline.create(dai.node.Sync)
sync.setRunOnHost(True) # Can also run on device
left.requestFullResolutionOutput().link(sync.inputs["left"])
right.requestFullResolutionOutput().link(sync.inputs["right"])

outQueue = sync.out.createOutputQueue()
pipeline.start()

while pipeline.isRunning():
    messageGroup : dai.MessageGroup = outQueue.get()
    left = messageGroup["left"]
    right = messageGroup["right"]
    print(f"Timestamps, message group {messageGroup.getTimestamp()}, left {left.getTimestamp()}, right {right.getTimestamp()}")
```

#### C++

```cpp
#include <atomic>
#include <csignal>
#include <iostream>

#include "depthai/depthai.hpp"

std::atomic<bool> quitEvent(false);

void signalHandler(int) {
    quitEvent = true;
}

int main() {
    signal(SIGTERM, signalHandler);
    signal(SIGINT, signalHandler);

    // Create pipeline
    dai::Pipeline pipeline;

    // Create and configure camera nodes
    auto left = pipeline.create<dai::node::Camera>();
    left->build(dai::CameraBoardSocket::CAM_B);

    auto right = pipeline.create<dai::node::Camera>();
    right->build(dai::CameraBoardSocket::CAM_C);

    // Create and configure sync node
    auto sync = pipeline.create<dai::node::Sync>();
    sync->setRunOnHost(true);  // Can also run on device

    // Link cameras to sync inputs
    left->requestFullResolutionOutput()->link(sync->inputs["left"]);
    right->requestFullResolutionOutput()->link(sync->inputs["right"]);

    // Create output queue
    auto outQueue = sync->out.createOutputQueue();

    pipeline.start();

    while(pipeline.isRunning() && !quitEvent) {
        auto messageGroup = outQueue->get<dai::MessageGroup>();
        if(messageGroup == nullptr) continue;

        auto leftMsg = messageGroup->get<dai::ImgFrame>("left");
        auto rightMsg = messageGroup->get<dai::ImgFrame>("right");

        std::cout << "Timestamps, message group " << messageGroup->getTimestamp().time_since_epoch().count() << std::endl;
        std::cout << "left " << leftMsg->getTimestamp().time_since_epoch().count() << std::endl;
        std::cout << "right " << rightMsg->getTimestamp().time_since_epoch().count() << std::endl;

        if(cv::waitKey(1) == 'q') {
            break;
        }
    }

    pipeline.stop();
    pipeline.wait();

    return 0;
}
```

### Need assistance?

Head over to [Discussion Forum](https://discuss.luxonis.com/) for technical support or any other questions you might have.
