Is a set of libraries wrote in .net standard to allow control a CasparrCG server and receive OSC messages.
CasparCG Server is a Windows and Linux software used to play out professional graphics, audio and video to multiple outputs. It has been in 24/7 broadcast production since 2006.
More info about CasparCG Server here
You can contact me or discuss about this lib here
Compatible to 2.0.7 version to 2.2 of CasparCG for now. Currently testing on 2.3 please feel free to test and report issue if you found one.
Badges | |
---|---|
Build | |
Nuget for AMCP Control | |
Nuget for OSC | |
Nuget for OSC Event Hub |
List of supported .net framework.
- .net6
- and more other here the compatibility matrix
dotnet add package StarDust.CasparCG.net.Microsoft.DependencyInjection
Use of dependency injection
The library can be use with Dependency Injection. In this example we use Microsoft Dependency Injection. Register all dependencies: Snippet
static void ConfigureIOC(IServiceCollection services)
{
services.AddCasparCG();
}
Initialize connection
Then you just need to call the Configure IOC and enjoy ;):
ConfigureIOC();
//Get casparCG device instance
var casparCGServer = serviceProvider.GetService<ICasparDevice>();
//Handler to be notify if the Server is connected or disconnected
casparCGServer.ConnectionStatusChanged += CasparDevice_ConnectionStatusChanged;
//Initialize the connection
casparCGServer.Connect("127.0.0.1");
Work with server
You can get the version of the current CasparCG Server:
var casparCGServer = serviceProvider.GetService<ICasparDevice>();
Console.WriteLine(casparCGServer.GetVersion());
Or clips list:
var casparCGServer = serviceProvider.GetService<ICasparDevice>();
var clips = casparCGServer.GetMediafiles();
Work with Channel Manager:
At the first connection the code will retrieve all channels available. The library declare a Channel manager for each channel. Channel manager has the amcp command that require a channel ID. If you want to play a clip on a channel
var channel = casparCGServer.Channels.First(x => x.ID == 1);
channel.LoadBG(new CasparPlayingInfoItem { VideoLayer = 1, Clipname = "AMB" });
channel.Play(1);
Work with CG Manager: A CG Manager is present on each Channel Manager If you want to play a template:
var channel = casparCGServer.Channels.First(x => x.ID == 1);
channel.CG.Add(10, 1, "caspar_text");
channel.CG.Play(10, 1);
Work with Mixer Manager: A Mixer Manager is present on each Channel Manager If you want to play with the mixer here we set the brigthness:
var channel = casparCGServer.Channels.First(x => x.ID == 1);
channel.Mixer.Brightness(1, 0.2F);
Demo project
You can see more example in demo project.
dotnet add package StarDust.CasparCG.net.OSC
Use of dependency injection
_container = new UnityContainer();
_container.RegisterType<IOscListener, OscListener>(new ContainerControlledLifetimeManager());
///Create a connection to CasparCG Server to allow osc message to be sent
_container.RegisterInstance<IServerConnection>( new ServerConnection(),new SingletonLifetimeManager());
Initialize the connection to listen to OSC message
///Connect to CasparCG to allow OSC message to be sent to osc client
_container.Resolve<IServerConnection>().Connect(new CasparCGConnectionSettings("127.0.0.1"));
//Get an instance of OcsListener from Unity
var oscListener = _container.Resolve<IOscListener>();
//Attach to event to get the OSC message when received
oscListener.OscMessageReceived += OscListener_OscMessageReceived;
//Begin to listen to OSC Message from CasparCG
oscListener.StartListening("127.0.0.1", 6250);
Stop to listen
oscListener.StopListening();
Can filter to receive notification only for some address
//Filter for a simple address
oscListener.AddToAddressFiltered("/channel/1/stage/layer/1/file/time");
//Filter for a range of address. Here we get all address for layer to 1-1000... and channel 1-10000...
oscListener.AddToAddressFiltered("/channel/[0-9]/stage/layer/[0-9]/file/time");
//Filter by regex. Here we want all message that begin by /channel/1/stage/layer/1 and not ended by time
oscListener.AddToAddressFilteredWithRegex("^/channel/[0-9]/stage/layer/1(?!.*?time)");
Or you can simply black list an address to don't be notify for it
//I don't want to be notify for this address, in this case [0-9] means for all channels
oscListener.AddToAddressBlackList("/channel/[0-9]/output/consume_time");
//Or you can use also a regex
oscListener.AddToAddressBlackListWithRegex("^/channel/[0-9]/stage/layer/1(?!.*?time)");
Remove from filtered list address
Pass the address or the pattern that you add before
oscListener.RemoveFromAddressFiltered("/channel/1/stage/layer/1/file/time");
Remove from black list address
Pass the address or the pattern that you add before
oscListener.RemoveFromAddressBlackListed("/channel/[0-9]/output/consume_time");
Demo project
You can see more example in demo project.
OSC Event hub is a class that capture the osc message parse the address and trigger .net event.
How to start up. Obviously ready for the Dependency injection. So you need to map interface and class. OSC Event hub has a dependency to the Osc listener.
dotnet add package StarDust.CasparCG.net.OSC.EventHub
Configure dependencies
_container = new UnityContainer();
_container.RegisterType<IOscListener, OscListener>(new ContainerControlledLifetimeManager());
_container.RegisterType<ICasparCGOscEventsHub, CasparCGOscEventsHub>();
///Create a connection to CasparCG Server to allow osc message to be sent
_container.RegisterInstance<IServerConnection>( new ServerConnection(),new SingletonLifetimeManager());
var eventHub = _container.Resolve<ICasparCGOscEventsHub>();
//Attach the desire event
eventHub.PlaybackClipChanged += OnPlaybackClipChanged;
///Connect to CasparCG to allow OSC message to be sent to osc client
_container.Resolve<IServerConnection>().Connect(new CasparCGConnectionSettings("127.0.0.1"));
//Start to listen Osc message on 6250 port. Check your Osc port on the config of Caspar CG
eventHub.CasparCgOscListener.StartListening(6250);
Address | Example Arguments | Description | Event | |
---|---|---|---|---|
/channel/[0-9]/ | format | PAL | The video format of the channel | OutputFormatChanged |
profiler/time | 0.041 | 0.04 | The amount of time that CasparCG Server is spending rendering the frame, two arguments are sent in this message, what it is and what it should be as shown in the example. | ProfilerTimeChanged | |
output/port/[0-9]/type | screen | A message like this will exists for each of the outputs in use, with the default CasparCG config file in use this will result in two rows; one of type screen, and one of type system-audio. Current types are [[screen|Screen Consumer]], system-audio, [[decklink|Decklink Consumer]], [[bluefish|Bluefish Consumer]] and [[file|Disk Consumer]] | OutputPortChanged | |
output/port/[0-9]/frame | 200 | 922222222888836854 | The number of frames that have been created by the consumer on this port, the example indicates that 200 frames have been written to disk and that a maximum of 922222222888836854 can be written. | ConsumerFrameCreatedChanged |
Stage messages contain properties related to CasparCG Server layers and the producers that are contained within them.
The following messages do not directly relate to a producer.
Address | Example Arguments | Description | Event | |
---|---|---|---|---|
/channel/[0-9]/stage/layer/[0-9]/ | time | 101.24 | Seconds the layer has been active | LayerActiveTimeChanged |
frame | 2531 | Time in frames that the layer has been active | LayerActiveFrameChanged | |
type | transition | LayerTypeChanged | ||
background/type | empty | BackgroundLayerTypeChanged | ||
profiler/time | 0.39 | 0.4 | Actual | Expected time on frame | LayerProfilerChanged | |
paused | True/False | Whether the layer is paused or not | LayerPausedChanged |
Address | Example Arguments | Description | Event |
---|---|---|---|
file/time | 12 / 400 | Seconds elapsed on file playback / Total Seconds | PlaybackClipTimeChanged |
file/frame | 300 / 10000 | Frames elapsed on file playback / Total frames | PlaybackClipFrameChanged |
file/fps | 25 | Framerate of the file being played | PlaybackClipFrameRateChanged |
file/path | AMB.mp4 | Filename and path (if file is in a sub-folder) of the media file, paths relative to the media folder defined in the config file | PlaybackClipPathChanged |
file/video/width | 1920 | Frame width of the video file | PlaybackClipWidthChanged |
file/video/height | 1080 | Frame height of the video file | PlaybackClipHeightChanged |
file/video/field | progressive | Scan type of the video file, progressive or interlaced | PlaybackClipFieldChanged |
file/video/codec | H.264 /AVC | Codec of the video file | PlaybackClipVideoCodecChanged |
file/audio/sample-rate | 48000 | Audio sample rate of this files audio track | PlaybackClipAudioSampleRateChanged |
file/audio/channels | 2 | Number of channels in this files audio track | PlaybackClipAudioChannelsChanged |
file/audio/format | s16 | Audio compression format, in this case uncompressed 16 bit PCM audio | PlaybackClipAudioFormatChanged |
file/audio/codec | AAC | Audio codec for the audio track in this file | PlaybackClipAudioCodecChanged |
loop | 1 | Whether the file is set to loop playback or not, only applies to ffmpeg inputs of type file not stream or device. | PlaybackLoopChanged |
The messages below may be produced when an object utilising the [[Flash Producer]] is in use on the stage.
Address | Example Arguments | Description | Event | |
---|---|---|---|---|
/channel/[0-9]/stage/layer/[0-9]/host/ | path | template_file.ft | TemplatePathChanged | |
width | 1920 | TemplateWidthChanged | ||
height | 1080 | TemplateHeightChanged | ||
fps | 50 | TemplateFpsChanged | ||
/channel/[0-9]/stage/layer/[0-9]/ | buffer | FlashProducerBufferChanged |
The majority of information from CasparCG's compositing module is not yet made available via OSC (an issue is open for this), the only information available currently is audio related as listed below.
Address | Example Arguments | Description | Event | |
---|---|---|---|---|
/channel/[0-9]/mixer/audio/ | nb_channels | 2 | Number of audio channels in use on this CasparCG channel | MixerAudioChannelsCountChanged |
[0-9]/dBFS | -20 | Audio level in dBFS | MixerAudioDbfsChanged |
- Abstract looging to add logging
- Fill missing XML Doc. Some help is welcome :p
- Implement lib that trigger event for CasparCG OSC messages
- For some enhancement request, please open a ticket.
- Feel free for feedcback on the caspar CG Forum topic