# Record Tracking Data and Video in C# (AR51.Net)

Record **tracking data** and, from the cameras you choose, **video**. Recordings are saved on the AR 51 servers, in a folder named after the recording.

## Start and stop a recording

```csharp
await ar51.Recording.StartRecordingAsync(new RecordingOptions
{
    Name = "take-01",
    CameraIds = new[] { camera.Id },   // empty = tracking data only, no video
});

await Task.Delay(TimeSpan.FromSeconds(5));
await ar51.Recording.StopRecordingAsync();
```

- `Name` is required — it's also the folder name on the servers, so it must be a valid folder name.
- Video is recorded at each camera's own resolution and frame rate.
- **All or nothing:** if a camera doesn't exist or fails to start, `StartRecordingAsync` throws and stops the parts that did start.
- **One recording at a time.** If a recording is already running — started by any app — `StartRecordingAsync` throws `AR51Exception` with `Rejected` and the message "A recording is already running. Stop it first.", without touching any camera. Start recordings from one app at a time: on current servers, another app that starts a recording while yours runs can end your recording's video early.
- `StopRecordingAsync` stops whatever is recording, **including a recording another app started** — so stop only a recording your app started.

## Follow the recording state

`IsRecording` and `RecordingStateChanged` follow the system live, whoever started the recording — checked about once a second:

```csharp
ar51.Recording.RecordingStateChanged += (_, e) => Console.WriteLine(e.IsRecording ? "Recording..." : "Recording stopped.");
```

## Complete sample

Record for a few seconds. Run it as `dotnet run -- take-01 5 <camera id> …` — the name, the number of seconds, then the cameras to record video from (none = tracking data only).

{/* SAMPLE:07-recording — generated from the ar51-net-samples repo; edit there */}
```csharp title="Program.cs"
// Record tracking data and video from chosen cameras for a few seconds.
// Usage: dotnet run -- <name> [seconds] [camera id ...]   (no camera ids = tracking data only)
// Recordings are saved on the AR 51 servers, in a folder with the recording's name.
using AR51.Net;

if (args.Length == 0) { Console.WriteLine("Usage: dotnet run -- <name> [seconds] [camera id ...]"); return; }
var name = args[0];
var seconds = args.Length > 1 ? int.Parse(args[1]) : 5;
var cameraIds = args.Skip(2).ToList();

await using IAR51Client ar51 = AR51Client.Create();
ar51.Recording.RecordingStateChanged += (_, e) => Console.WriteLine(e.IsRecording ? "Recording..." : "Recording stopped.");
await ar51.StartAsync();

var started = false;
try
{
    // All or nothing: if one camera fails to start, nothing is left half-started.
    // A recording that is already running (started by another app) is refused with AR51ErrorCode.Rejected.
    await ar51.Recording.StartRecordingAsync(new RecordingOptions { Name = name, CameraIds = cameraIds });
    started = true;
    await Task.Delay(TimeSpan.FromSeconds(seconds));
}
catch (AR51Exception exception)
{
    Console.WriteLine($"Recording failed ({exception.ErrorCode}): {exception.Message}");
}
finally
{
    // Stop only the recording this program started, never one another app is running.
    if (started) await ar51.Recording.StopRecordingAsync();
}
```

[View this sample on Bitbucket](https://bitbucket.org/ar51/ar51-net-samples/src/main/07-recording/) — clone the [samples repository](https://bitbucket.org/ar51/ar51-net-samples) to run it.
{/* /SAMPLE */}

## Reference

[`IRecordingClient`](/docs/sdk-api/csharp-api/classes/irecordingclient/) · [`RecordingOptions`](/docs/sdk-api/csharp-api/classes/irecordingclient/#recordingoptions)
