using System;
using System.Threading;
using Interop.TimecodeLib;
using GrassValley.Mseries.AppServer;
using GrassValley.Mseries.AppServerLog;
using GrassValley.Mseries.ChanStatus;
using GrassValley.Mseries.ConfigMgr;
using GrassValley.Mseries.Control;
using GrassValley.Mseries.DVCapture;
using GrassValley.Mseries.Editor;
using GrassValley.Mseries.MediaMgr;
using GrassValley.Mseries.Security;
using GrassValley.Mseries.Status;
using GrassValley.Mseries.TransferQueue;
// Leave the following "css_reference" lines in when running with CS-Script. They're
// more than just comments - they tell CS-Script which DLLs to load if the DLL
// name does not match the namespace that it implements.
//css_reference Credentials.dll;
//css_reference ServerUtil.dll;
/// ;
/// This is a sample CS-Script app for controlling the Grass Valley K2 server.
/// The code is regular C# code, but it's written for CS-Script which can
/// run it as a script from a DOS command prompt.
///
/// Go to the K2 AppServer Developer's Guide for more information:
/// http://www.gvgdevelopers.com/K2DevGuide/K2DevGuide.html#%5B%5BCS-Script%20Sample%20Scripts%5D%5D
///
/// For more information about CS-Script go to:
/// http://www.members.optusnet.com.au/~olegshilo/
/// ;
namespace K2Script
{
class Test
{
static int Main(string[] args)
{
// this example shows how to do insert edits and dual-context transitions. It uses three 10 second clips
// in the V:\default bin called "test1", "test2", and "test3".
try
{
// get the application's name & create a unique suite name
string appName = Environment.GetCommandLineArgs()[0];
string suiteName = appName + "_" + System.Guid.NewGuid().ToString("N");
// fill in these values for your connection (i.e. hardcode them, pass in
// cmdline arguments, read from file, read from console, etc.)
string host = "";
string username = "";
string password = "";
string domain = "";
// Connect to host & pass in credentials. The "using" block disposes connection when done.
using ( Connection connection = new Connection(appName, suiteName,
host, username, password, domain) )
{
// do work only if we have a valid connection
if ( connection.IsConnected )
{
//////////////////////////
// DO WORK HERE
//////////////////////////
// for AppServerMgr functions call: connection.AppServerMgr.Function()
// for AppServer functions call: connection.AppServer.Function()
const int INT_MIN = -2147483648;
const int INT_MAX = 2147483647;
string channel = "C2";
// create a controller
bool isNewController = false;
ISimpleController controller = connection.AppServer.CreateController(
appName, channel, out isNewController);
ISimplePlayerRecorder player = (ISimplePlayerRecorder) controller;
ITwoHeadPlayerRecorder preview = (ITwoHeadPlayerRecorder) controller;
// create a media mgr and make sure that temporary scratch clip does not exist
IMediaMgr mediaMgr = connection.AppServer.CreateMediaMgr(appName);
string scratchClip = "edl/cmf//local/V:/default/~myscratchclip";
if ( mediaMgr.AssetExists( scratchClip ) )
mediaMgr.DeleteAsset(scratchClip);
// create a new scratch clip
player.SetCurrentBin("V:", "default");
player.New("~myscratchclip");
ISimpleEditor editor = (ISimpleEditor) player.GetEditor();
//insert clip 2 at the end of the scratch clip -- passing in empty string edit ID does this. returns an ID string of the edit.
string editID2 = editor.InsertEdit("edl/cmf//local/V:/default/test2", "", INT_MIN, INT_MAX, 0);
// insert clip 1 before clip 2 above
string editID1 = editor.InsertEdit("edl/cmf//local/V:/default/test1", editID2, INT_MIN, INT_MAX, 0);
// cue it up and start playing, this wil play clip 1, then clip 2
player.CueStart();
player.Play();
// while main context is playing, load preview context with 3rd clip
preview.LoadPreview("edl/cmf//local/V:/default/test3");
// EXAMPLE 1: preview context starts playing after main context ends
preview.BeginPreviewContextChange();
preview.CueStart(); // cue to some position
preview.Play();
// tell preview context to go active after primary context finishes
preview.CommitContextChange("follow"); // manual or follow
Thread.Sleep(35000);
/*
// EXAMPLE 2: start & end limits - timeline relative, not clip
player.SetStartLimit("00:00:05,00");
player.SetEndLimit("00:00:10,00");
Thread.Sleep(20000);
*/
/*
// EXAMPLE 3: force change to second context
// Sleep 15 seconds
Thread.Sleep(5000);
// then force an immediate context change i.e. asap
preview.BeginPreviewContextChange();
preview.Play();
preview.CommitContextChange("asap");
// sleep awhile to see the result on the output
Thread.Sleep(15000);
*/
/*
// EXAMPLE 4: second context is *scheduled* to play 5 seconds after start
string timeOfDay = (string) player.GetStatus("timeofdaystr");
string videoFormat = (string) player.GetStatus("videoformatstr");
// create a new timecode object & set its video format
VdrTimecode timecode = new VdrTimecode();
timecode.VideoFormat = videoFormat;
// set the value equal to current position + 5 seconds
timecode.AsString = timeOfDay;
timecode.Add("00:00:05,00");
// clip must be queued before scheduling a context change using time of day
preview.BeginPreviewContextChange();
preview.CueStart();
// manually commit the CueStart context change. A manual operation performs
// the operation but does not perform the context change. So the preview
// clip cues to start, but the preview context does not become active
preview.CommitContextChange("manual");
// schedule the play command to time of day
preview.BeginPreviewContextChange();
preview.Play();
preview.ScheduleContextChange("timeofday", timecode.AsString);
//player.CancelScheduledChange ("timeofday", timecode.AsString);
*/
// eject the clip
player.Stop();
player.Eject();
// close the channel
controller.CloseChannel();
// delete scratch clip
if ( mediaMgr.AssetExists( scratchClip ) )
mediaMgr.DeleteAsset(scratchClip);
}
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
return 0;
}
}
// Connection helper class: sets up credentials & hostname, connects to K2
public class Connection: IDisposable
{
private bool _connected = false;
private AppServerMgrProxy _appServerMgrProxy = null;
private IAppServer _appServer = null;
/// ;
/// Object that connects to the specified K2 credentials
/// ;
/// ;The application's name.;
/// ;The suite's name.;
/// ;The K2's host name.;
/// ;The username.;
/// ;The password.;
/// ;The domain.;
public Connection(string appname, string suitename, string host, string username, string password, string domain)
{
try
{
//////////////////////////
// SETUP
//////////////////////////
if ( null == host || host.Length == 0)
{
Console.WriteLine("Empty host name passed to Connection object.");
return;
}
//////////////////////////
// CONNECT TO K2
//////////////////////////
// create an AppServerMgr proxy object
_appServerMgrProxy = new AppServerMgrProxy();
// tell it which K2 we're connecting to
_appServerMgrProxy.SetHost(host);
// give it the user credentials we want to use
if ( username.Length > 0 )
_appServerMgrProxy.SetUserCredentials(username, password, domain, false);
// connect to the K2's AppServerMgr
if ( !_appServerMgrProxy.Connect() )
{
// if the connection failed, report an error and exit
Console.WriteLine("ERROR: Could not connect to AppService on host '" + host + "'. Check the host name.");
_appServerMgrProxy = null;
return;
}
// if we got here we're connected to K2 AppService
//////////////////////////
// CREATE AN APPSERVER
//////////////////////////
// now create an AppServer
bool newConnection = false;
_appServer = _appServerMgrProxy.CreateAppServer(suitename,
appname, out newConnection);
_connected = true;
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
/// ;
/// Gets a value indicating whether this instance is connected.
/// ;
/// ;
/// ;true; if this instance is connected; otherwise, ;false;.
/// ;
public bool IsConnected
{
get
{
return _connected;
}
}
/// ;
/// Gets the AppServerMgr.
/// ;
/// ;The AppServerMgr;
public AppServerMgrProxy AppServerMgr
{
get
{
if ( _appServerMgrProxy == null )
Console.WriteLine("WARNING: AppServerMgrProxy object == null!");
return _appServerMgrProxy;
}
}
/// ;
/// Gets the AppServer
/// ;
/// ;The AppServer;
public IAppServer AppServer
{
get
{
if ( _appServerMgrProxy == null )
Console.WriteLine("WARNING: AppServerProxy object == null!");
return _appServer;
}
}
/// ;
/// Disposes this instance.
/// ;
public void Dispose()
{
if ( _appServer != null )
_appServer.CloseConnection();
}
}
}